Forráskód Böngészése

动环设备告警规则关联

jingyuanchao 1 éve
szülő
commit
513f0cadac
16 módosított fájl, 417 hozzáadás és 77 törlés
  1. 15 0
      project_data/sql/0.1.1/soc/soc.sql
  2. 18 0
      soc-api/soc-api-system/src/main/java/com/xunmei/system/api/domain/iot/IotDeviceStatus.java
  3. 9 8
      soc-common/soc-common-core/src/main/java/com/xunmei/common/core/domain/mediator/domain/IotAlarmSystemField.java
  4. 3 3
      soc-common/soc-common-core/src/main/java/com/xunmei/common/core/enums/iot/SensorType.java
  5. 15 0
      soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/mapper/IotDeviceStatusMapper.java
  6. 19 0
      soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/IotDeviceStatusService.java
  7. 22 11
      soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotAlarmRuleSourceServiceImpl.java
  8. 0 3
      soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotCommonSensorServiceImpl.java
  9. 27 0
      soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotDeviceStatusServiceImpl.java
  10. 24 1
      soc-modules/soc-modules-iot/src/main/resources/mapper/IotAlarmRuleSourceMapper.xml
  11. 27 1
      soc-modules/soc-modules-iot/src/main/resources/mapper/IotSensorMapper.xml
  12. 3 1
      soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/alarm/service/IotAlarmDataService.java
  13. 149 17
      soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/alarm/service/impl/IotAlarmDataServiceImpl.java
  14. 4 6
      soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/sensor/service/impl/IotSensorServiceImpl.java
  15. 61 9
      soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/iot/service/impl/IotDeviceStatusServiceImpl.java
  16. 21 17
      soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/enums/DeviceTypeEnum.java

+ 15 - 0
project_data/sql/0.1.1/soc/soc.sql

@@ -100,6 +100,21 @@ BEGIN
     END IF;
 
 
+    -- 系统报警属性字段表添加property_name字段
+    IF NOT EXISTS(SELECT *
+                  FROM information_schema.columns
+                  WHERE table_schema = DATABASE()
+                    AND table_name = 'iot_alarm_system_field'
+                    AND column_name = 'property_name') THEN
+        alter table iot_alarm_system_field
+            add property_name varchar(32) null comment '属性名称' after name;
+        update iot_alarm_system_field set property_name = 'alarm';
+        update iot_alarm_system_field set property_name = 'temperature' where sys_field_code = '4183_1';
+        update iot_alarm_system_field set property_name = 'humidity' where sys_field_code = '4183_2';
+    END IF;
+
+
+
 
 
 END ??

+ 18 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/domain/iot/IotDeviceStatus.java

@@ -10,6 +10,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.time.LocalDateTime;
+
 /**
  * 【请填写功能名称】对象 iot_device_status
  *
@@ -39,6 +41,10 @@ public class IotDeviceStatus extends BaseEntity {
     @ApiModelProperty(value = "设备编码")
     private String deviceCode;
 
+    @TableField(value = "device_type")
+    @ApiModelProperty(value = "设备类型")
+    private String deviceType;
+
     @TableField(value = "device_name")
     @ApiModelProperty(value = "设备名称")
     private String deviceName;
@@ -67,6 +73,18 @@ public class IotDeviceStatus extends BaseEntity {
     @ApiModelProperty(value = "设备状态数据")
     private String info;
 
+    @ApiModelProperty(value = "最后一次状态更新时间")
+    @TableField("state_update_time")
+    private LocalDateTime stateUpdateTime;
+
+    @ApiModelProperty(value = "最后一次状态更新时间")
+    @TableField("state_start_time")
+    private LocalDateTime stateStartTime;
+
+    @ApiModelProperty(value = "告警状态,0:正常,1:告警,2:未知")
+    @TableField(value = "state")
+    private Integer state;
+
 
     public void setUniqueCode() {
         this.uniqueCode = this.iotToken + "_" + this.deviceProduct + "_" + this.deviceCode;

+ 9 - 8
soc-common/soc-common-core/src/main/java/com/xunmei/common/core/domain/mediator/domain/IotAlarmSystemField.java

@@ -1,20 +1,17 @@
 package com.xunmei.common.core.domain.mediator.domain;
 
-import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-
-import java.time.LocalDateTime;
-
 import com.baomidou.mybatisplus.annotation.TableField;
-
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
 /**
  * <p>
  * 系统报警属性字段表
@@ -51,6 +48,10 @@ public class IotAlarmSystemField implements Serializable {
     @TableField("name")
     private String name;
 
+    @ApiModelProperty(value = "属性名称")
+    @TableField("property_name")
+    private String propertyName;
+
     @ApiModelProperty(value = "属性规格信息,eg:{'0': '门已关闭','1': '门已打开'}")
     @TableField("specs")
     private String specs;

+ 3 - 3
soc-common/soc-common-core/src/main/java/com/xunmei/common/core/enums/iot/SensorType.java

@@ -67,13 +67,13 @@ public enum SensorType {
         return e != null ? e.getDesc() : "";
     }
 
-    public static Integer getCodeByProduct(String productName) {
+    public static String  getCodeByProduct(String productName) {
         for (SensorType value : SensorType.values()) {
             if (ObjectUtil.equal(value.getProductName(),productName)){
-                return value.getCode();
+                return value.getCode().toString();
             }
         }
-        return null;
+        return StringUtil.EMPTY_STRING;
     }
 
     /**

+ 15 - 0
soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/mapper/IotDeviceStatusMapper.java

@@ -0,0 +1,15 @@
+package com.xunmei.iot.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ *
+ * @author xunmei
+ * @date 2024-07-18
+ */
+public interface IotDeviceStatusMapper extends BaseMapper<IotDeviceStatus> {
+
+
+}

