ソースを参照

feat:新增数据异常websocket推送status字段
feat:新增sims获取冷链预警历史接口
feat:新增导出传感器数据适配sensorCode查询
fix:修复数据/设备恢复后预警记录未删除bug
fix:修复修改数据上下限因缓存无法回显bug

黄渊昊 3 日 前
コミット
240a9a4ff3
12 ファイル変更99 行追加8 行削除
  1. 1 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/offline/DeviceOfflineDetectionService.java
  2. 3 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/SensorAlarmService.java
  3. 20 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/SensorAlarmServiceImpl.java
  4. 1 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java
  5. 8 2
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/RedisSensorAlarmMessagePushService.java
  6. 1 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WebSocketPushService.java
  7. 1 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/config/JfcloudColdChainConstants.java
  8. 18 2
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/controller/SimsController.java
  9. 31 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/SensorAlarmSearchParam.java
  10. 7 1
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java
  11. 2 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitornotice/param/TrendParam.java
  12. 6 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitornotice/service/impl/MonitorNoticeServiceImpl.java

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/offline/DeviceOfflineDetectionService.java

@@ -146,7 +146,7 @@ public class DeviceOfflineDetectionService {
                 log.debug("设备 {}-{} 在线,最后上报时间:{}。", deviceCode, route, lastReportTimeStr);
                 MonitorTargetRegion monitorTargetRegion = monitorTargetRegionService.findOneByDeviceCodeAndSensorNo(deviceCode, route);
                 if (Objects.nonNull(monitorTargetRegion)) {
-                    if (redisSensorAlarmMessagePushService.hasExceededPushLimitLike("*", monitorTargetRegion.getId(), route, "设备离线")) {
+                    if (redisSensorAlarmMessagePushService.hasExceededPushLimitLike(monitorTargetRegion.getId(), route, "设备离线")) {
                         publishAlarm(deviceCode, route, lastReportTimeStr, "设备上线", SensorAlarmType.SENSOR_ON_LINE.getDeviceCode());
                     }
                 } else {

+ 3 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/SensorAlarmService.java

@@ -7,6 +7,7 @@ import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
 import vip.xiaonuo.coldchain.core.alarm.enums.SensorAlarmType;
 import vip.xiaonuo.coldchain.modular.app.param.Message;
 import vip.xiaonuo.coldchain.modular.app.param.MessagePageParam;
+import vip.xiaonuo.coldchain.modular.app.param.SensorAlarmSearchParam;
 import vip.xiaonuo.coldchain.modular.monitornotice.param.MonitorNoticePageParam;
 import vip.xiaonuo.coldchain.modular.monitorsearchhistory.dto.TopWarningDto;
 import vip.xiaonuo.common.pojo.CommonResult;
@@ -38,4 +39,6 @@ public interface SensorAlarmService extends IService<SensorAlarm> {
     List<TopWarningDto> topWarning(List<String> types);
 
     DataTrendDto getLastWeekDataTrend();
+
+    Page<SensorAlarm> getSimsAlarmHistory(SensorAlarmSearchParam sensorAlarmSearchParam);
 }

+ 20 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/SensorAlarmServiceImpl.java

@@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -29,6 +30,7 @@ import vip.xiaonuo.coldchain.core.alarm.mapper.SensorAlarmMapper;
 import vip.xiaonuo.coldchain.modular.app.param.Message;
 import vip.xiaonuo.coldchain.modular.app.param.MessagePageParam;
 import vip.xiaonuo.coldchain.modular.app.param.MessageType;
+import vip.xiaonuo.coldchain.modular.app.param.SensorAlarmSearchParam;
 import vip.xiaonuo.coldchain.modular.monitornotice.param.MonitorNoticePageParam;
 import vip.xiaonuo.coldchain.modular.monitorsearchhistory.dto.TopWarningDto;
 import vip.xiaonuo.common.enums.CommonDeleteFlagEnum;
@@ -330,6 +332,24 @@ public class SensorAlarmServiceImpl extends ServiceImpl<SensorAlarmMapper, Senso
         return dataTrendDto;
     }
 
+    @Override
+    public Page<SensorAlarm> getSimsAlarmHistory(SensorAlarmSearchParam sensorAlarmSearchParam) {
+        LambdaQueryWrapper<SensorAlarm> queryWrapper = new LambdaQueryWrapper<>();
+        if (StrUtil.isNotBlank(sensorAlarmSearchParam.getSensorCode())) {
+            queryWrapper.eq(SensorAlarm::getSensorCode, sensorAlarmSearchParam.getSensorCode());
+        }
+        if (Objects.nonNull(sensorAlarmSearchParam.getSensorRoute())) {
+            queryWrapper.eq(SensorAlarm::getSensorRoute, sensorAlarmSearchParam.getSensorRoute());
+        }
+        if (Objects.nonNull(sensorAlarmSearchParam.getStartTime()) && Objects.nonNull(sensorAlarmSearchParam.getEndTime())) {
+            Assert.isTrue(sensorAlarmSearchParam.getStartTime().before(sensorAlarmSearchParam.getEndTime()), "开始时间不能大于结束时间");
+            queryWrapper.between(SensorAlarm::getCreateTime, sensorAlarmSearchParam.getStartTime(), sensorAlarmSearchParam.getEndTime());
+        }
+        queryWrapper.orderByDesc(SensorAlarm::getCreateTime);
+        Page<SensorAlarm> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
+        return page;
+    }
+
     public Page<SensorAlarm> getSensorAlarmPage(MessagePageParam messagePageParam) {
 
         StopWatch stopWatch = new StopWatch();

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java

@@ -118,7 +118,7 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
         } else {
             //todo
             // SensorAlarmType.DATA_RESTORE_ALARM
-            if (redisSensorAlarmMessagePushService.hasExceededPushLimitLike("*", monitorTargetRegion.getId(), monitorTargetRegion.getSensorRoute(),type + "*")) {
+            if (redisSensorAlarmMessagePushService.hasExceededPushLimitLike(monitorTargetRegion.getId(), monitorTargetRegion.getSensorRoute(),type + "*")) {
                 publishAlarm(type + "恢复", value, unit, time, upperThreshold, monitorTargetRegion
                         , SensorAlarmType.DATA_RESTORE_ALARM.getDeviceCode());
                 alarmTriggered = true;

+ 8 - 2
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/RedisSensorAlarmMessagePushService.java

@@ -120,6 +120,7 @@ public class RedisSensorAlarmMessagePushService {
                                 b = pushService.sendAlarmRecoverMessage(alarm, firstAlarmTimeForRecovery);
                                 if (b) {
                                     delAlarmTime(deviceID, alarm.getSensorRoute(), "0");
+                                    delAlarmCount(openId, alarm.getSensorCode(), alarm.getSensorRoute(), "0");
                                 }
                                 break;
                             case "4":
@@ -127,6 +128,7 @@ public class RedisSensorAlarmMessagePushService {
                                 b = pushService.sendOnlineMessage(alarm, firstAlarmTimeForOnline);
                                 if (b) {
                                     delAlarmTime(deviceID, alarm.getSensorRoute(), "1");
+                                    delAlarmCount(openId, alarm.getSensorCode(), alarm.getSensorRoute(), "1");
                                 }
                                 break;
                         }
@@ -144,6 +146,10 @@ public class RedisSensorAlarmMessagePushService {
         saveAlarmToDatabase(alarm);
     }
 
+    private void delAlarmCount(String openId, String sensorCode, Integer sensorRoute, String type) {
+        redisTemplate.delete(generatePushHistoryCountKey(openId, sensorCode, sensorRoute, type));
+    }
+
     //    获取设备第一次报警时间
     private Object getAlarmTime(String deviceID, Integer sensorRoute, String alarmType) {
         String key = generateAlarmHistoryKey(deviceID, sensorRoute, alarmType);
@@ -177,8 +183,8 @@ public class RedisSensorAlarmMessagePushService {
         return pushTimes.size() >= JfcloudColdChainConstants.MESS_PUSH_MAX_PUSH_COUNT;
     }
 
-    public boolean hasExceededPushLimitLike(String openid, String deviceID, Integer sensorRoute, String alarmType) {
-        String key = generatePushHistoryKey(openid, deviceID, sensorRoute, alarmType);
+    public boolean hasExceededPushLimitLike(String sensorCode, Integer sensorRoute, String alarmType) {
+        String key = generateAlarmHistoryKey(sensorCode, sensorRoute, alarmType);
         Set<String> keys = redisTemplate.keys(key);
         if (keys == null || keys.isEmpty()) {
             return false;

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WebSocketPushService.java

@@ -28,6 +28,7 @@ public class WebSocketPushService implements MessagePushService {
             JSONObject alarmJson = new JSONObject();
             alarmJson.set("sensorCode", sensorCode != null ? sensorCode : "");
             alarmJson.set("sensorRoute", sensorRoute != null ? sensorRoute : "");
+            alarmJson.set("status", "online");
             alarmJson.set("value", String.valueOf(alarm.getValue()));
             alarmJson.set("settingValue", String.valueOf(alarm.getThreshold()));
             alarmJson.set("alarmType", alarmType != null ? alarmType : "");

+ 1 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/config/JfcloudColdChainConstants.java

@@ -81,6 +81,6 @@ public interface JfcloudColdChainConstants {
     /**
      * 每 10 分钟定期执行设备缓存更新
      */
-    Long OFFLINE_THRESHOLD_SECONDS = 10 * 60 * 1000L;
+    Long OFFLINE_THRESHOLD_SECONDS = 5 * 60 * 1000L;
 
 }

+ 18 - 2
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/controller/SimsController.java

@@ -1,7 +1,9 @@
 package vip.xiaonuo.coldchain.modular.app.controller;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
@@ -11,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
 import vip.xiaonuo.coldchain.core.alarm.service.SensorAlarmService;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
 import vip.xiaonuo.coldchain.modular.app.dto.DeviceDataDto;
@@ -50,6 +53,8 @@ public class SimsController {
     private MonitorTargetRegionService monitorTargetRegionService;
     @Resource
     private MonitorTargetService monitorTargetService;
+    @Resource
+    private SensorAlarmService sensorAlarmService;
 
     @Operation(summary = "获取设备的最新的温湿度")
     @GetMapping("/{deviceCode}/{roads}")
@@ -76,7 +81,9 @@ public class SimsController {
     @Operation(summary = "导出传感器数据")
     @PostMapping("/monitornotice/export")
     public void export(HttpServletResponse response, TrendParam trendParam, MultipartFile file) {
-        MonitorDevice monitorDevice = monitorDeviceService.queryEntity(trendParam.getDeviceId());
+        Assert.isTrue(StrUtil.isNotBlank(trendParam.getSensorCode()), "sensorCode不能为空");
+        MonitorDevice monitorDevice = monitorDeviceService.findByDeviceCode(trendParam.getSensorCode());
+        trendParam.setDeviceId(monitorDevice.getId());
         AppTrendParam appTrendParam = BeanUtil.copyProperties(trendParam, AppTrendParam.class);
         appTrendParam.setSensorCode(monitorDevice.getDeviceCode());
         appDeviceService.export(response, appTrendParam, file);
@@ -112,7 +119,7 @@ public class SimsController {
     @Operation(summary = "设置点位上下限值")
     @PostMapping("/monitortargetregion/update/limit")
     public CommonResult<Boolean> updateRegionLimit(@RequestBody @Valid UpdateLimitParam updateLimitParam) {
-        if (StrUtil.isNotBlank(updateLimitParam.getMonitorTargetRegionId())) {
+        if (StrUtil.isBlank(updateLimitParam.getMonitorTargetRegionId())) {
             MonitorTargetRegion monitorTargetRegion = monitorTargetRegionService.findOneByDeviceCodeAndSensorNo(updateLimitParam.getSensorCode(), updateLimitParam.getSensorRoute());
             updateLimitParam.setMonitorTargetRegionId(monitorTargetRegion.getId());
         }
@@ -130,4 +137,13 @@ public class SimsController {
         return CommonResult.data(monitorTargetService.queryEntity(monitorTargetRegion.getMonitorTargetId()));
     }
 
+    /**
+     * 获取预警历史
+     */
+    @Operation(summary = "获取预警历史")
+    @PostMapping("/monitordevice/getAlarmHistory")
+    public CommonResult<Page<SensorAlarm>> getAlarmHistory(@RequestBody @Valid SensorAlarmSearchParam sensorAlarmSearchParam) {
+        return CommonResult.data(sensorAlarmService.getSimsAlarmHistory(sensorAlarmSearchParam));
+    }
+
 }

+ 31 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/param/SensorAlarmSearchParam.java

@@ -0,0 +1,31 @@
+package vip.xiaonuo.coldchain.modular.app.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SensorAlarmSearchParam {
+
+    private String sensorCode;
+    private Integer sensorRoute;
+    private Date startTime;
+    private Date endTime;
+
+    /**
+     * 当前页
+     */
+    @Schema(description = "当前页码")
+    private Integer current;
+
+    /**
+     * 每页条数
+     */
+    @Schema(description = "每页条数")
+    private Integer size;
+}

+ 7 - 1
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/app/service/AppDeviceService.java

@@ -47,6 +47,7 @@ import vip.xiaonuo.coldchain.core.alarm.mapper.SensorAlarmMapper;
 import vip.xiaonuo.coldchain.core.alarm.service.SensorAlarmService;
 import vip.xiaonuo.coldchain.core.alarm.service.delay.DeviceAlertDelayService;
 import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
+import vip.xiaonuo.coldchain.core.config.JfcloudRedisCacheService;
 import vip.xiaonuo.coldchain.core.service.JfcloudSensorDataService;
 import vip.xiaonuo.coldchain.modular.app.dto.AppInfo;
 import vip.xiaonuo.coldchain.modular.app.param.*;
@@ -99,6 +100,7 @@ public class AppDeviceService {
     private final DeviceAlertDelayService delayService;
 
     private final SensorAlarmMapper sensorAlarmMapper;
+    private final JfcloudRedisCacheService jfcloudRedisCacheService;
     @Resource
     DevConfigService devConfigService;
 
@@ -718,7 +720,11 @@ public class AppDeviceService {
         updateField(appDeviceAlarmParam::getPm25Down, monitorTargetRegion::setPm25Down);
         updateField(appDeviceAlarmParam::getPm10Up, monitorTargetRegion::setPm10Up);
         updateField(appDeviceAlarmParam::getPm10Down, monitorTargetRegion::setPm10Down);
-        return monitorTargetRegionService.updateById(monitorTargetRegion);
+        boolean falg = monitorTargetRegionService.updateById(monitorTargetRegion);
+        if (falg) {
+            jfcloudRedisCacheService.evictMonitorTargetRegionCache(monitorTargetRegion.getDeviceCode(), monitorTargetRegion.getSensorRoute());
+        }
+        return falg;
     }
 
     private <V> void updateField(Supplier<V> getter, Consumer<V> setter) {

+ 2 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitornotice/param/TrendParam.java

@@ -20,4 +20,6 @@ public class TrendParam {
     private String endTime;
 
     private String aggregationWindow;
+
+    private String sensorCode;
 }

+ 6 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/modular/monitornotice/service/impl/MonitorNoticeServiceImpl.java

@@ -435,6 +435,12 @@ public class MonitorNoticeServiceImpl extends ServiceImpl<MonitorNoticeMapper, M
         Date date = new Date();
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         realtime.setUpdateTime(format.format(date));
+        realtime.setTemperatureUp(oneByDeviceCodeAndSensorNo.getTemperatureUp());
+        realtime.setTemperatureDown(oneByDeviceCodeAndSensorNo.getTemperatureDown());
+        realtime.setHumidityUp(oneByDeviceCodeAndSensorNo.getHumidityUp());
+        realtime.setHumidityDown(oneByDeviceCodeAndSensorNo.getHumidityDown());
+        realtime.setCo2Up(oneByDeviceCodeAndSensorNo.getCo2Up());
+        realtime.setCo2Down(oneByDeviceCodeAndSensorNo.getCo2Down());
         return realtime;
     }
 }