|
|
@@ -238,6 +238,7 @@ public class IotDataTransferService {
|
|
|
|
|
|
Long engineeringId = transferVO.getEngineeringId();
|
|
|
|
|
|
+ int skippedNullField = 0;
|
|
|
for (JSONObject deviceDataItem : deviceData) {
|
|
|
Integer deviceId = deviceDataItem.getIntValue("device_id");
|
|
|
LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
|
|
|
@@ -247,6 +248,32 @@ public class IotDataTransferService {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
+ // 检查业务字段是否为空,为空则计入失败(修复:原逻辑静默跳过并误计为成功)
|
|
|
+ boolean fieldMissing = false;
|
|
|
+ switch (deviceType) {
|
|
|
+ case 707:
|
|
|
+ if (deviceDataItem.getFloat("wd") == null) fieldMissing = true;
|
|
|
+ break;
|
|
|
+ case 708:
|
|
|
+ if (deviceDataItem.getFloat("sd") == null) fieldMissing = true;
|
|
|
+ break;
|
|
|
+ case 709:
|
|
|
+ if (deviceDataItem.getFloat("o2") == null) fieldMissing = true;
|
|
|
+ break;
|
|
|
+ case 710:
|
|
|
+ if (deviceDataItem.getFloat("co2") == null) fieldMissing = true;
|
|
|
+ break;
|
|
|
+ case 711:
|
|
|
+ if (deviceDataItem.getFloat("co") == null) fieldMissing = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (fieldMissing) {
|
|
|
+ log.warn("设备{}[类型{}]的业务字段数据为空,跳过推送,计入失败", deviceId, deviceType);
|
|
|
+ result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ skippedNullField++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
boolean deviceSuccess = true;
|
|
|
try {
|
|
|
switch (deviceType) {
|
|
|
@@ -267,7 +294,7 @@ public class IotDataTransferService {
|
|
|
break;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- log.warn("设备{}推送失败:{}", deviceId, e.getMessage());
|
|
|
+ log.warn("设备{}[类型{}]推送异常:{}", deviceId, deviceType, e.getMessage(), e);
|
|
|
deviceSuccess = false;
|
|
|
}
|
|
|
|
|
|
@@ -278,6 +305,10 @@ public class IotDataTransferService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (skippedNullField > 0) {
|
|
|
+ log.warn("[类型{}] 因业务字段为空而跳过的设备数量:{}", deviceType, skippedNullField);
|
|
|
+ }
|
|
|
+
|
|
|
int success = result.get("successCount");
|
|
|
int failure = result.get("failureCount");
|
|
|
int notSynced = totalDevices - success - failure;
|
|
|
@@ -1126,8 +1157,16 @@ public class IotDataTransferService {
|
|
|
}
|
|
|
|
|
|
// 累加成功数和失败数
|
|
|
- totalSuccessCount += result.getOrDefault("successCount", 0);
|
|
|
- totalFailureCount += result.getOrDefault("failureCount", 0);
|
|
|
+ int typeSuccess = result.getOrDefault("successCount", 0);
|
|
|
+ int typeFailure = result.getOrDefault("failureCount", 0);
|
|
|
+ totalSuccessCount += typeSuccess;
|
|
|
+ totalFailureCount += typeFailure;
|
|
|
+
|
|
|
+ // 分类型诊断日志:精确定位每种类型的成功/失败/未同步
|
|
|
+ int typeTotal = transferVO.getDevices() != null ? transferVO.getDevices().size() : 0;
|
|
|
+ int typeNotSynced = typeTotal - typeSuccess - typeFailure;
|
|
|
+ log.info("[类型分诊] deviceType={} | 总设备={} | 成功={} | 失败={} | 未同步={}",
|
|
|
+ deviceType, typeTotal, typeSuccess, typeFailure, typeNotSynced);
|
|
|
}
|
|
|
|
|
|
// 任务完成总结
|
|
|
@@ -1220,12 +1259,18 @@ public class IotDataTransferService {
|
|
|
* @return 解析后的时间,如果解析失败返回null
|
|
|
*/
|
|
|
private LocalDateTime parseDataTime(JSONObject deviceDataItem) {
|
|
|
- // log.warn("解析的json{}", deviceDataItem.toString());
|
|
|
- Long dataTime = deviceDataItem.getLong("realtime");
|
|
|
- if (dataTime == null) {
|
|
|
- log.warn("设备{}的time为空", deviceDataItem.getString("device_id"));
|
|
|
- return null;
|
|
|
+ Object raw = deviceDataItem.get("realtime");
|
|
|
+ Long dataTime = null;
|
|
|
+ if (raw instanceof Long) {
|
|
|
+ dataTime = (Long) raw;
|
|
|
+ } else if (raw instanceof Integer) {
|
|
|
+ dataTime = ((Integer) raw).longValue();
|
|
|
+ } else if (raw instanceof Number) {
|
|
|
+ dataTime = ((Number) raw).longValue();
|
|
|
+ } else if (raw instanceof String) {
|
|
|
+ try { dataTime = Long.parseLong((String) raw); } catch (Exception ignored) {}
|
|
|
}
|
|
|
+ if (dataTime == null) return null;
|
|
|
return LocalDateTime.ofInstant(Instant.ofEpochMilli(dataTime), ZoneId.systemDefault());
|
|
|
}
|
|
|
|