+ 19 - 0
soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/IotDeviceStatusService.java

@@ -0,0 +1,19 @@
+package com.xunmei.iot.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
+
+import java.util.List;
+
+/**
+ * 【请填写功能名称】Service接口
+ *
+ * @author xunmei
+ * @date 2024-07-18
+ */
+public interface IotDeviceStatusService extends IService<IotDeviceStatus> {
+
+
+    List<IotDeviceStatus> selectByUniqueCodeList(List<String> uniqueCodeList);
+}

+ 22 - 11
soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotAlarmRuleSourceServiceImpl.java

@@ -16,15 +16,15 @@ import com.xunmei.common.redis.utils.RedisUtils;
 import com.xunmei.iot.dto.alarm.IotAlarmRuleSourceDetailDto;
 import com.xunmei.iot.dto.alarm.IotAlarmRuleSourceDeviceBatchJoin;
 import com.xunmei.iot.dto.alarm.IotAlarmRuleSourceDeviceDto;
-import com.xunmei.iot.dto.alarm.IotAlarmRuleSourceDeviceRuleDto;
-import com.xunmei.iot.enums.ProductTypeEnum;
 import com.xunmei.iot.enums.ValueTypeEnum;
-import com.xunmei.iot.mapper.IotAlarmRuleExpressMapper;
-import com.xunmei.iot.mapper.IotAlarmRuleMapper;
-import com.xunmei.iot.mapper.IotAlarmRuleSourceMapper;
-import com.xunmei.iot.mapper.IotCommonSensorMapper;
+import com.xunmei.iot.mapper.*;
 import com.xunmei.iot.service.IotAlarmRuleSourceService;
-import com.xunmei.iot.vo.alarm.*;
+import com.xunmei.iot.service.IotDeviceStatusService;
+import com.xunmei.iot.vo.alarm.IotAlarmRuleSourceDetailVo;
+import com.xunmei.iot.vo.alarm.IotAlarmRuleSourceDeviceVo;
+import com.xunmei.iot.vo.alarm.ProductDeviceTempVo;
+import com.xunmei.iot.vo.alarm.ProductTypeDataVo;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
 import com.xunmei.system.api.vo.SysOrgVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -48,7 +48,8 @@ public class IotAlarmRuleSourceServiceImpl extends ServiceImpl<IotAlarmRuleSourc
 
     @Autowired
     private IotCommonSensorMapper iotCommonSensorMapper;
-
+    @Autowired
+    private IotDeviceStatusService iotDeviceStatusService;
     @Override
     public IotAlarmRuleSourceDetailVo detail(IotAlarmRuleSourceDetailDto detailVo) throws Exception {
         IotAlarmRuleSourceDetailVo iotAlarmRuleSourceDetailVo = new IotAlarmRuleSourceDetailVo();
@@ -212,8 +213,18 @@ public class IotAlarmRuleSourceServiceImpl extends ServiceImpl<IotAlarmRuleSourc
                 List<ProductDeviceTempVo> deviceTempList = pdv.getDeviceTempList();
                 //获取对应的设备id
                 List<String> deviceIds = deviceTempList.stream().map(ProductDeviceTempVo::getDeviceId).collect(Collectors.toList());
-
-                List<IotSensor> iotSensors = iotCommonSensorMapper.selectByIds(deviceIds);
+                List<IotDeviceStatus> deviceStatuses = iotDeviceStatusService.selectByUniqueCodeList(deviceIds);
+                // CONCAT(org_id,'-',device_code) as device_code
+                final Map<String, IotDeviceStatus> deviceIdAndName = deviceStatuses.stream().collect(Collectors.toMap(IotDeviceStatus::getUniqueCode, Function.identity()));
+                for (ProductDeviceTempVo ptv : deviceTempList) {
+                    final IotDeviceStatus deviceStatus = deviceIdAndName.get(ptv.getDeviceId());
+                    if (deviceStatus != null) {
+                        ptv.setDeviceName(deviceStatus.getDeviceName());
+                        final String orgName = dealOrgName(cacheList, deviceStatus.getOrgPath(), deviceStatus.getOrgName());
+                        ptv.setOrgName(orgName);
+                    }
+                }
+                /*List<IotSensor> iotSensors = iotCommonSensorMapper.selectByIds(deviceIds);
                 // CONCAT(org_id,'-',device_code) as device_code
                 final Map<String, IotSensor> deviceIdAndName = iotSensors.stream().collect(Collectors.toMap(IotSensor::getDeviceCode, Function.identity()));
                 for (ProductDeviceTempVo ptv : deviceTempList) {
@@ -223,7 +234,7 @@ public class IotAlarmRuleSourceServiceImpl extends ServiceImpl<IotAlarmRuleSourc
                         final String orgName = dealOrgName(cacheList, sensor.getOrgPath(), sensor.getOrgName());
                         ptv.setOrgName(orgName);
                     }
-                }
+                }*/
             }
         }
     }

