Преглед на файлове

Merge remote-tracking branch 'origin/master'

zengy преди 1 месец
родител
ревизия
59c5dd1778

+ 4 - 40
firefighting-pressure-service/src/main/java/com/zksy/pressure/utils/MessageHandler.java

@@ -5,9 +5,6 @@ import static com.zksy.common.utils.CollectionSideEffects.*;
 import cn.hutool.core.lang.UUID;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.apache.hc.client5.http.utils.Hex;
-import com.zksy.api.domain.WarningThreshold;
-import com.zksy.api.service.EarlyWarningAutoService;
-import com.zksy.api.service.WarningThresholdService;
 import com.zksy.api.domain.AlarmData;
 import com.zksy.api.service.AlarmDataService;
 import com.zksy.api.utils.AlarmLevelUtil;
@@ -48,12 +45,8 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 	private static Logger logger = LoggerFactory.getLogger(MessageHandler.class);
 	private final FirefightingPressureService firefightingPressureService;
 	@Autowired
-	private WarningThresholdService warningThresholdService;
-	@Autowired
 	private AlarmDataService alarmDataService;
 	@Autowired
-	private EarlyWarningAutoService earlyWarningAutoService;
-	@Autowired
 	private SmsUtil smsUtil;
 	@Autowired
     private DevicePhoneFetchUtil devicePhoneFetchUtil;
@@ -250,54 +243,25 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
     public void checkIfSmsAlertNeeded(FirefightingPressure data) {
         String deviceCode = data.getTelemeteringStation();
         Integer status = alarmStatus(
-                evaluate(deviceCode, "压力阈值评估", () -> evaluatePressure(data)),
                 handleReportedAlarm(data, data.getD14(), "压力变幅报警", "WARN-PRESSURE-VARY"),
                 handleReportedAlarm(data, data.getD13(), "压力下下限报警", "WARN-PRESSURE-LOW-LOW"),
                 handleReportedAlarm(data, data.getD12(), "压力上上限报警", "WARN-PRESSURE-HIGH-HIGH"),
                 handleReportedAlarm(data, data.getD11(), "压力下线报警", "WARN-PRESSURE-LOW"),
-                handleReportedAlarm(data, data.getD10(), "压力上限报警", "WARN-PRESSURE-HIGH"),
-                handleReportedAlarm(data, data.getD9(), "传感器状态", "WARN-SENSOR-STATUS"),
-                handleReportedAlarm(data, data.getD1(), "倾斜报警1", "WARN-TILT-1"));
+                handleReportedAlarm(data, data.getD10(), "压力上限报警", "WARN-PRESSURE-HIGH"));
         if (status != null) {
             updateDeviceAlarmStatus(deviceCode, status);
         }
     }
 
