Browse Source

Merge remote-tracking branch 'origin/V0.1.1' into V0.1.1

xujie 1 year ago
parent
commit
16a9486fe0

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

@@ -120,6 +120,26 @@ BEGIN
     ALTER TABLE `mediator_video_diagnosis_log`
         MODIFY COLUMN `img_url` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '录像质量诊断图片' AFTER `detail_info`;
 
+    -- 防区表删除CategoryId字段
+    IF  EXISTS(SELECT *
+                  FROM information_schema.columns
+                  WHERE table_schema = DATABASE()
+                    AND table_name = 'iot_alarm_defence_area'
+                    AND column_name = 'category_id') THEN
+        ALTER TABLE `soc`.`iot_alarm_defence_area`
+            DROP COLUMN `category_id`;
+    END IF;
+
+    -- 防区表增加module_address字段
+    IF NOT EXISTS(SELECT *
+               FROM information_schema.columns
+               WHERE table_schema = DATABASE()
+                 AND table_name = 'iot_alarm_defence_area'
+                 AND column_name = 'module_address') THEN
+        ALTER TABLE   `iot_alarm_defence_area`
+            ADD COLUMN `module_address` varchar(12) NULL AFTER `iot_token`;
+    END IF;
+
 
 END ??
 DELIMITER ;

+ 3 - 0
soc-common/soc-common-core/src/main/java/com/xunmei/common/core/domain/iot/domain/IotAlarmDefenceArea.java

@@ -108,6 +108,9 @@ public class IotAlarmDefenceArea implements Serializable {
     @ApiModelProperty(value = "iot服务唯一编码")
     @TableField("iot_token")
     private String iotToken;
+    @ApiModelProperty(value = "模块地址")
+    @TableField("module_address")
+    private String moduleAddress;
 
 
 }

+ 66 - 0
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/iot/dto/AlarmDataReq.java