+ 0 - 3
soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotCommonSensorServiceImpl.java

@@ -22,7 +22,6 @@ import com.xunmei.common.security.utils.SecurityUtils;
 import com.xunmei.iot.dto.sensor.SensorAppPageDto;
 import com.xunmei.iot.dto.sensor.SensorPageDto;
 import com.xunmei.iot.mapper.IotCommonSensorMapper;
-import com.xunmei.iot.mapper.MediatorCategoryMapper;
 import com.xunmei.iot.service.IIotCommonSensorService;
 import com.xunmei.iot.vo.sensor.*;
 import com.xunmei.system.api.RemoteOrgService;
@@ -57,8 +56,6 @@ public class IotCommonSensorServiceImpl extends ServiceImpl<IotCommonSensorMappe
     @Resource
     private IotCommonSensorMapper sensorMapper;
 
-    @Resource
-    private MediatorCategoryMapper categoryMapper;
 
     @Override
     public TableDataInfo<SensorPageVo> selectSensorDataPage(SensorPageDto request) {

+ 27 - 0
soc-modules/soc-modules-iot/src/main/java/com/xunmei/iot/service/impl/IotDeviceStatusServiceImpl.java

@@ -0,0 +1,27 @@
+package com.xunmei.iot.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xunmei.iot.mapper.IotDeviceStatusMapper;
+import com.xunmei.iot.service.IotDeviceStatusService;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+@Service
+public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMapper, IotDeviceStatus> implements IotDeviceStatusService {
+
+
+    @Override
+    public List<IotDeviceStatus> selectByUniqueCodeList(List<String> uniqueCodeList) {
+        if (ObjectUtil.isEmpty(uniqueCodeList)) {
+            return Collections.emptyList();
+        }
+        LambdaQueryWrapper<IotDeviceStatus> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(IotDeviceStatus::getUniqueCode, uniqueCodeList);
+        return baseMapper.selectList(wrapper);
+    }
+}

+ 24 - 1
soc-modules/soc-modules-iot/src/main/resources/mapper/IotAlarmRuleSourceMapper.xml

@@ -45,7 +45,7 @@
                 LEFT JOIN (select source_type,source_type_des from iot_alarm_system_field GROUP BY source_type,source_type_des) d on a.source_type = d.source_type
         where a.rule_id = #{ruleId}
     </select>
-    <select id="selectDeviceList" resultType="com.xunmei.iot.vo.alarm.IotAlarmRuleSourceDeviceVo">
+    <!--<select id="selectDeviceList" resultType="com.xunmei.iot.vo.alarm.IotAlarmRuleSourceDeviceVo">
         SELECT DISTINCT
         d.device_code AS deviceId,
         d.device_name AS deviceName,
@@ -67,6 +67,29 @@
             and d.device_name like concat('%',#{param.deviceName},'%')
         </if>
 
+    </select>-->
+    <select id="selectDeviceList" resultType="com.xunmei.iot.vo.alarm.IotAlarmRuleSourceDeviceVo">
+        SELECT DISTINCT
+        d.unique_code AS deviceId,
+        d.device_name AS deviceName,
+        d.org_id AS orgId,
+        d.org_path AS orgPath,
+        b.short_name as org_name
+        FROM
+        iot_device_status d
+        LEFT JOIN sys_org b ON d.org_id = b.id
+        where 1=1
+        <if test="param.includeSub == false">
+            and   d.org_id = #{param.orgId}
+        </if>
+        <if test="param.includeSub == true">
+            and   b.path like concat((select path from sys_org where id = #{param.orgId} ),'%')
+        </if>
+        and d.device_type = #{param.type}
+        <if test="param.deviceName != null and param.deviceName != ''">
+            and d.device_name like concat('%',#{param.deviceName},'%')
+        </if>
+
     </select>
     <select id="getRuleSourceSize" resultType="com.xunmei.iot.vo.alarm.IotAlarmRuleSourceTotalVo">
         SELECT

+ 27 - 1
soc-modules/soc-modules-iot/src/main/resources/mapper/IotSensorMapper.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.xunmei.iot.mapper.IotCommonSensorMapper">
-    <select id="selectPageData" resultType="com.xunmei.iot.vo.sensor.SensorPageVo">
+    <!--<select id="selectPageData" resultType="com.xunmei.iot.vo.sensor.SensorPageVo">
         select s.id, org_id, org_name,org_path, device_name, device_type, infos as info,device_code, state_update_time as updateTime,state
         from iot_sensor s
         where s.deleted=0
@@ -26,6 +26,32 @@
         <if test="request.endTime!= null">
             and s.state_update_time <![CDATA[<=]]>  #{request.endTime}
         </if>
+    </select>-->
+    <select id="selectPageData" resultType="com.xunmei.iot.vo.sensor.SensorPageVo">
+        select s.id, s.org_id, s.org_name,s.org_path, s.device_name, ds.device_type, ds.info as info,s.device_code, ds.state_update_time as updateTime,ds.state
+        from iot_device_info s inner join iot_device_status ds on s.id=ds.device_id
+        where s.deleted=0
+        <if test="request.orgId!= null">
+            and s.org_id=#{request.orgId}
+        </if>
+        <if test="request.orgPath!= null">
+            and s.org_path like CONCAT(#{request.orgPath}, '%')
+        </if>
+        <if test="request.deviceName != null and request.deviceName!= ''">
+            and s.device_name like CONCAT('%',#{request.deviceName},'%')
+        </if>
+        <if test="request.state!= null">
+            and ds.state = #{request.state}
+        </if>
+        <if test="request.deviceType!= null and request.deviceType!= ''">
+            and ds.device_type = #{request.deviceType}
+        </if>
+        <if test="request.startTime!= null">
+            and ds.state_update_time >=#{request.startTime}
+        </if>
+        <if test="request.endTime!= null">
+            and ds.state_update_time <![CDATA[<=]]>  #{request.endTime}
+        </if>
     </select>
     <select id="selectAppPageData" resultType="com.xunmei.iot.vo.sensor.SensorAppPageVo">
         select s.id,org_name,org_id, device_name, device_type, infos as info,device_code, state_update_time ,state

+ 3 - 1
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/alarm/service/IotAlarmDataService.java

@@ -5,6 +5,7 @@ import com.xunmei.common.core.domain.iot.domain.IotDvrHardDiskDetection;
 import com.xunmei.common.core.domain.iot.domain.IotSensor;
 import com.xunmei.common.core.domain.mediator.domain.IotAlarmData;
 import com.xunmei.common.core.domain.video.MediatorVideoDiagnosisRecord;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
 
 import java.util.List;
 
@@ -25,7 +26,8 @@ public interface IotAlarmDataService extends IService<IotAlarmData> {
      * 4.根据绑定的规则判断是否需要生成告警数据。
      * 5.如果结果是告警,判断是否已有告警数据,如果有则不生成告警数据。如果是告警结束,则修改告警数据的结束时间。
      */
-    void dealSensorData(IotSensor iotSensor)throws Exception;
+   // void dealSensorData(IotSensor iotSensor)throws Exception;
+    void dealDeviceStatusData(IotDeviceStatus deviceStatus)throws Exception;
 
     /**
      * 处理动环类告警数据

+ 149 - 17
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/alarm/service/impl/IotAlarmDataServiceImpl.java

@@ -28,9 +28,11 @@ import com.xunmei.mediator.api.enums.AlarmVideoTypeEnum;
 import com.xunmei.mediator.api.enums.SmsNotifyType;
 import com.xunmei.mediator.api.sensor.mapper.IotSensorMapper;
 import com.xunmei.mediator.api.alarm.service.IotAlarmDataService;
+import com.xunmei.mediator.iot.mapper.IotDeviceStatusMapper;
 import com.xunmei.system.api.RemoteConfigService;
 import com.xunmei.system.api.RemoteSmsService;
 import com.xunmei.system.api.domain.SysConfig;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
 import com.xunmei.system.api.util.LogUtils;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -71,6 +73,8 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
 
     @Autowired
     private IotSensorMapper iotSensorMapper;
+    @Autowired
+    private IotDeviceStatusMapper deviceStatusMapper;;
 
     @Autowired
     private RemoteConfigService remoteConfigService;
@@ -78,17 +82,141 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
     @Autowired
     private RemoteSmsService remoteSmsService;
 
+    @Override
     @Transactional(rollbackFor = Exception.class)
+    public void dealDeviceStatusData(IotDeviceStatus deviceStatus) throws Exception {
+        Date now = new Date();
+        //判断是否有绑定规则
+        QueryWrapper<IotAlarmRuleSource> qw = new QueryWrapper<>();
+        qw.lambda().eq(IotAlarmRuleSource::getValue, deviceStatus.getUniqueCode())
+                .eq(IotAlarmRuleSource::getOrgId, deviceStatus.getOrgId());
+        IotAlarmRuleSource iotAlarmRuleSource = iotAlarmRuleSourceMapper.selectOne(qw);
+        if (iotAlarmRuleSource == null) {
+            //设备未绑定规则,不做处理
+            return;
+        }
+
+        //获取该设备对应的规则
+        int weekDay = DateUtil.thisDayOfWeek() - 1;
+        // 0 代表星期天, 规则表中星期天存的为7,需要做一下转换
+        if (weekDay == 0) {
+            weekDay = 7;
+        }
+        System.out.println(weekDay);
+        QueryWrapper<IotAlarmRuleExpress> ruleExpress = new QueryWrapper<>();
+        ruleExpress.lambda().eq(IotAlarmRuleExpress::getRuleId, iotAlarmRuleSource.getRuleId())
+                .eq(IotAlarmRuleExpress::getSourceType, iotAlarmRuleSource.getSourceType())
+                .eq(IotAlarmRuleExpress::getWeekDay, weekDay);
+        List<IotAlarmRuleExpress> iotAlarmRuleExpresses = iotAlarmRuleExpressMapper.selectList(ruleExpress);
+
+        List<IotAlarmSystemField> fields = iotAlarmSystemFieldMapper.selectList(null);
+        Map<String, IotAlarmSystemField> fieldMap = fields.stream().collect(Collectors.toMap(IotAlarmSystemField::getSysFieldCode, Function.identity()));
+        String dateStr = DateUtil.format(new Date(), "yyyy-MM-dd");
+        boolean isAlarm = false;
+        boolean isExpress = false;
+        List<IotAlarmData> list = new ArrayList<>();
+        for (IotAlarmRuleExpress express : iotAlarmRuleExpresses) {
+            Boolean smsType = express.getSmsType();
+            boolean isOk = compareTime(express, dateStr, now);
+            if (!isOk) {
+                //不在时间段内
+                continue;
+            }
+            isExpress = true;
+            IotAlarmData alarmData = createAlarmData(deviceStatus, express, fieldMap);
+            if (alarmData != null) {
+                isAlarm = true;
+                alarmData.setSmsType(smsType);
+                list.add(alarmData);
+            }
+        }
+
+        String deviceCode = deviceStatus.getUniqueCode();
+        QueryWrapper<IotAlarmData> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(IotAlarmData::getDeviceId, deviceCode)
+                .eq(IotAlarmData::getOrgId, deviceStatus.getOrgId())
+                .isNull(IotAlarmData::getEndTime);
+        List<IotAlarmData> alarms = baseMapper.selectList(queryWrapper);
+        if (isAlarm && alarms.size() == 0) {
+            //报警中,且表中没有告警数据,则插入数据
+            this.saveBatch(list);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            for (IotAlarmData alarm : list) {
+                if (alarm.getSmsType()) {
+                    LogUtils.DIRECT_HOST_SENSOR_STATUS.info("传感器【 {} 】 发生报警需要发送短信提醒", deviceStatus.getDeviceName());
+                    CompletableFuture.runAsync(()->{
+                        try {
+                            //需要发送短信
+                            LocalDateTime time = alarm.getTime();
+                            String timeStr = time.format(formatter);
+                            String alarmType = SmsNotifyType.getDesc(deviceStatus.getDeviceType());
+                            LogUtils.DIRECT_HOST_SENSOR_STATUS.info("传感器【 {} 】 发生报警: {} ,准备异步发送短信提醒", deviceStatus.getDeviceName(), alarmType);
+                            remoteSmsService.sendSmsIot(deviceStatus.getOrgId(), alarmType, alarm.getContent(), timeStr);
+                            LogUtils.DIRECT_HOST_SENSOR_STATUS.info("传感器【 {} 】 发生报警: {} ,异步发送短信提醒完成", deviceStatus.getDeviceName(), alarmType);
+                        } catch (Exception e) {
+                            LogUtils.DIRECT_HOST_SENSOR_STATUS.info("传感器【 {} 】 发生报警,异步发送短信提醒时发生异常:{}", deviceStatus.getDeviceName(), e.getMessage());
+
+                            throw new RuntimeException(e);
+                        }
+
+                    });
+                }
+            }
+            if (ObjectUtil.notEqual(deviceStatus.getState(), 1)) {
+                deviceStatus.setState(1);
+                deviceStatus.setStateUpdateTime(LocalDateTime.now());
+                deviceStatus.setStateStartTime(LocalDateTime.now());
+                deviceStatusMapper.updateById(deviceStatus);
+            }
+        } else {
+            // 本次上传的设备状态数据 没有生成告警
+            if (isExpress && !isAlarm) {
+                //报警恢复
+                if (alarms.size() != 0) {
+                    // 温湿度一个设备 存在同时2条告警的情况
+                    if (alarms.size() > 1) {
+                        for (IotAlarmData oldAlarm : alarms) {
+                            oldAlarm.setEndTime(LocalDateTime.now());
+                            this.updateById(oldAlarm);
+                        }
+                    } else {
+                        IotAlarmData iotAlarmData = alarms.get(0);
+                        iotAlarmData.setEndTime(LocalDateTime.now());
+                        this.updateById(iotAlarmData);
+                    }
+                }
+
+                if (ObjectUtil.notEqual(deviceStatus.getState(), 0)) {
+                    deviceStatus.setStateUpdateTime(LocalDateTime.now());
+                    deviceStatus.setStateStartTime(LocalDateTime.now());
+                    deviceStatus.setState(0);
+                    deviceStatusMapper.updateById(deviceStatus);
+                }
+            }
+            // 处理温湿度 一个设备 2 种告警, 可能会单个恢复的情况
+            else if (isAlarm && isExpress) {
+                if (ObjectUtil.notEqual(list.size(), alarms.size())) {
+                    List<IotAlarmData> noAlarmData = alarms.stream().filter(x -> !list.stream().anyMatch(y -> ObjectUtil.equal(y.getFieldCode(), x.getFieldCode()))).collect(Collectors.toList());
+                    for (IotAlarmData oldAlarm : noAlarmData) {
+                        oldAlarm.setEndTime(LocalDateTime.now());
+                        this.updateById(oldAlarm);
+                    }
+                }
+            }
+        }
+    }
+
+   /* @Transactional(rollbackFor = Exception.class)
     @Override
     public void dealSensorData(IotSensor iotSensor) throws Exception {
-        /**
+        *//**
          * 生成告警数据逻辑梳理
          * 1.根据传入的设备数据,判断设备类型。
          * 2.根据设备类型获取设备绑定规则。
          * 3.根据绑定规则判断适用于星期几,时间段。
          * 4.根据绑定的规则判断是否需要生成告警数据。
          * 5.如果结果是告警,判断是否已有告警数据,如果有则不生成告警数据。如果是告警结束,则修改告警数据的结束时间。
-         */
+         *//*
         Date now = new Date();
         //判断是否有绑定规则
         QueryWrapper<IotAlarmRuleSource> qw = new QueryWrapper<>();
@@ -209,17 +337,17 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
                 }
             }
         }
-    }
+    }*/
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void dealSensorListData(List<IotSensor> iotSensor) throws Exception {
-        if (ObjectUtil.isEmpty(iotSensor)) {
+        /*if (ObjectUtil.isEmpty(iotSensor)) {
             return;
         }
         for (IotSensor sensor : iotSensor) {
             dealSensorData(sensor);
-        }
+        }*/
     }
 
     @Override
@@ -389,11 +517,11 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
 
     }
 
-    private IotAlarmData createAlarmData(IotSensor iotSensor, IotAlarmRuleExpress express, Map<String, IotAlarmSystemField> fieldMap) {
+    private IotAlarmData createAlarmData(IotDeviceStatus deviceStatus, IotAlarmRuleExpress express, Map<String, IotAlarmSystemField> fieldMap) {
         IotAlarmData iotAlarmData = null;
         String operator = express.getOperator();
         String settingValue = express.getValue();
-        String infos = iotSensor.getInfos();
+        String infos = deviceStatus.getInfo();
         Map<String, String> dataMap = dealInfos(infos);
         IotAlarmSystemField field = fieldMap.get(express.getFieldcode());
         String sensorValue = dataMap.get(field.getName());
@@ -406,7 +534,7 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
             // sensorValue 存在为null的情况, deviceType和 infos.name 不对应的情况
             if (ObjectUtil.equal(sensorValue, settingValue)) {
                 //对上了
-                iotAlarmData = builderAlarm(sensorValue, field, express, iotSensor);
+                iotAlarmData = builderAlarm(sensorValue, field, express, deviceStatus);
             }
         }
 
@@ -415,7 +543,7 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
             final BigDecimal setValue = new BigDecimal(settingValue);
             if (curValue.compareTo(setValue) > 0) {
                 //对上了
-                iotAlarmData = builderAlarm(sensorValue, field, express, iotSensor);
+                iotAlarmData = builderAlarm(sensorValue, field, express, deviceStatus);
             }
         }
 
@@ -424,7 +552,7 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
             final BigDecimal setValue = new BigDecimal(settingValue);
             if (curValue.compareTo(setValue) > 0 || curValue.equals(setValue)) {
                 //对上了
-                iotAlarmData = builderAlarm(sensorValue, field, express, iotSensor);
+                iotAlarmData = builderAlarm(sensorValue, field, express, deviceStatus);
             }
         }
 
@@ -433,7 +561,7 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
             final BigDecimal setValue = new BigDecimal(settingValue);
             if (curValue.compareTo(setValue) < 0) {
                 //对上了
-                iotAlarmData = builderAlarm(sensorValue, field, express, iotSensor);
+                iotAlarmData = builderAlarm(sensorValue, field, express, deviceStatus);
             }
         }
 
@@ -442,7 +570,7 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
             final BigDecimal setValue = new BigDecimal(settingValue);
             if (curValue.compareTo(setValue) < 0 || curValue.equals(setValue)) {
                 //对上了
-                iotAlarmData = builderAlarm(sensorValue, field, express, iotSensor);
+                iotAlarmData = builderAlarm(sensorValue, field, express, deviceStatus);
             }
         }
 