-    private boolean evaluatePressure(FirefightingPressure data) {
-        String deviceId = data.getTelemeteringStation();
-        String warningCode = "WARN-PRESSURE";
-        WarningThreshold threshold = warningThresholdService.getWarningThresholdByDeviceAndCode(deviceId, warningCode);
-        if (threshold == null || (threshold.getMinValue() == null && threshold.getMaxValue() == null)) {
-            return false;
-        }
-        if (data.getPressureValue() == null) {
-            throw new IllegalArgumentException("缺少压力值");
-        }
-        BigDecimal actual = BigDecimal.valueOf(data.getPressureValue());
-        BigDecimal min = threshold.getMinValue() == null ? null : BigDecimal.valueOf(threshold.getMinValue());
-        BigDecimal max = threshold.getMaxValue() == null ? null : BigDecimal.valueOf(threshold.getMaxValue());
-        String type = threshold.getWarningType() != null ? threshold.getWarningType() : "压力预警";
-        boolean over = (min != null && actual.compareTo(min) <= 0) || (max != null && actual.compareTo(max) >= 0);
-        if (over) {
-            int level = AlarmLevelUtil.calculateLevel(actual, min, max);
-            run(deviceId, warningCode + ":报警入库", () -> saveAlarmData(deviceId, type, warningCode, min, max, actual, threshold.getRemark()));
-            run(deviceId, warningCode + ":关闭预警", () -> earlyWarningAutoService.closeAutoWarning(deviceId, warningCode, "已达报警阈值,转报警处理"));
-            if (level == 1) {
-                run(deviceId, warningCode + ":短信通知", () -> sendMessage(deviceId, type, data.getLongitude(), data.getLatitude()));
-            }
-        } else {
-            run(deviceId, warningCode + ":生成预警", () -> earlyWarningAutoService.checkAndGenerate(deviceId, type, warningCode, min, max, actual, threshold.getRemark()));
-        }
-        return over;
-    }
-
     private Boolean handleReportedAlarm(FirefightingPressure data, Integer flag, String type, String code) {
         if (flag == null || (flag != 0 && flag != 1)) {
             return null;
         }
         if (flag == 1) {
             String deviceCode = data.getTelemeteringStation();
-            run(deviceCode, code + ":主动报警入库", () -> saveAlarmDataLevelOne(deviceCode, type, code, null, type));
+            BigDecimal actualValue = data.getPressureValue() == null
+                    ? null : BigDecimal.valueOf(data.getPressureValue());
+            run(deviceCode, code + ":主动报警入库", () -> saveAlarmDataLevelOne(deviceCode, type, code, actualValue, type));
             run(deviceCode, code + ":短信通知", () -> sendMessage(deviceCode, type, data.getLongitude(), data.getLatitude()));
         }
         return flag == 1;

+ 20 - 5
manhole-service/src/main/java/com/zksy/manhole/service/impl/ManholeDataServiceImpl.java

@@ -11,6 +11,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+
 /**
  * 井盖数据Service业务层处理
  * 
@@ -54,21 +56,34 @@ public class ManholeDataServiceImpl extends ServiceImpl<ManholeDataMapper, Manho
     private void checkAndSaveAlarm(ManholeData result) {
         String deviceCode = result.getImeiCardNumber();
         Integer status = alarmStatus(
-                handleReportedAlarm(deviceCode, result.getAlarmStatus(), "倾斜预警", WARN_CODE_TILT, "井盖倾斜报警"),
-                handleReportedAlarm(deviceCode, result.getWaterInfiltrationAlarmStatus(), "水浸预警", WARN_CODE_WATER_INFILTRATION, "井盖水浸报警"),
-                handleReportedAlarm(deviceCode, result.getWaterLevelAlarmStatus(), "窨井水位预警", WARN_WATER_MANHOLE_LEVEL, "井盖水位报警"));
+                handleReportedAlarm(deviceCode, result.getAlarmStatus(), "倾斜预警", WARN_CODE_TILT, parseTiltAngle(result.getTiltAngle()), "井盖倾斜报警"),
+                handleReportedAlarm(deviceCode, result.getWaterInfiltrationAlarmStatus(), "水浸预警", WARN_CODE_WATER_INFILTRATION, null, "井盖水浸报警"),
+                handleReportedAlarm(deviceCode, result.getWaterLevelAlarmStatus(), "窨井水位预警", WARN_WATER_MANHOLE_LEVEL, null, "井盖水位报警"));
         if (status != null) {
             run(deviceCode, "报警状态同步", () -> alarmUtil.updateDeviceAlarmStatus(deviceCode, status));
         }
     }
 
-    private Boolean handleReportedAlarm(String deviceCode, String flag, String type, String code, String remark) {
+    private Boolean handleReportedAlarm(String deviceCode, String flag, String type, String code,
+                                        BigDecimal actualValue, String remark) {
         if (!"0".equals(flag) && !"1".equals(flag)) {
             return null;
         }
         if ("1".equals(flag)) {
-            run(deviceCode, code, () -> alarmUtil.saveAlarmWithLevel(deviceCode, type, code, null, 1, remark));
+            run(deviceCode, code, () -> alarmUtil.saveAlarmWithLevel(deviceCode, type, code, actualValue, 1, remark));
         }
         return "1".equals(flag);
     }
+
+    private BigDecimal parseTiltAngle(String tiltAngle) {
+        if (tiltAngle == null || tiltAngle.trim().isEmpty()) {
+            return null;
+        }
+        try {
+            return new BigDecimal(tiltAngle.trim());
+        } catch (NumberFormatException e) {
+            log.warn("井盖倾斜角度不是有效数值,告警仍保留但实际值为空: tiltAngle={}", tiltAngle);
+            return null;
+        }
+    }
 }

+ 1 - 1
telemetry-service/src/main/java/com/zksy/telemetry/TelemetryApplication.java

@@ -23,6 +23,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 public class TelemetryApplication {
     public static void main(String[] args) {
         SpringApplication.run(TelemetryApplication.class, args);
-        System.out.println("平升遥测终端协议启动成功");
+        System.out.println("平升遥测终端协议(压力)启动成功");
     }
 }

+ 105 - 1
telemetry-service/src/main/java/com/zksy/telemetry/utils/MessageHandler.java

@@ -3,8 +3,15 @@ package com.zksy.telemetry.utils;
 import static com.zksy.common.utils.CollectionSideEffects.*;
 
 import com.zksy.common.exception.InvalidMessageException;
+import com.zksy.api.domain.AlarmData;
+import com.zksy.api.domain.WarningThreshold;
+import com.zksy.api.service.AlarmDataService;
+import com.zksy.api.service.EarlyWarningAutoService;
+import com.zksy.api.service.WarningThresholdService;
+import com.zksy.api.utils.AlarmLevelUtil;
 import com.zksy.telemetry.domain.TelemetryData;
 import com.zksy.telemetry.service.TelemetryDataService;
+import com.zksy.utils.DevicePhoneFetchUtil;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandler;
@@ -12,6 +19,7 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.timeout.ReadTimeoutException;
 import io.netty.util.ReferenceCountUtil;
+import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -19,6 +27,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.math.BigDecimal;
+import com.zksy.api.utils.SmsUtil;
 
 @ChannelHandler.Sharable
 @Slf4j
@@ -29,6 +41,16 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 	@Autowired
 	private DeviceOfflineCheckTask deviceOfflineCheckTask;
 	@Autowired
+	private WarningThresholdService warningThresholdService;
+	@Autowired
+	private AlarmDataService alarmDataService;
+	@Autowired
+	private EarlyWarningAutoService earlyWarningAutoService;
+	@Autowired
+	private SmsUtil smsUtil;
+	@Autowired
+	private DevicePhoneFetchUtil devicePhoneFetchUtil;
+	@Autowired
 	public MessageHandler(TelemetryDataService telemetryDataService) {
 		this.service = telemetryDataService;
 	}
@@ -91,6 +113,7 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
                     }
                 });
                 run(deviceCode, "在线状态同步", () -> deviceOfflineCheckTask.markDeviceOnline(deviceCode));
+                run(deviceCode, "压力报警预警评估", () -> evaluatePressure(resultData, resolveDeviceCode(resultData)));
 
 			} else if (frameType == 0x34) {
 				/*logger.info("收到结束通讯帧,准备发送回应包");
@@ -114,6 +137,87 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
         }
     }
 
+    /**
+     * 平升遥测终端的供水压力使用数值阈值判断 WARN-PRESSURE。
+     * 压力值来自本次采集报文,阈值范围来自 warning_threshold 表。
+     */
+    private void evaluatePressure(TelemetryData data, String deviceCode) {
+        if (warningThresholdService == null || alarmDataService == null || earlyWarningAutoService == null) {
+            throw new IllegalStateException("压力告警依赖未注入");
+        }
+        if (data.getPressure() == null || data.getPressure().trim().isEmpty()) {
+            throw new IllegalArgumentException("采集报文缺少压力值");
+        }
+        BigDecimal actual = new BigDecimal(data.getPressure().trim());
+        String warningCode = "WARN-PRESSURE";
+        WarningThreshold threshold = warningThresholdService
+                .getWarningThresholdByDeviceAndCode(deviceCode, warningCode);
+        if (threshold == null || (threshold.getMinValue() == null && threshold.getMaxValue() == null)) {
+            log.warn("未配置供水压力阈值,跳过 WARN-PRESSURE 评估: deviceCode={}", deviceCode);
+            return;
+        }
+
+        BigDecimal min = threshold.getMinValue() == null ? null : BigDecimal.valueOf(threshold.getMinValue());
+        BigDecimal max = threshold.getMaxValue() == null ? null : BigDecimal.valueOf(threshold.getMaxValue());
+        String warningType = threshold.getWarningType() == null ? "压力预警" : threshold.getWarningType();
+        boolean over = (min != null && actual.compareTo(min) <= 0)
+                || (max != null && actual.compareTo(max) >= 0);
+        if (over) {
+            int level = AlarmLevelUtil.calculateLevel(actual, min, max);
+            run(deviceCode, warningCode + ":报警入库", () -> {
+                AlarmData alarm = new AlarmData();
+                alarm.setDeviceCode(deviceCode);
+                alarm.setWarningType(warningType);
+                alarm.setWarningCode(warningCode);
+                alarm.setMinValue(min);
+                alarm.setMaxValue(max);
+                alarm.setActualValue(actual);
+                alarm.setAlarmLevel(level);
+                alarm.setDeviationRatio(AlarmLevelUtil.calculateDeviationRatio(actual, min, max));
+                alarm.setAlarmStatus(0);
+                alarm.setAlarmTime(java.time.LocalDateTime.now());
+                alarm.setRemark(threshold.getRemark());
+                alarm.setCreateTime(java.time.LocalDateTime.now());
+                requireSaved(alarmDataService.saveAlarmData(alarm));
+            });
+            run(deviceCode, warningCode + ":关闭预警", () ->
+                    earlyWarningAutoService.closeAutoWarning(deviceCode, warningCode, "已达报警阈值,转报警处理"));
+            if (level == 1) {
+                run(deviceCode, warningCode + ":一级告警短信", () -> sendAlarmSms(deviceCode, warningType, actual, min, max));
+            }
+        } else {
+            run(deviceCode, warningCode + ":生成预警", () ->
+                    earlyWarningAutoService.checkAndGenerate(deviceCode, warningType, warningCode,
+                            min, max, actual, threshold.getRemark()));
+        }
+    }
+
+    private String resolveDeviceCode(TelemetryData data) {
+        if (data.getDeviceCode() != null && !data.getDeviceCode().trim().isEmpty()) {
+            return data.getDeviceCode().trim();
+        }
+        return data.getSystemIdentifier();
+    }
+
+    private void sendAlarmSms(String deviceCode, String warningType, BigDecimal actual,
+                              BigDecimal min, BigDecimal max) {
+        if (smsUtil == null || devicePhoneFetchUtil == null) {
+            throw new IllegalStateException("一级告警短信依赖未注入");
+        }
+        List<String> phones = devicePhoneFetchUtil.getPhoneListByDeviceId(deviceCode);
+        if (phones == null || phones.isEmpty()) {
+            log.warn("一级告警短信跳过:未找到设备联系人手机号, deviceCode={}", deviceCode);
+            return;
+        }
+        JSONObject params = new JSONObject();
+        params.put("deviceNo", deviceCode);
+        params.put("alarmType", warningType);
+        params.put("location", "当前值:" + actual + ",正常范围:" + min + "~" + max);
+        Map<String, Boolean> result = smsUtil.sendBatchSms(phones, params.toJSONString());
+        long successCount = result == null ? 0 : result.values().stream().filter(Boolean.TRUE::equals).count();
+        log.info("一级压力告警短信发送完成: deviceCode={}, success={}/{}", deviceCode, successCount, phones.size());
+    }
+
 
 	// 工具方法:发送错误响应
 	private void sendErrorResponse(ChannelHandlerContext ctx, String msg) {
@@ -168,4 +272,4 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
 			logger.error("发送数据失败: {}", e.getMessage());
 		}
 	}
-}
+}