@@ -0,0 +1,66 @@
+package com.xunmei.host.iot.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author jingyuanchao
+ * @date 2024/8/7 15:55
+ */
+@Data
+public class AlarmDataReq{
+
+    private Long id;
+
+    @ApiModelProperty(value = "规则id")
+    private Long ruleId;
+
+    @ApiModelProperty(value = "设备id")
+    private String deviceCode;
+
+    @ApiModelProperty(value = "设备id")
+    private String deviceName;
+
+    @ApiModelProperty(value = "报警源产品类型")
+    private String productType;
+
+    @ApiModelProperty(value = "报警源产品类型显示名称 中文")
+    private String productName;
+
+    @ApiModelProperty(value = "报警源产品类型属性")
+    private String productProperty;
+
+    @ApiModelProperty(value = "告警开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty(value = "告警结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+    @ApiModelProperty(value = "操作符,GT(大于)、GTE(大于等于)、LT(小于)、LTE(小于等于)、EQUALS(等于)")
+    private String operator;
+
+    @ApiModelProperty(value = "对比值key")
+    private String value;
+
+    @ApiModelProperty(value = "对比值value")
+    private String valueText;
+
+    @ApiModelProperty(value = "告警内容")
+    private String content;
+
+    @ApiModelProperty(value = "告警值")
+    private String alarmValue;
+
+    @ApiModelProperty(value = "告警数据类型:0 动环类告警,1主机类告警")
+    private Integer dataType;
+
+    @ApiModelProperty(value = "是否需要发送短信")
+    private Boolean smsType;
+}

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

@@ -15,8 +15,6 @@ import com.xunmei.system.api.domain.iot.IotDeviceStatus;
 public interface IotDeviceStatusService extends IService<IotDeviceStatus> {
 
 
-    WebsocketResult dealDeviceStatusChange(WebsocketExecuteReq executeReq);
-
     IotDeviceStatus getByDeviceId(Long deviceId);
 
 

+ 6 - 3
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/iot/service/impl/IotDeviceInfoServiceImpl.java

@@ -272,7 +272,7 @@ public class IotDeviceInfoServiceImpl extends ServiceImpl<IotDeviceInfoMapper, I
 
     @Override
     public ProductEnums product() {
-        return ProductEnums.IOT_SERVER;
+        return ProductEnums.DETECTION_HOST;
     }
 
     @Override
@@ -676,11 +676,13 @@ public class IotDeviceInfoServiceImpl extends ServiceImpl<IotDeviceInfoMapper, I
         info.setSubSystemCode(String.valueOf(subSystemInfo.getDeviceCode()));
         info.setDefenceAreaName(defenceAreaInfo.getDeviceName());
         info.setDefenceAreaIndex(Integer.parseInt(defenceAreaInfo.getDeviceCode()));
-        info.setSensorType(subSystemInfo.getSubType());
-        info.setSensorTypeName(DefenceAreaType.getName(subSystemInfo.getSubType()));
+        info.setSensorType(defenceAreaInfo.getSubType());
+        info.setSensorTypeName(DefenceAreaType.getName(defenceAreaInfo.getSubType()));
+        info.setModuleAddress(defenceAreaInfo.getModuleAddress());
         //info.setSensorTypeName();
         //alarm:报警,bypass:旁路,normal:正常,activity:活动,unKnown:未知
         info.setState("unKnown");
+        info.setStateText("未知");
         info.setIotToken(serverInfo.getIotCode());
         info.setOrgId(serverInfo.getOrgId());
         info.setOrgName(serverInfo.getOrgName());
@@ -700,6 +702,7 @@ public class IotDeviceInfoServiceImpl extends ServiceImpl<IotDeviceInfoMapper, I
         info.setOrgName(serverInfo.getOrgName());
         info.setOrgPath(serverInfo.getOrgPath());
         info.setSensorType(alarmInputInfo.getSubType());
+        info.setModuleAddress(alarmInputInfo.getModuleAddress());
         info.setSensorTypeName(DefenceAreaType.getName(alarmInputInfo.getSubType()));
         info.setUpdateBy("system");
         info.setUpdateTime(LocalDateTime.now());

+ 115 - 95
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/iot/service/impl/IotDeviceStatusServiceImpl.java

@@ -8,17 +8,26 @@ 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.IotAlarmData;
 import com.xunmei.common.core.domain.mediator.domain.IotAlarmSystemField;
+import com.xunmei.common.core.enums.iot.BaseDeviceTypeEnum;
 import com.xunmei.common.core.enums.iot.DeviceTypeEnum;
 import com.xunmei.common.core.enums.iot.SensorType;
+import com.xunmei.common.core.util.BeanHelper;
 import com.xunmei.host.alarm.mapper.IotAlarmSystemFieldMapper;
 import com.xunmei.host.alarm.service.IotAlarmDataService;
+import com.xunmei.host.iot.dto.AlarmDataReq;
 import com.xunmei.host.iot.mapper.IotDeviceStatusMapper;
 import com.xunmei.host.iot.service.IIotDeviceInfoService;
 import com.xunmei.host.iot.service.IotDeviceStatusService;
+import com.xunmei.host.server.service.IotServerInfoService;
+import com.xunmei.host.websocket.constant.WebSocketConstants;
 import com.xunmei.host.websocket.dto.WebsocketExecuteReq;
 import com.xunmei.host.websocket.dto.WebsocketResult;
 import com.xunmei.host.websocket.enums.DeviceNetStatusEnum;
+import com.xunmei.host.websocket.enums.ProductEnums;
+import com.xunmei.host.websocket.service.RouterService;
+import com.xunmei.system.api.domain.SysOrg;
 import com.xunmei.system.api.domain.iot.IotDeviceInfo;
 import com.xunmei.system.api.domain.iot.IotDeviceStatus;
 import com.xunmei.system.api.enums.ElectricityMeterAttributes;
@@ -28,13 +37,11 @@ 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.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.StringJoiner;
 
 
 /**
@@ -45,16 +52,17 @@ import java.util.Map;
  */
 @Slf4j
 @Service
-public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMapper, IotDeviceStatus> implements IotDeviceStatusService {
+public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMapper, IotDeviceStatus> implements IotDeviceStatusService, RouterService {
     @Autowired
     private IotDeviceStatusMapper iotDeviceStatusMapper;
     @Autowired
     private IIotDeviceInfoService iotDeviceInfoService;
     @Autowired
-    private IotAlarmDataService alarmDataService;
+    private IotServerInfoService serverInfoService;
     @Autowired
     private IotAlarmSystemFieldMapper alarmSystemFieldMapper;
-
+    @Autowired
+    private IotAlarmDataService iotAlarmDataService;
 
     @Override
     public IotDeviceStatus getByDeviceId(Long deviceId) {
@@ -64,94 +72,6 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
         return iotDeviceStatusMapper.selectOne(wrapper);
     }
 
-    /**
-     * {
-     * "topic": "/things/FSU_TemperatureAndHumidity/XXDevice/property/post",
-     * "id":"xxx",  // Guid,消息IoT生成。
-     * "timestamp": "2023-01-11T18:00:00 +08:00",
-     * "headers":{
-     * "topicType":"",// Topic类型,相对于topicCategory的细分
-     * "topicCategory": "",// Topic分类
-     * "productName": "FSU_TemperatureAndHumidity",
-     * "deviceName": "XXDevice"
-     * },
-     * "payload":[
-     * {
-     * "propertyName": "temperature",// 应用方调用的属性名称
-     * "args": 23.6,
-     * "dataSpec": {
-     * "defaultValue": 0,
-     * "max": 5000,
-     * "min": -300,
-     * "step": 0.01,
-     * "unit": "℃",
-     * "unitName": "摄氏度",
-     * "dataType": "Int"
-     * }
-     * },
-     * {
-     * "propertyName": "humidity",// 应用方调用的属性名称
-     * "args": 23.6,
-     * "dataSpec": {
-     * "defaultValue": 0,
-     * "max": 5000,
-     * "min": -300,
-     * "step": 0.01,
-     * "unit": "%RH",
-     * "unitName": "",
-     * "dataType": "Int"
-     * }
-     * }
-     * ]
-     * }
-     *
-     * @param req
-     * @return
-     */
-
-    @Override
-    @Transactional
-    public WebsocketResult dealDeviceStatusChange(WebsocketExecuteReq req) {
-        final JSONArray data = (JSONArray) req.getData();
-        final String productName = req.getProductName();
-        final DeviceTypeEnum deviceTypeEnum = DeviceTypeEnum.valueOf(productName);
-
-        final IotDeviceInfo code = iotDeviceInfoService.selectByTypeAndCode(req.getToken(), deviceTypeEnum.getCode(), req.getProductName(), req.getDeviceName());
-        if (code == null) {
-            log.error("动环设备状态同步时,未能找到对应设备,token:{},productName:{},deviceNane:{}", req.getToken(), req.getProductName(), req.getDeviceName());
-            return new WebsocketResult();
-        }
-        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();
-            BeanUtils.copyProperties(code, status, "id");
-            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, List<IotAlarmSystemField> fieldList, String deviceType) {
         final JSONArray array = new JSONArray();
@@ -167,7 +87,7 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
                     .findFirst()
                     .orElse(StringUtil.EMPTY_STRING);
             String val = DeviceTypeEnum.getStatusText(jsb.get("args"));
-            if (ObjectUtil.hasEmpty(name,val)) {
+            if (ObjectUtil.hasEmpty(name, val)) {
                 continue;
             }
             object.put("name", name);
@@ -220,4 +140,104 @@ public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMappe
 
 
     }
+
+    @Override
+    public ProductEnums product() {
+        return ProductEnums.DETECTION_HOST;
+    }
+
+    @Override
+    public String routerKey() {
+        StringJoiner sj = new StringJoiner(",");
+        //设备状态变更
+        sj.add(WebSocketConstants.SUB_DEVICES_STATUS);
+        //设备发生报警
+        sj.add(WebSocketConstants.SUB_DEVICE_ALARM);
+
+        return sj.toString();
+    }
+
+    @Override
+    public Object execute(WebsocketExecuteReq req) {
+        final String event = req.getEvent();
+        switch (event) {
+            case WebSocketConstants.SUB_DEVICES_STATUS:
+                return dealDeviceStatus(req);
+            case WebSocketConstants.SUB_DEVICE_ALARM:
+                return dealDeviceAlarm(req);
+            default:
+                throw new RuntimeException("未知的消息类型");
+        }
+    }
+
+    private Object dealDeviceAlarm(WebsocketExecuteReq req) {
+        final SysOrg sysOrg = serverInfoService.selectOrgByToken(req.getToken());
+        if (ObjectUtil.isNull(sysOrg)) {
+            LogUtils.WEBSOCKET_MSG.error("收到设备报警消息,根据token:{}未查询到机构信息", req.getToken());
+            return null;
+        }
+        List<IotAlarmSystemField> fieldList = alarmSystemFieldMapper.selectList(new LambdaQueryWrapper<>());
+
+        final JSONArray data = (JSONArray) req.getData();
+        final List<AlarmDataReq> dataReqList = data.toJavaList(AlarmDataReq.class);
+        for (AlarmDataReq dataReq : dataReqList) {
+            IotDeviceInfo deviceInfo = iotDeviceInfoService.selectByTokenProductAndDeviceCode(req.getToken(), req.getProductName(), req.getDeviceName());
+            if (ObjectUtil.isNull(deviceInfo)) {
+                LogUtils.WEBSOCKET_MSG.error("收到设备报警消息,根据token:{},productName:{},deviceName:{}未查询到设备信息", req.getToken(), req.getProductName(), req.getDeviceName());
+                continue;
+            }
+            final IotAlarmData iotAlarmData = BeanHelper.copyProperties(dataReq, IotAlarmData.class);
+            iotAlarmData.setOrgId(sysOrg.getId());
+            iotAlarmData.setDeviceId(String.valueOf(deviceInfo.getId()));
+            final String sourceType = SensorType.getCodeByProduct(dataReq.getProductType());
+            fieldList.stream()
+                    .filter(r->ObjectUtil.equal(r.getSourceType(),sourceType))
+                    .filter(r->ObjectUtil.equal(r.getPropertyName(),dataReq.getProductProperty()))
+                    .findAny()
+                    .ifPresent(r->{
+                        iotAlarmData.setSourceType(r.getSourceType());
+                        iotAlarmData.setSourceTypeDes(r.getSourceTypeDes());
+                        iotAlarmData.setFieldCode(r.getSysFieldCode());
+                    });
+            iotAlarmDataService.save(iotAlarmData);
+            if (Boolean.TRUE.equals(dataReq.getSmsType())) {
+                //todo  发送短信
+            }
+        }
+
+
+
+
+        return null;
+    }
+
+    private WebsocketResult dealDeviceStatus(WebsocketExecuteReq req) {
+        final JSONArray data = (JSONArray) req.getData();
+        final String productName = req.getProductName();
+        final BaseDeviceTypeEnum deviceTypeEnum = BaseDeviceTypeEnum.valueOf(productName);
+
+        final IotDeviceInfo code = iotDeviceInfoService.selectByTypeAndCode(req.getToken(), deviceTypeEnum.getCode(), req.getProductName(), req.getDeviceName());
+        if (code == null) {
+            log.error("动环设备状态同步时,未能找到对应设备,token:{},productName:{},deviceNane:{}", req.getToken(), req.getProductName(), req.getDeviceName());
+            return new WebsocketResult();
+        }
+        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();
+            BeanUtils.copyProperties(code, status, "id");
+            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);
+        }
+        return null;
+    }
 }

+ 8 - 26
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/websocket/constant/WebSocketConstants.java

@@ -77,32 +77,6 @@ public interface WebSocketConstants {
     String UP_LINK_SERVICE_PASS_THROUGH = "uplinkServicePassthrough";
 
     /**
-     * 获取Dvs状态
-     */
-    String GET_DVS_STATUS_SERVICES = "getDvsStatus";
-    /**
-     * 获取通道详细信息列表,包含摄像机状态
-     */
-    String GET_DVS_CHANNEL_INFOS_SERVICES = "getDvsChannelInfos";
-    /**
-     * 获取磁盘信息,基础信息+状态
-     */
-    String GET_DISK_INFOS_SERVICES = "getDiskInfos";
-    /**
-     * 获取录像计划
-     */
-    String GET_DVS_RECORD_PLANS_SERVICES = "getDvsRecordPlans";
-    /**
-     * 添加视频诊断任务
-     */
-    String EXECUTE_VQD_TASK_SERVICES = "excuteVQDTask";
-
-    /**
-     * 获取该产品下的已添加的所有Dvs设备信息
-     */
-    String GET_DVS_INFOS_SERVICES = "getDvsInfos";
-
-    /**
      * 客户端主动上报 视频诊断结果 事件名称
      */
     String VQD = "vqd";
@@ -144,6 +118,14 @@ public interface WebSocketConstants {
     String SUB_SYSTEM_STATUS = "subsystemStatus";
 
     /**
+     * 子设备状态改变事件
+     */
+    String SUB_DEVICES_STATUS = "subDevicesStatus";
+    /**
+     * 设备报警
+     */
+    String SUB_DEVICE_ALARM = "subDeviceAlarm";
+    /**
      * 报警主机报警防区(传感器)改变状态
      */
     String SENSOR_STATUS = "sensorStatus";

+ 1 - 0
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/websocket/dto/dvs/SubDeviceInfo.java

@@ -10,4 +10,5 @@ public class SubDeviceInfo {
     private String type;
     private String parentCode;
     private String subType;//(枚举,防区枚举类型);
+    private String moduleAddress;
 }

+ 1 - 0
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/websocket/enums/ProductEnums.java

@@ -15,6 +15,7 @@ public enum ProductEnums {
     ALARM_HOST(new String[]{"InAnter_BM1600NTSmall", "Hik_DS19A", "HikModule", "FengYe_H402", "HengTong_CKWU01C", "MtaOCX", "CrossProcessDemo", "HoneywellOCX_IPM", "DaHuaAlarmHost", "BOSCH_CMS"}),
 
     IOT_SERVER(new String[]{"IoTServer","IoTServerDevice"}),
+    DETECTION_HOST(new String[]{"DetectionHost","DetectionHostDevice"}),
     FSU_GATEWAY(new String[]{"FSU_Gateway","FSU_Smoke","FSU_Infrared","FSU_TemperatureAndHumidity","FSU_DoorMagnetic","FSU_Gas","FSU_RollingShutterDoor","FSU_Water","FSU_SmartMeter","FSU_AirConditioner","FSU_Ups","FSU_DoPowerControl","FSU_ThreePhaseACVoltage"}),
     ;
 

+ 4 - 5
soc-modules/soc-modules-host/src/main/java/com/xunmei/host/websocket/handler/SocWebSocketHandler.java

@@ -163,10 +163,10 @@ public class SocWebSocketHandler extends AbstractWebSocketHandler {
                 //系统通知
                 case SYS_NOTICE:
                     break;
-                //设备状态通知
+              /*  //设备状态通知
                 case DEVICE_STATUS:
                     iotDeviceStatusService.deviceStatusChangeDeal(executeReq);
-                    break;
+                    break;*/
                 //产品事件通知消息
                 case PRODUCT_EVENT_NOTICE:
                     //IoT返回服务调用消息
@@ -178,14 +178,13 @@ public class SocWebSocketHandler extends AbstractWebSocketHandler {
                     result = (WebsocketResult) routeService.execute(executeReq);
                     break;
                 //IoT上报属性变化
-                case PRODUCT_PROPERTY_POST:
+               /* case PRODUCT_PROPERTY_POST:
                     result = iotDeviceStatusService.dealDeviceStatusChange(executeReq);
-                    break;
+                    break;*/
                 default:
                     break;
             }
             WebSocketUtils.sendMessage(session, result);
-            //LogUtils.WEBSOCKET_MSG.info("中心平台返回 {} 消息,,内容:{}", ip, JacksonUtils.toJSONString(result));
         } catch (Exception e) {
             LogUtils.WEBSOCKET_MSG.error("消息处理失败,ip:{},异常内容:{}", ip, e);
         }