AlarmUtil.java 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package com.zksy.manhole.utils;
  2. import static com.zksy.common.utils.CollectionSideEffects.*;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.zksy.api.utils.AlarmLevelUtil;
  5. import com.zksy.api.utils.SmsUtil;
  6. import com.zksy.api.domain.AlarmData;
  7. import com.zksy.api.service.AlarmDataService;
  8. import com.zksy.api.service.DeviceContactService;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.beans.factory.annotation.Value;
  13. import org.springframework.http.HttpEntity;
  14. import org.springframework.http.HttpHeaders;
  15. import org.springframework.http.MediaType;
  16. import org.springframework.stereotype.Component;
  17. import org.springframework.web.client.RestTemplate;
  18. import java.math.BigDecimal;
  19. import java.time.LocalDateTime;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. @Component
  24. public class AlarmUtil {
  25. private static final Logger log = LoggerFactory.getLogger(AlarmUtil.class);
  26. @Autowired
  27. private RestTemplate restTemplate;
  28. @Autowired
  29. private SmsUtil smsUtil;
  30. @Autowired
  31. private DeviceContactService devicePhoneFetchUtil;
  32. @Autowired
  33. private AlarmDataService alarmDataService;
  34. @Value("${device.status.api.url:http://zk-api-service/equipmentStatus/updateAlarmStatus}")
  35. private String deviceStatusApiUrl;
  36. public void checkAndSaveAlarm(String deviceCode,
  37. String warningType, String warningCode, Double minValue, Double maxValue,
  38. BigDecimal actualValue, String remark) {
  39. if (actualValue == null) {
  40. return;
  41. }
  42. boolean shouldAlarm = false;
  43. if (minValue != null && actualValue.doubleValue() <= minValue) {
  44. shouldAlarm = true;
  45. }
  46. if (maxValue != null && actualValue.doubleValue() >= maxValue) {
  47. shouldAlarm = true;
  48. }
  49. if (shouldAlarm) {
  50. saveAlarm(deviceCode, warningType, warningCode,
  51. minValue != null ? BigDecimal.valueOf(minValue) : null,
  52. maxValue != null ? BigDecimal.valueOf(maxValue) : null,
  53. actualValue, remark);
  54. }
  55. }
  56. public int saveAlarm(String deviceCode,
  57. String warningType, String warningCode, BigDecimal minValue, BigDecimal maxValue,
  58. BigDecimal actualValue, String remark) {
  59. int alarmLevel = 4;
  60. try {
  61. AlarmData alarmData = new AlarmData();
  62. alarmData.setDeviceCode(deviceCode);
  63. alarmData.setWarningCode(warningCode);
  64. alarmData.setMinValue(minValue);
  65. alarmData.setMaxValue(maxValue);
  66. alarmData.setActualValue(actualValue);
  67. alarmLevel = AlarmLevelUtil.calculateLevel(actualValue, minValue, maxValue);
  68. BigDecimal deviationRatio = AlarmLevelUtil.calculateDeviationRatio(actualValue, minValue, maxValue);
  69. alarmData.setAlarmLevel(alarmLevel);
  70. alarmData.setDeviationRatio(deviationRatio);
  71. alarmData.setAlarmStatus(0);
  72. alarmData.setCreateTime(LocalDateTime.now());
  73. boolean saved = run(deviceCode, warningCode + ":报警入库", () ->
  74. requireSaved(alarmDataService.saveAlarmData(alarmData)));
  75. if (alarmLevel == 1) {
  76. log.warn("【1级紧急告警】deviceCode={}, warningCode={}, deviationRatio={}%",
  77. deviceCode, warningCode, deviationRatio);
  78. sendAlarmSms(deviceCode, warningType, actualValue, minValue, maxValue);
  79. }
  80. if (saved) log.info("告警数据入库成功: deviceCode={}, warningCode={}, level={}级", deviceCode, warningCode, alarmLevel);
  81. } catch (Exception e) {
  82. log.error("保存告警数据失败: deviceCode={}, warningCode={}", deviceCode, warningCode, e);
  83. }
  84. return alarmLevel;
  85. }
  86. /**
  87. * 保存告警数据(指定告警等级,适用于状态型告警)
  88. * @param deviceCode 设备编码
  89. * @param warningType 告警类型
  90. * @param warningCode 告警编码
  91. * @param actualValue 实际值(可为null)
  92. * @param alarmLevel 告警等级(1-4)
  93. * @param remark 备注
  94. * @return 告警等级
  95. */
  96. public int saveAlarmWithLevel(String deviceCode,
  97. String warningType, String warningCode,
  98. BigDecimal actualValue, int alarmLevel, String remark) {
  99. try {
  100. AlarmData alarmData = new AlarmData();
  101. alarmData.setDeviceCode(deviceCode);
  102. alarmData.setWarningCode(warningCode);
  103. alarmData.setActualValue(actualValue);
  104. alarmData.setAlarmLevel(alarmLevel);
  105. alarmData.setDeviationRatio(BigDecimal.ZERO);
  106. alarmData.setAlarmStatus(0);
  107. alarmData.setCreateTime(LocalDateTime.now());
  108. boolean saved = run(deviceCode, warningCode + ":报警入库", () ->
  109. requireSaved(alarmDataService.saveAlarmData(alarmData)));
  110. if (alarmLevel == 1) {
  111. log.warn("【1级紧急告警】deviceCode={}, warningCode={}", deviceCode, warningCode);
  112. sendAlarmSms(deviceCode, warningType, actualValue, null, null);
  113. }
  114. if (saved) log.info("告警数据入库成功: deviceCode={}, warningCode={}, level={}级", deviceCode, warningCode, alarmLevel);
  115. } catch (Exception e) {
  116. log.error("保存告警数据异常: {}", e.getMessage());
  117. }
  118. return alarmLevel;
  119. }
  120. private void sendAlarmSms(String deviceCode, String warningType, BigDecimal actualValue,
  121. BigDecimal minValue, BigDecimal maxValue) {
  122. try {
  123. List<String> phoneList = devicePhoneFetchUtil.getPhoneListByDeviceCode(deviceCode);
  124. if (phoneList == null || phoneList.isEmpty()) {
  125. log.warn("报警短信发送失败:未找到设备{}的联系人手机号", deviceCode);
  126. return;
  127. }
  128. JSONObject params = new JSONObject();
  129. params.put("deviceNo", deviceCode);
  130. params.put("alarmType", warningType);
  131. params.put("location", "当前值:" + actualValue + ",正常范围:" + minValue + "~" + maxValue);
  132. Map<String, Boolean> result = smsUtil.sendBatchSms(phoneList, params.toJSONString());
  133. long successCount = result.values().stream().filter(Boolean::booleanValue).count();
  134. log.info("1级告警短信发送完成,成功{}条,失败{}条", successCount, phoneList.size() - successCount);
  135. } catch (Exception e) {
  136. log.error("发送报警短信异常: {}", e.getMessage());
  137. }
  138. }
  139. /**
  140. * 更新设备报警状态
  141. * @param deviceCode 设备编码
  142. * @param alarmStatus 报警状态:0-正常,1-报警
  143. */
  144. public void updateDeviceAlarmStatus(String deviceCode, int alarmStatus) {
  145. try {
  146. Map<String, Object> params = new HashMap<>();
  147. params.put("deviceCode", deviceCode);
  148. params.put("alarmStatus", alarmStatus);
  149. HttpHeaders headers = new HttpHeaders();
  150. headers.setContentType(MediaType.APPLICATION_JSON);
  151. HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
  152. Map<?, ?> response = restTemplate.postForObject(deviceStatusApiUrl, request, Map.class);
  153. if (response == null || !Boolean.TRUE.equals(response.get("success"))) {
  154. log.warn("设备报警状态更新未成功: deviceCode={}, alarmStatus={}, response={}", deviceCode, alarmStatus, response);
  155. return;
  156. }
  157. log.info("设备报警状态更新成功: deviceCode={}, alarmStatus={}", deviceCode, alarmStatus);
  158. } catch (Exception e) {
  159. log.error("更新设备报警状态失败: deviceCode={}, alarmStatus={}", deviceCode, alarmStatus, e);
  160. }
  161. }
  162. }