@@ -472,11 +600,11 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
         return iotAlarmData;
     }
 
-    private IotAlarmData builderAlarm(String sensorValue, IotAlarmSystemField field, IotAlarmRuleExpress express, IotSensor iotSensor) {
+    private IotAlarmData builderAlarm(String sensorValue, IotAlarmSystemField field, IotAlarmRuleExpress express, IotDeviceStatus deviceStatus) {
         IotAlarmData iotAlarmData = new IotAlarmData();
         iotAlarmData.setAlarmValue(sensorValue + (field.getUnit() == null ? "" : field.getUnit()));
         iotAlarmData.setTime(LocalDateTime.now());
-        iotAlarmData.setDeviceName(iotSensor.getDeviceName());
+        iotAlarmData.setDeviceName(deviceStatus.getDeviceName());
         iotAlarmData.setRuleId(express.getRuleId());
         iotAlarmData.setSourceType(field.getSourceType());
         iotAlarmData.setSourceTypeDes(field.getSourceTypeDes() + "告警");
@@ -484,10 +612,14 @@ public class IotAlarmDataServiceImpl extends ServiceImpl<IotAlarmDataMapper, Iot
         iotAlarmData.setOperator(express.getOperator());
         iotAlarmData.setValue(express.getValue());
         iotAlarmData.setValueText(express.getValueText());
-        iotAlarmData.setContent(iotSensor.getDeviceName() + "触发" + iotAlarmData.getSourceTypeDes());
-        iotAlarmData.setOrgId(iotSensor.getOrgId());
+        iotAlarmData.setContent(deviceStatus.getDeviceName() + "触发" + iotAlarmData.getSourceTypeDes());
+        iotAlarmData.setOrgId(deviceStatus.getOrgId());
         iotAlarmData.setDataType(AlarmDataTypeEnum.IOT_ALARM.getValue());
-        iotAlarmData.setDeviceId(iotSensor.getDeviceCode());
+        iotAlarmData.setDeviceId(deviceStatus.getUniqueCode());
+        iotAlarmData.setCreateTime(new Date());
+        iotAlarmData.setUpdateTime(new Date());
+        iotAlarmData.setCreateBy("system");
+        iotAlarmData.setUpdateBy("system");
         return iotAlarmData;
     }
 

+ 4 - 6
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/api/sensor/service/impl/IotSensorServiceImpl.java

@@ -14,11 +14,11 @@ import com.xunmei.common.core.domain.iot.domain.IotSensor;
 import com.xunmei.common.core.domain.iot.domain.IotSensorLog;
 import com.xunmei.common.core.utils.DateUtils;
 import com.xunmei.common.security.utils.DictUtils;
-import com.xunmei.mediator.api.sensor.mapper.IotSensorMapper;
 import com.xunmei.mediator.api.alarm.service.IotAlarmDataService;
+import com.xunmei.mediator.api.north.service.NorthErrorService;
+import com.xunmei.mediator.api.sensor.mapper.IotSensorMapper;
 import com.xunmei.mediator.api.sensor.service.IotSensorLogService;
 import com.xunmei.mediator.api.sensor.service.IotSensorService;
-import com.xunmei.mediator.api.north.service.NorthErrorService;
 import com.xunmei.mediator.util.CheckDataUtil;
 import com.xunmei.mediator.util.RedisCheckRepeatDataUtil;
 import com.xunmei.system.api.RemoteOrgService;
@@ -37,8 +37,6 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.support.TransactionSynchronization;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
@@ -154,7 +152,7 @@ public class IotSensorServiceImpl extends ServiceImpl<IotSensorMapper, IotSensor
         northErrorService.saveErrorData(errors);
         updateBatchById(sensorList);
         iotSensorLogService.saveBatch(sensorLogList);
-        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+       /* TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
             @Override
             public void afterCommit() {
                 try {
@@ -163,7 +161,7 @@ public class IotSensorServiceImpl extends ServiceImpl<IotSensorMapper, IotSensor
                     throw new RuntimeException(e);
                 }
             }
-        });
+        });*/
     }
 
     private String dealInfoData(String infoStr) {

+ 61 - 9
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/iot/service/impl/IotDeviceStatusServiceImpl.java

@@ -1,5 +1,6 @@
 package com.xunmei.mediator.iot.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -7,7 +8,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xunmei.common.core.constant.Constants;
+import com.xunmei.common.core.domain.mediator.domain.IotAlarmSystemField;
 import com.xunmei.common.core.enums.iot.SensorType;
+import com.xunmei.mediator.api.alarm.mapper.IotAlarmSystemFieldMapper;
+import com.xunmei.mediator.api.alarm.service.IotAlarmDataService;
 import com.xunmei.mediator.iot.mapper.IotDeviceStatusMapper;
 import com.xunmei.mediator.iot.service.IIotDeviceInfoService;
 import com.xunmei.mediator.iot.service.IotDeviceStatusService;
@@ -16,10 +20,18 @@ import com.xunmei.mediator.websocket.dto.WebsocketResult;
 import com.xunmei.mediator.websocket.enums.DeviceTypeEnum;
 import com.xunmei.system.api.domain.iot.IotDeviceInfo;
 import com.xunmei.system.api.domain.iot.IotDeviceStatus;
+import com.xunmei.system.api.enums.ElectricityMeterAttributes;
+import io.netty.util.internal.StringUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -35,6 +47,10 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
     private IotDeviceStatusMapper iotDeviceStatusMapper;
     @Autowired
     private IIotDeviceInfoService iotDeviceInfoService;
+    @Autowired
+    private IotAlarmDataService alarmDataService;
+    @Autowired
+    private IotAlarmSystemFieldMapper alarmSystemFieldMapper;
 
 
     @Override
@@ -91,8 +107,8 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
      */
 
     @Override
+    @Transactional
     public WebsocketResult dealDeviceStatusChange(WebsocketExecuteReq req) {
-        final JSONObject header = req.getHeader();
         final JSONArray data = (JSONArray) req.getData();
         final String productName = req.getProductName();
         final DeviceTypeEnum deviceTypeEnum = DeviceTypeEnum.valueOf(productName);
@@ -102,7 +118,9 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
             log.error("动环设备状态同步时,未能找到对应设备,token:{},productName:{},deviceNane:{}", req.getToken(), req.getProductName(), req.getDeviceName());
             return new WebsocketResult();
         }
-        final JSONArray array = dealStatusData(data);
+        String deviceType = SensorType.getCodeByProduct(productName);
+        List<IotAlarmSystemField> fieldList = alarmSystemFieldMapper.selectList(new LambdaQueryWrapper<>());
+        final JSONArray array = dealStatusData(data,fieldList,deviceType);
         IotDeviceStatus status = getByDeviceId(code.getId());
         if (status == null) {
             status = new IotDeviceStatus();
@@ -110,27 +128,61 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
             status.setDeviceId(code.getId());
             status.setId(IdWorker.getId());
             status.setUniqueCode();
+            status.setDeviceType(deviceType);
             status.setInfo(JSON.toJSONString(array));
             save(status);
         }else {
             status.setInfo(JSON.toJSONString(array));
             updateById(status);
         }
+        IotDeviceStatus finalStatus = status;
+        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+            @Override
+            public void afterCommit() {
+                try {
+                    alarmDataService.dealDeviceStatusData(finalStatus);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
 
         return new WebsocketResult();
     }
-    private static JSONArray dealStatusData(JSONArray data) {
+    private static JSONArray dealStatusData(JSONArray data,List<IotAlarmSystemField> fieldList,String deviceType) {
         final JSONArray array = new JSONArray();
         for (Object datum : data) {
             JSONObject jsb = (JSONObject) datum;
             JSONObject object = new JSONObject();
-            object.put("propertyName", jsb.get("propertyName"));
-            object.put("args", jsb.get("args"));
-            JSONObject dataSpec = JSON.parseObject(jsb.get("dataSpec").toString());
-            object.put("unit", dataSpec.get("unit"));
-            object.put("unitName", dataSpec.get("unitName"));
-            object.put("dataType", dataSpec.get("dataType"));
             array.add(object);
+            String name = fieldList
+                    .stream()
+                    .filter(r -> ObjectUtil.equal(r.getPropertyName(), jsb.get("propertyName")))
+                    .filter(r -> ObjectUtil.equal(deviceType, String.valueOf(r.getSourceType())))
+                    .map(IotAlarmSystemField::getName)
+                    .findFirst()
+                    .orElse(StringUtil.EMPTY_STRING);
+            String val = DeviceTypeEnum.getStatusText(jsb.get("args"));
+            object.put("name", name);
+            object.put("val", val);
+            final ElectricityMeterAttributes attributesEnum = ElectricityMeterAttributes.getEnumByName(name);
+            if (ObjectUtil.isNull(attributesEnum)) {
+              continue;
+            }
+            if (ObjectUtil.isNotEmpty(attributesEnum.getUnit())) {
+                //说明存在单位,那么把val拼接上单位set到原来的属性值中去
+                object.put("unit", attributesEnum.getUnit());
+                object.put("res", val + attributesEnum.getUnit());
+            } else {
+                object.put("unit", attributesEnum.getEnumText());
+                final Map extraMap = com.alibaba.fastjson2.JSON.parseObject(attributesEnum.getEnumText(), Map.class);
+                for (Object o : extraMap.keySet()) {
+                    if (String.valueOf(o).equals(val)) {
+                        object.put("res", (String) extraMap.get(o));
+                    }
+                }
+
+            }
         }
         return array;
     }

+ 21 - 17
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/enums/DeviceTypeEnum.java

@@ -1,5 +1,13 @@
 package com.xunmei.mediator.websocket.enums;
 
+import io.netty.util.internal.StringUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
 public enum DeviceTypeEnum {
 
     DVS("1", "DVS监控主机"),
@@ -24,24 +32,20 @@ public enum DeviceTypeEnum {
     private String code;
     private String desc;
 
-    private DeviceTypeEnum(String code, String desc) {
-        this.code = code;
-        this.desc = desc;
-    }
-
-    public String getCode() {
-        return this.code;
-    }
 
-    public void setCode(String code) {
-        this.code = code;
+    public static String getStatusText(Object obj){
+        if (obj == null){
+            return StringUtil.EMPTY_STRING;
+        }
+        if (obj instanceof Boolean){
+            //true:报警,false:正常
+            if (Boolean.TRUE.equals(obj)){
+                return "1";
+            }else{
+                return "0";
+            }
+        }
+        return obj.toString();
     }
 
-    public String getDesc() {
-        return this.desc;
-    }
-
-    public void setDesc(String desc) {
-        this.desc = desc;
-    }
 }