package com.moral.service.impl; import static org.apache.commons.lang3.time.DateUtils.addDays; import static org.apache.commons.lang3.time.DateUtils.truncate; import static org.springframework.util.ObjectUtils.isEmpty; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.Resource; import org.apache.commons.lang3.time.DateUtils; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import com.moral.common.util.CalculateUtils; import com.moral.common.util.ResourceUtil; import com.moral.common.util.ValidateUtil; import com.moral.entity.Device; import com.moral.mapper.HistoryMinutelyMapper; import com.moral.mapper.DeviceMapper; import com.moral.mapper.SensorMapper; import com.moral.service.HistoryMinutelyService; @Service public class HistoryMinutelyServiceImpl implements HistoryMinutelyService { @Resource private HistoryMinutelyMapper historyMinutelyMapper; @Resource private DeviceMapper deviceMapper; @Resource private SensorMapper sensorMapper; private Set sensorKeys = new HashSet(); @Override public Map getDayAQIByDevice(Map parameters) { ValidateUtil.notNull(parameters.get("mac"), "param.is.null"); Date date = new Date(); // 昨日00:00:00 parameters.put("start", truncate(addDays(date, -1), Calendar.DATE)); // 今日00:00:00 parameters.put("end", truncate(date, Calendar.DATE)); Map average = historyMinutelyMapper.getDayAQIByDevice(parameters); return getAQIByDataMap(average); } private Map getAQIByDataMap(Map average) { Map resultMap = new HashMap(); if (isEmpty(average)) { resultMap.put("AQI", "N/V"); } else { String[] IAQIValues = ResourceUtil.getArrValue("IAQI"); Set IAQIs = new HashSet(); for (Map.Entry entry : average.entrySet()) { double minMacKey = 0, maxMacKey = 0, minIAQI = 0, maxIAQI = 0; String[] macKeyValues = ResourceUtil.getArrValue(entry.getKey()); Double avg = entry.getValue(); if (isEmpty(avg)) { IAQIs.add(null); } else { int index = -1; for (int i = 0; i < macKeyValues.length; i++) { if (avg <= Double.valueOf(macKeyValues[i])) { if (i == 0) { index = i; } else { index = i - 1; } break; } } if (index == -1) { IAQIs.add(Double.MAX_VALUE); } else { minMacKey = Double.valueOf(macKeyValues[index]); maxMacKey = Double.valueOf(macKeyValues[index + 1]); minIAQI = Double.valueOf(IAQIValues[index]); maxIAQI = Double.valueOf(IAQIValues[index + 1]); Double result = CalculateUtils.calculateIAQI(maxIAQI, minIAQI, maxMacKey, minMacKey, avg); IAQIs.add(result); } } } IAQIs.remove(null); if (isEmpty(IAQIs)) { resultMap.put("AQI", "N/V"); } else { Double AQI = Collections.max(IAQIs); if (AQI == Double.MAX_VALUE) { resultMap.put("AQI", IAQIValues[IAQIValues.length - 1]); } else { resultMap.put("AQI", String.format("%.0f", AQI)); } } } return resultMap; } public Map> getMonitorPointOrDeviceAvgData4Compare(Map parameters) throws Exception { Map> resultMap = new HashMap>(); if (ObjectUtils.isEmpty(parameters)) { resultMap.put("c", null); return resultMap; } List> resultList = getMonitorPointOrDeviceAvgData(parameters); List timeList = new ArrayList(); List dataList = new ArrayList(); String sensorKey = (String) parameters.get("sensorKey"); for (Map map : resultList) { String time = map.get("time").toString(); time =time.substring(time.length() - 2); timeList.add(time); dataList.add(map.get(sensorKey)); } String part = (String) parameters.get("part"); resultMap.put("time" + part, timeList); resultMap.put("data" + part, dataList); return resultMap; } @Override public Map> getCompareReport(Map parameters) throws Exception { Map> resultMap = new HashMap>(); Map parametersA = new HashMap(); Map parametersB = new HashMap(); if (parameters.containsKey("time") && parameters.containsKey("monitorPoint")) { parametersA.put("part", "A"); parametersA.putAll(parameters); parametersA.remove("timeb"); } if (parameters.containsKey("timeb") && parameters.containsKey("monitorPointb")) { parametersB.putAll(parameters); parametersB.put("part", "B"); parametersB.put("time", parametersB.get("timeb")); parametersB.put("monitorPoint", parametersB.get("monitorPointb")); if (parameters.containsKey("macb")) { parametersB.put("mac", parametersB.get("macb")); } parametersB.remove("timeb"); } List> list = new ArrayList>(); list.add(parametersA); list.add(parametersB); ExecutorService threadPool = Executors.newCachedThreadPool(); CompletionService>> cs = new ExecutorCompletionService>>(threadPool); for (Map map : list) { cs.submit(new Callable>>() { @Override public Map> call() throws Exception { return getMonitorPointOrDeviceAvgData4Compare(map); } }); } for (Map map : list) { resultMap.putAll(cs.take().get()); } if (resultMap.containsKey("timeA") && resultMap.containsKey("timeB")) { List timeA = resultMap.get("timeA"); List timeB = resultMap.get("timeB"); List time = new ArrayList(timeA); List time1 = new ArrayList(timeB); List dataA = resultMap.get("dataA"); List dataB = resultMap.get("dataB"); List resultA = new ArrayList(); List resultB = new ArrayList(); time1.removeAll(time); time.addAll(time1); time.sort(new Comparator() { @Override public int compare(Object o1, Object o2) { return Integer.compare(Integer.valueOf(o1.toString()), Integer.valueOf(o2.toString())); } }); for (int i = 0; i < time.size(); i++) { Object object = time.get(i); int indexA = timeA.indexOf(object); if (indexA > -1) { resultA.add(i, dataA.get(indexA)); }else { resultA.add("-"); } int indexB = timeB.indexOf(object); if (indexB > -1) { resultB.add(i, dataB.get(indexB)); }else { resultB.add("-"); } } resultMap.put("dataA", resultA); resultMap.put("dataB", resultB); resultMap.put("time", time); } else if (resultMap.containsKey("timeA")) { resultMap.put("time", resultMap.get("timeA")); } else { resultMap.put("time", resultMap.get("timeB")); } return resultMap; } @Override public List> getMonitorPointOrDeviceAvgData(Map parameters) throws Exception { List> resul ; String type = (String) parameters.get("type"); String time = (String) parameters.get("time"); String format = (String) parameters.get("format"); Date start = DateUtils.parseDate(time, format), end = null ; if (parameters.containsKey("timeb")) { end = DateUtils.parseDate((String)parameters.get("timeb"), format); } else { switch (type) { case "year": end = DateUtils.addYears(start, 1); break; case "month": end = DateUtils.addMonths(start, 1); break; case "day": end = DateUtils.addDays(start, 1); break; case "hour": end = DateUtils.addHours(start, 1); break; } } parameters.put("start", start); parameters.put("end", end); if (parameters.containsKey("sensorKey")) { String sensorKey = (String) parameters.get("sensorKey"); String sensorKeyColumn = "AVG(json -> '$." + sensorKey + "[0]') " + sensorKey; parameters.put("sensorKeyColumn", sensorKeyColumn); } if (!parameters.containsKey("mac")) { resul = new ArrayList>(); Integer monitorPointId = Integer.valueOf((String) parameters.get("monitorPoint")); List> deviceVersions = deviceMapper.getDeviceVersionIdByMonitorPoint(monitorPointId); ExecutorService threadPool = Executors.newCachedThreadPool(); CompletionService>> cs = new ExecutorCompletionService>>(threadPool); List> list = new ArrayList>(); for (Map map : deviceVersions) { cs.submit(new Callable>>() { @Override public List> call() throws Exception { Map parameter = new HashMap(parameters); Integer deviceVersionId = (Integer) map.get("deviceVersionId"); if (!parameter.containsKey("sensorKeyColumn")) { List> sensors = sensorMapper.getSensorsByDeviceVersionId(deviceVersionId); String sensorKeyColumn = getSensorKeyColumnBySensors(sensors); parameter.put("sensorKeyColumn", sensorKeyColumn); parameters.put("sensors", sensorKeys); } List macs = deviceMapper.getDeviceMacByMonitorPointAndDeviceVersion(monitorPointId, deviceVersionId); if (ObjectUtils.isEmpty(macs) || macs.contains("null") ) { return new ArrayList>(); }else { parameter.put("macs", macs); return historyMinutelyMapper.getMonitorPointOrDeviceAvgData(parameter); } } }); } for (Map map : deviceVersions) { list.addAll(cs.take().get()); } Map> result = new LinkedHashMap>(); for (Map map : list) { time = (String) map.get("time"); map.remove("time"); Map times = new HashMap(); if (result.containsKey(time)) { times = (Map) result.get(time); } for (Map.Entry entry : map.entrySet()) { String sensorKey = entry.getKey(); Number[] doubles = new Number[3]; Double sum = (Double) entry.getValue(); Integer count = 1; if (times.containsKey(sensorKey)) { doubles = times.get(sensorKey); sum = (Double) doubles[0] + sum; count = (Integer) doubles[1] + 1; } doubles[0] = sum; doubles[1] = count; doubles[2] = new BigDecimal(sum / count).setScale(3, RoundingMode.HALF_UP).doubleValue(); times.put(sensorKey, doubles); } result.put(time, times); } Iterator>> iterator = result.entrySet().iterator(); while(iterator.hasNext()){ Entry> entry = iterator.next(); String resultTime = entry.getKey(); Map value = entry.getValue(); Map resultMap = new HashMap(); resultMap.put("time", resultTime); for (String sensorKey : value.keySet()) { resultMap.put(sensorKey, value.get(sensorKey)[2]); } resul.add(resultMap); } } else { if (!parameters.containsKey("sensorKeyColumn")) { String mac = (String) parameters.get("mac"); Device device = new Device(); device.setMac(mac); device = deviceMapper.selectOne(device); List> sensors = sensorMapper.getSensorsByDeviceVersionId(device.getDeviceVersionId()); String sensorKeyColumn = getSensorKeyColumnBySensors(sensors); parameters.put("sensorKeyColumn", sensorKeyColumn); parameters.put("sensors", sensorKeys); } resul = historyMinutelyMapper.getMonitorPointOrDeviceAvgData(parameters); } return resul; } private String getSensorKeyColumnBySensors(List> sensors) { String sensorKeyColumn = ""; for (int i = 0; i < sensors.size(); i++) { String sensorKey = (String) sensors.get(i).get("sensor_key"); String name = (String) sensors.get(i).get("name"); if (i == sensors.size() - 1) { sensorKeyColumn += "AVG(json -> '$." + sensorKey + "[0]') " + sensorKey; } else { sensorKeyColumn += "AVG(json -> '$." + sensorKey + "[0]') " + sensorKey + ","; } sensorKeys.add(sensorKey + "-" + name); } return sensorKeyColumn; } }