|
|
@@ -1,9 +1,11 @@
|
|
|
package com.jeesite.modules.mes.service;
|
|
|
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
import com.jeesite.common.collect.ListUtils;
|
|
|
import com.jeesite.common.collect.MapUtils;
|
|
|
@@ -24,6 +26,33 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
@Service
|
|
|
public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw300Data> {
|
|
|
|
|
|
+ private static final Map<String, String> DEVICE_NAME_MAP = new LinkedHashMap<>();
|
|
|
+ private static final Map<String, Double> CT_RATIO_MAP = new LinkedHashMap<>();
|
|
|
+ private static final Set<Integer> SCREEN_POINT_IDS = new HashSet<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ DEVICE_NAME_MAP.put("26060805200001", "配电房电表");
|
|
|
+ DEVICE_NAME_MAP.put("26060805200002", "空压机房电表");
|
|
|
+ CT_RATIO_MAP.put("26060805200001", 500D);
|
|
|
+ CT_RATIO_MAP.put("26060805200002", 100D);
|
|
|
+
|
|
|
+ SCREEN_POINT_IDS.add(1);
|
|
|
+ SCREEN_POINT_IDS.add(2);
|
|
|
+ SCREEN_POINT_IDS.add(3);
|
|
|
+ SCREEN_POINT_IDS.add(7);
|
|
|
+ SCREEN_POINT_IDS.add(8);
|
|
|
+ SCREEN_POINT_IDS.add(9);
|
|
|
+ SCREEN_POINT_IDS.add(13);
|
|
|
+ SCREEN_POINT_IDS.add(22);
|
|
|
+ SCREEN_POINT_IDS.add(23);
|
|
|
+ SCREEN_POINT_IDS.add(24);
|
|
|
+ SCREEN_POINT_IDS.add(25);
|
|
|
+ SCREEN_POINT_IDS.add(26);
|
|
|
+ SCREEN_POINT_IDS.add(28);
|
|
|
+ SCREEN_POINT_IDS.add(34);
|
|
|
+ SCREEN_POINT_IDS.add(35);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public MesAdw300Data get(MesAdw300Data mesAdw300Data) {
|
|
|
return super.get(mesAdw300Data);
|
|
|
@@ -72,28 +101,32 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
String deviceSn = entry.getKey();
|
|
|
Map<Integer, Map<String, Object>> points = entry.getValue();
|
|
|
Map<String, Object> device = MapUtils.newHashMap();
|
|
|
- double power = getPointDouble(points, 13);
|
|
|
- double todayEnergy = todayEnergyMap.getOrDefault(deviceSn, 0D);
|
|
|
+ double power = calculatePower(deviceSn, points);
|
|
|
+ double todayEnergyRaw = todayEnergyMap.getOrDefault(deviceSn, 0D);
|
|
|
+ double todayEnergy = scaleByCtRatio(deviceSn, todayEnergyRaw);
|
|
|
Date reportTime = getDate(points);
|
|
|
- boolean online = reportTime != null && now.getTime() - reportTime.getTime() <= 5L * 60L * 1000L;
|
|
|
+ boolean online = !points.isEmpty();
|
|
|
if (online) {
|
|
|
onlineCount++;
|
|
|
}
|
|
|
totalPower += power;
|
|
|
totalEnergy += todayEnergy;
|
|
|
+ double totalEnergyValue = scaleByCtRatio(deviceSn, getPointDouble(points, 28));
|
|
|
|
|
|
device.put("deviceSn", deviceSn);
|
|
|
+ device.put("deviceName", getDeviceName(deviceSn));
|
|
|
device.put("online", online);
|
|
|
device.put("reportTime", reportTime);
|
|
|
+ device.put("reportTimeText", getDateText(points));
|
|
|
device.put("power", round(power));
|
|
|
device.put("todayEnergy", round(todayEnergy));
|
|
|
- device.put("totalEnergy", round(getPointDouble(points, 28)));
|
|
|
+ device.put("totalEnergy", round(totalEnergyValue));
|
|
|
device.put("ua", round(getPointDouble(points, 1)));
|
|
|
device.put("ub", round(getPointDouble(points, 2)));
|
|
|
device.put("uc", round(getPointDouble(points, 3)));
|
|
|
- device.put("ia", round(getPointDouble(points, 7)));
|
|
|
- device.put("ib", round(getPointDouble(points, 8)));
|
|
|
- device.put("ic", round(getPointDouble(points, 9)));
|
|
|
+ device.put("ia", round(scaleByCtRatio(deviceSn, getPointDouble(points, 7))));
|
|
|
+ device.put("ib", round(scaleByCtRatio(deviceSn, getPointDouble(points, 8))));
|
|
|
+ device.put("ic", round(scaleByCtRatio(deviceSn, getPointDouble(points, 9))));
|
|
|
devices.add(device);
|
|
|
}
|
|
|
|
|
|
@@ -118,7 +151,16 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
@Transactional
|
|
|
public void saveMessage(Adw300Message message) {
|
|
|
Date reportTime = message.getReportTime() == null ? new Date() : message.getReportTime();
|
|
|
+ Date storeWindowStart = getHalfHourStart(reportTime);
|
|
|
+ Date storeWindowEnd = new Date(storeWindowStart.getTime() + 30L * 60L * 1000L);
|
|
|
+ Long savedCount = dao.countByDeviceAndReportTimeRange(message.getDeviceNo(), storeWindowStart, storeWindowEnd);
|
|
|
+ if (savedCount != null && savedCount > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
for (Adw300Point point : message.getPoints()) {
|
|
|
+ if (!SCREEN_POINT_IDS.contains(point.getId())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
MesAdw300Data data = new MesAdw300Data();
|
|
|
data.setDeviceSn(message.getDeviceNo());
|
|
|
data.setReportTime(reportTime);
|
|
|
@@ -127,7 +169,6 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
data.setPointName(point.getName());
|
|
|
data.setPointValue(point.getValue() == null ? null : String.valueOf(point.getValue()));
|
|
|
data.setUnit(point.getUnit());
|
|
|
- data.setRawPayload(message.getPayload());
|
|
|
this.save(data);
|
|
|
}
|
|
|
}
|
|
|
@@ -154,6 +195,16 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
return calendar.getTime();
|
|
|
}
|
|
|
|
|
|
+ private Date getHalfHourStart(Date reportTime) {
|
|
|
+ java.util.Calendar calendar = java.util.Calendar.getInstance();
|
|
|
+ calendar.setTime(reportTime);
|
|
|
+ int minute = calendar.get(java.util.Calendar.MINUTE);
|
|
|
+ calendar.set(java.util.Calendar.MINUTE, minute < 30 ? 0 : 30);
|
|
|
+ calendar.set(java.util.Calendar.SECOND, 0);
|
|
|
+ calendar.set(java.util.Calendar.MILLISECOND, 0);
|
|
|
+ return calendar.getTime();
|
|
|
+ }
|
|
|
+
|
|
|
private List<String> buildHours() {
|
|
|
List<String> hours = ListUtils.newArrayList();
|
|
|
for (int i = 0; i < 24; i++) {
|
|
|
@@ -167,17 +218,7 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
for (String deviceSn : deviceSnList) {
|
|
|
dataMap.put(deviceSn, new LinkedHashMap<>());
|
|
|
}
|
|
|
- for (Map<String, Object> row : rows) {
|
|
|
- String deviceSn = getString(row.get("deviceSn"));
|
|
|
- String hourLabel = getString(row.get("hourLabel"));
|
|
|
- if (deviceSn == null || hourLabel == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (!dataMap.containsKey(deviceSn)) {
|
|
|
- dataMap.put(deviceSn, new LinkedHashMap<>());
|
|
|
- }
|
|
|
- dataMap.get(deviceSn).put(hourLabel, getDouble(row.get("energy")));
|
|
|
- }
|
|
|
+ putHourlyRows(dataMap, rows, false);
|
|
|
|
|
|
List<String> hours = buildHours();
|
|
|
List<Map<String, Object>> series = ListUtils.newArrayList();
|
|
|
@@ -187,13 +228,30 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
for (String hour : hours) {
|
|
|
values.add(round(entry.getValue().getOrDefault(hour, 0D)));
|
|
|
}
|
|
|
- item.put("name", entry.getKey());
|
|
|
+ item.put("name", getDeviceName(entry.getKey()));
|
|
|
item.put("data", values);
|
|
|
series.add(item);
|
|
|
}
|
|
|
return series;
|
|
|
}
|
|
|
|
|
|
+ private void putHourlyRows(Map<String, Map<String, Double>> dataMap, List<Map<String, Object>> rows, boolean fallback) {
|
|
|
+ for (Map<String, Object> row : rows) {
|
|
|
+ String deviceSn = getString(row.get("deviceSn"));
|
|
|
+ String hourLabel = getString(row.get("hourLabel"));
|
|
|
+ if (deviceSn == null || hourLabel == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!dataMap.containsKey(deviceSn)) {
|
|
|
+ dataMap.put(deviceSn, new LinkedHashMap<>());
|
|
|
+ }
|
|
|
+ Double current = dataMap.get(deviceSn).get(hourLabel);
|
|
|
+ if (!fallback || current == null || current <= 0D) {
|
|
|
+ dataMap.get(deviceSn).put(hourLabel, scaleByCtRatio(deviceSn, getDouble(row.get("energy"))));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private Map<String, Double> mapNumberByDevice(List<Map<String, Object>> rows, String key) {
|
|
|
Map<String, Double> result = new LinkedHashMap<>();
|
|
|
for (Map<String, Object> row : rows) {
|
|
|
@@ -207,14 +265,67 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
|
|
|
private Date getDate(Map<Integer, Map<String, Object>> points) {
|
|
|
for (Map<String, Object> point : points.values()) {
|
|
|
+ Object textValue = point.get("reportTimeText");
|
|
|
+ if (textValue != null) {
|
|
|
+ try {
|
|
|
+ return com.jeesite.common.lang.DateUtils.parseDate(String.valueOf(textValue));
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ // Try typed report time below.
|
|
|
+ }
|
|
|
+ }
|
|
|
Object value = point.get("reportTime");
|
|
|
if (value instanceof Date) {
|
|
|
return (Date) value;
|
|
|
}
|
|
|
+ if (value != null) {
|
|
|
+ try {
|
|
|
+ return com.jeesite.common.lang.DateUtils.parseDate(String.valueOf(value));
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ // Try possible non-camel-case map keys below.
|
|
|
+ }
|
|
|
+ }
|
|
|
+ value = point.get("report_time");
|
|
|
+ if (value instanceof Date) {
|
|
|
+ return (Date) value;
|
|
|
+ }
|
|
|
+ if (value != null) {
|
|
|
+ try {
|
|
|
+ return com.jeesite.common.lang.DateUtils.parseDate(String.valueOf(value));
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getDateText(Map<Integer, Map<String, Object>> points) {
|
|
|
+ for (Map<String, Object> point : points.values()) {
|
|
|
+ Object value = point.get("reportTimeText");
|
|
|
+ if (value != null) {
|
|
|
+ return String.valueOf(value);
|
|
|
+ }
|
|
|
+ value = point.get("reportTime");
|
|
|
+ if (value != null) {
|
|
|
+ return String.valueOf(value);
|
|
|
+ }
|
|
|
+ value = point.get("report_time");
|
|
|
+ if (value != null) {
|
|
|
+ return String.valueOf(value);
|
|
|
+ }
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ private String getDeviceName(String deviceSn) {
|
|
|
+ String name = DEVICE_NAME_MAP.get(deviceSn);
|
|
|
+ return name == null ? deviceSn : name;
|
|
|
+ }
|
|
|
+
|
|
|
+ private double scaleByCtRatio(String deviceSn, double value) {
|
|
|
+ return value * CT_RATIO_MAP.getOrDefault(deviceSn, 1D);
|
|
|
+ }
|
|
|
+
|
|
|
private double getPointDouble(Map<Integer, Map<String, Object>> points, int pointId) {
|
|
|
Map<String, Object> point = points.get(pointId);
|
|
|
if (point == null) {
|
|
|
@@ -258,4 +369,31 @@ public class MesAdw300DataService extends CrudService<MesAdw300DataDao, MesAdw30
|
|
|
private double round(double value) {
|
|
|
return Math.round(value * 1000D) / 1000D;
|
|
|
}
|
|
|
+
|
|
|
+ private double calculatePower(String deviceSn, Map<Integer, Map<String, Object>> points) {
|
|
|
+ double ua = getPointDouble(points, 1);
|
|
|
+ double ub = getPointDouble(points, 2);
|
|
|
+ double uc = getPointDouble(points, 3);
|
|
|
+ double ia = scaleByCtRatio(deviceSn, getPointDouble(points, 7));
|
|
|
+ double ib = scaleByCtRatio(deviceSn, getPointDouble(points, 8));
|
|
|
+ double ic = scaleByCtRatio(deviceSn, getPointDouble(points, 9));
|
|
|
+ double pfa = Math.abs(getPointDouble(points, 22));
|
|
|
+ double pfb = Math.abs(getPointDouble(points, 23));
|
|
|
+ double pfc = Math.abs(getPointDouble(points, 24));
|
|
|
+ if (pfa > 0D && pfa <= 1D && pfb > 0D && pfb <= 1D && pfc > 0D && pfc <= 1D) {
|
|
|
+ return (ua * ia * pfa + ub * ib * pfb + uc * ic * pfc) / 1000D;
|
|
|
+ }
|
|
|
+
|
|
|
+ double powerFactor = Math.abs(getPointDouble(points, 25));
|
|
|
+ if (powerFactor <= 0D || powerFactor > 1D) {
|
|
|
+ powerFactor = 0.9D;
|
|
|
+ }
|
|
|
+
|
|
|
+ double avgVoltage = (ua + ub + uc) / 3D;
|
|
|
+ double avgCurrent = (ia + ib + ic) / 3D;
|
|
|
+ if (avgVoltage <= 0D || avgCurrent <= 0D) {
|
|
|
+ return scaleByCtRatio(deviceSn, Math.abs(getPointDouble(points, 13)));
|
|
|
+ }
|
|
|
+ return 3D * avgVoltage * avgCurrent * powerFactor / 1000D;
|
|
|
+ }
|
|
|
}
|