Kaynağa Gözat

北向传感器状态代码提交

jingyuanchao 1 yıl önce
ebeveyn
işleme
1b3cda7219

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

@@ -824,6 +824,25 @@ CREATE TABLE `iot_device_info_extend`  (
                                            PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
 
+DROP TABLE IF EXISTS `iot_device_status`;
+CREATE TABLE `iot_device_status` (
+                                     `id` bigint NOT NULL,
+                                     `device_id` bigint DEFAULT NULL COMMENT '设备id',
+                                     `device_product` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '设备品牌',
+                                     `device_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '设备编码',
+                                     `device_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '设备名称',
+                                     `iot_token` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'iot服务唯一编码',
+                                     `org_id` bigint DEFAULT NULL COMMENT '机构id',
+                                     `org_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '机构名称',
+                                     `org_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '机构路径',
+                                     `info` text COLLATE utf8mb4_general_ci COMMENT '设备状态数据',
+                                     `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+                                     `update_time` datetime DEFAULT NULL COMMENT '修改时间',
+                                     `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
+                                     `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
+                                     PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
 
 -- ----------------------------
 -- view structure for hv_org

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

@@ -0,0 +1,76 @@
+package com.xunmei.system.api.domain.iot;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.xunmei.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 【请填写功能名称】对象 iot_device_status
+ *
+ * @author xunmei
+ * @date 2024-07-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("iot_device_status")
+@ApiModel(value = "IotDeviceStatus对象", description = "【请填写功能名称】")
+public class IotDeviceStatus extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    @ApiModelProperty(value = "设备id")
+    private Long deviceId;
+
+    @ApiModelProperty(value = "设备品牌")
+    private String deviceProduct;
+
+    @ApiModelProperty(value = "设备编码")
+    private String deviceCode;
+
+    @ApiModelProperty(value = "设备名称")
+    private String deviceName;
+
+    @ApiModelProperty(value = "iot服务唯一编码")
+    private String iotToken;
+
+    @ApiModelProperty(value = "机构id")
+    private Long orgId;
+
+    @ApiModelProperty(value = "机构名称")
+    private String orgName;
+
+    @ApiModelProperty(value = "机构路径")
+    private String orgPath;
+
+    @ApiModelProperty(value = "设备状态数据")
+    private String info;
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("deviceId", getDeviceId())
+                .append("deviceProduct", getDeviceProduct())
+                .append("deviceCode", getDeviceCode())
+                .append("deviceName", getDeviceName())
+                .append("iotToken", getIotToken())
+                .append("orgId", getOrgId())
+                .append("orgName", getOrgName())
+                .append("orgPath", getOrgPath())
+                .append("info", getInfo())
+                .append("createTime", getCreateTime())
+                .append("updateTime", getUpdateTime())
+                .append("createBy", getCreateBy())
+                .append("updateBy", getUpdateBy())
+                .toString();
+    }
+}

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

@@ -0,0 +1,16 @@
+package com.xunmei.mediator.iot.mapper;
+
+import java.util.List;
+
+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-mediator/src/main/java/com/xunmei/mediator/iot/service/IotDeviceStatusService.java

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

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

@@ -0,0 +1,82 @@
+package com.xunmei.mediator.iot.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xunmei.common.core.utils.DateUtils;
+import com.xunmei.common.core.web.page.TableDataInfo;
+import com.xunmei.mediator.iot.mapper.IotDeviceStatusMapper;
+import com.xunmei.mediator.iot.service.IotDeviceStatusService;
+import com.xunmei.mediator.websocket.dto.WebsocketExecuteReq;
+import com.xunmei.mediator.websocket.dto.WebsocketResult;
+import com.xunmei.system.api.domain.iot.IotDeviceStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ *
+ * @author xunmei
+ * @date 2024-07-18
+ */
+@Service
+public class IotDeviceStatusServiceImpl extends ServiceImpl<IotDeviceStatusMapper, IotDeviceStatus> implements IotDeviceStatusService {
+    @Autowired
+    private IotDeviceStatusMapper iotDeviceStatusMapper;
+
+    /**
+     * {
+     *   "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
+    public WebsocketResult dealDeviceStatusChange(WebsocketExecuteReq req) {
+        final JSONObject header = req.getHeader();
+        final Object data = req.getData();
+
+
+        return null;
+    }
+}

+ 1 - 0
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/constant/WebSocketConstants.java

@@ -55,6 +55,7 @@ public interface WebSocketConstants {
      */
     String ARGS="args";
     String DATA="data";
+    String HEADER="headers";
 
     /**
      * IOT主动上报录像完整性事件

+ 3 - 0
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/dto/WebsocketExecuteReq.java

@@ -1,5 +1,6 @@
 package com.xunmei.mediator.websocket.dto;
 
+import com.alibaba.fastjson.JSONObject;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -24,6 +25,8 @@ public class WebsocketExecuteReq {
 
     private String topic;
 
+    private JSONObject header;
+
     @ApiModelProperty(value = "topic中的productName")
     private String productName;
     @ApiModelProperty(value = "topic中的deviceName")

+ 49 - 0
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/dto/WebsocketPayloadResolve.java

@@ -0,0 +1,49 @@
+package com.xunmei.mediator.websocket.dto;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.xunmei.mediator.websocket.constant.WebSocketConstants;
+import io.netty.util.internal.StringUtil;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Map;
+
+/**
+ * @author jingyuanchao
+ * @date 2024/7/18 16:56
+ */
+@Data
+@NoArgsConstructor
+public class WebsocketPayloadResolve {
+
+    private String routingKey;
+    private JSONObject header;
+    private Object data;
+
+
+    public WebsocketPayloadResolve(WebsocketResult result) {
+        WebsocketPayloadResolve resolve = new WebsocketPayloadResolve();
+        if (result.getPayload() instanceof JSONObject) {
+            Map map = ((JSONObject) result.getPayload()).toJavaObject(Map.class);
+            //上报事件
+            String event = (String) map.get(WebSocketConstants.EVENT);
+            String service = (String) map.get(WebSocketConstants.SERVICE);
+            JSONObject header = (JSONObject) map.get(WebSocketConstants.HEADER);
+            String routingKey = ObjectUtil.isNotEmpty(event) ? event : service;
+            JSONObject args = (JSONObject) (ObjectUtil.isNotEmpty(map.get(WebSocketConstants.DATA)) ? map.get(WebSocketConstants.DATA) : map.get(WebSocketConstants.ARGS));
+            resolve.setRoutingKey(routingKey);
+            resolve.setHeader(header);
+            resolve.setData(args);
+        }
+        if (result.getPayload() instanceof JSONArray) {
+            final JSONArray jsonArray = (JSONArray) result.getPayload();
+            resolve.setData(jsonArray);
+            resolve.setRoutingKey(StringUtil.EMPTY_STRING);
+            resolve.setHeader(result.getHeaders());
+        }
+
+
+    }
+}

+ 2 - 1
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/dto/WebsocketResult.java

@@ -1,6 +1,7 @@
 package com.xunmei.mediator.websocket.dto;
 
 import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.xunmei.common.core.constant.HttpStatus;
 import com.xunmei.mediator.websocket.constant.WebSocketConstants;
 import com.xunmei.system.api.dto.protection.ReceiveErrorDto;
@@ -42,7 +43,7 @@ public class WebsocketResult implements Serializable {
     /**
      * 消息头
      */
-    private String headers;
+    private JSONObject headers;
     /**
      * 消息内容
      */

+ 40 - 46
soc-modules/soc-modules-mediator/src/main/java/com/xunmei/mediator/websocket/handler/SocWebSocketHandler.java

@@ -8,8 +8,9 @@ import com.xunmei.common.core.enums.iot.IotServerConnectStatus;
 import com.xunmei.common.core.utils.JacksonUtils;
 import com.xunmei.common.core.utils.StringUtils;
 import com.xunmei.mediator.api.server.service.IotServerInfoService;
-import com.xunmei.mediator.websocket.constant.WebSocketConstants;
+import com.xunmei.mediator.iot.service.IotDeviceStatusService;
 import com.xunmei.mediator.websocket.dto.WebsocketExecuteReq;
+import com.xunmei.mediator.websocket.dto.WebsocketPayloadResolve;
 import com.xunmei.mediator.websocket.dto.WebsocketResult;
 import com.xunmei.mediator.websocket.enums.TopicTypeEnums;
 import com.xunmei.mediator.websocket.enums.WebsocketStatus;
@@ -17,7 +18,6 @@ import com.xunmei.mediator.websocket.holder.WebSocketSessionHolder;
 import com.xunmei.mediator.websocket.service.RouterService;
 import com.xunmei.mediator.websocket.service.RouterServiceHandler;
 import com.xunmei.mediator.websocket.utils.WebSocketUtils;
-import com.xunmei.system.api.dto.protection.ReceiveErrorDto;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -44,6 +44,8 @@ public class SocWebSocketHandler extends AbstractWebSocketHandler {
 
     @Autowired
     private IotServerInfoService iotServerInfoService;
+    @Autowired
+    private IotDeviceStatusService iotDeviceStatusService;
 
     /**
      * 连接成功后
@@ -146,58 +148,50 @@ public class SocWebSocketHandler extends AbstractWebSocketHandler {
         String token = WebSocketSessionHolder.updateToken(session);
         String payload = message.getPayload();
         log.info("接收到消息:{}", message.getPayload());
-
         if (payload.isEmpty()) {
+            log.error("消息内容为空,token:{}", token);
             return;
         }
         try {
             WebsocketResult websocketResult = JSON.parseObject(payload, WebsocketResult.class);
             Object obj = websocketResult.getPayload();
             String topic = websocketResult.getTopic();
-            if (ObjectUtil.isNotEmpty(obj)) {
-
-                TopicTypeEnums typeEnums = TopicTypeEnums.matcherTopicTypeEnums(topic);
-                if (typeEnums == null) {
-                    log.error("消息topic错误:{}", topic);
-                    return;
-                }
-                Map map = JSON.parseObject(obj.toString(), Map.class);
-                //上报事件
-                String event = (String) map.get(WebSocketConstants.EVENT);
-                String service = (String) map.get(WebSocketConstants.SERVICE);
-                String trigger = (String) map.get(WebSocketConstants.TRIGGER);
-                String routingKey = ObjectUtil.isNotEmpty(event) ? event : service;
-
-                //上报消息内容
-                JSONObject args = (JSONObject) (ObjectUtil.isNotEmpty(map.get(WebSocketConstants.DATA)) ? map.get(WebSocketConstants.DATA) : map.get(WebSocketConstants.ARGS));
-                if (ObjectUtil.isEmpty(event) || args == null) {
-                    log.error("消息内容为空:{}", message.getPayload());
-                    return;
-                }
-                switch (typeEnums) {
-                    //系统通知
-                    case SYS_NOTICE:
-                        break;
-                    //设备状态通知
-                    case DEVICE_STATUS:
-                        break;
-                    //产品事件通知消息
-                    case PRODUCT_EVENT_NOTICE:
-                        //IoT返回服务调用消息
-                    case PRODUCT_SERVICE_REPLY:
-                        RouterService routeService = RouterServiceHandler.getRouteService(typeEnums.getProductName(), routingKey);
-                        WebsocketResult result = (WebsocketResult) routeService.execute(new WebsocketExecuteReq(event, args, token, websocketResult.getId(),topic, typeEnums.getProductName(), typeEnums.getDeviceName()));
-                        WebSocketUtils.sendMessage(session,result);
-                       /* DvsBaseInfo javaObject = JSON.toJavaObject(args, DvsBaseInfo.class);
-                        websocketService.dealDvsBaseInfo(javaObject, token);*/
-                        break;
-                    //IoT返回属性
-                    case PRODUCT_PROPERTY_GET_REPLY:
-                        break;
-                    default:
-                        break;
-                }
+            if (ObjectUtil.isEmpty(obj)) {
+                log.error("消息内容为空,topic:{}", topic);
+                return;
+            }
+            TopicTypeEnums typeEnums = TopicTypeEnums.matcherTopicTypeEnums(topic);
+            if (typeEnums == null) {
+                log.error("消息topic错误,topic:{}", topic);
+                return;
+            }
+            WebsocketPayloadResolve payloadResolve = new WebsocketPayloadResolve(websocketResult);
+            //上报消息内容
+            final Object args = payloadResolve.getData();
+            WebsocketExecuteReq executeReq = new WebsocketExecuteReq(payloadResolve.getRoutingKey(), args, token, websocketResult.getId(), topic, payloadResolve.getHeader(), typeEnums.getProductName(), typeEnums.getDeviceName());
+            WebsocketResult result = null;
+            switch (typeEnums) {
+                //系统通知
+                case SYS_NOTICE:
+                    break;
+                //设备状态通知
+                case DEVICE_STATUS:
+                    break;
+                //产品事件通知消息
+                case PRODUCT_EVENT_NOTICE:
+                    //IoT返回服务调用消息
+                case PRODUCT_SERVICE_REPLY:
+                    RouterService routeService = RouterServiceHandler.getRouteService(typeEnums.getProductName(), payloadResolve.getRoutingKey());
+                    result = (WebsocketResult) routeService.execute(executeReq);
+                    break;
+                //IoT上报属性变化
+                case PRODUCT_PROPERTY_POST:
+                    result = iotDeviceStatusService.dealDeviceStatusChange(executeReq);
+                    break;
+                default:
+                    break;
             }
+            WebSocketUtils.sendMessage(session, result);
         } catch (Exception e) {
             log.error("转换消息内容时出错:{}", e);
         }

+ 5 - 0
soc-modules/soc-modules-mediator/src/main/resources/mapper/IotDeviceStatusMapper.xml

@@ -0,0 +1,5 @@
+<?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.mediator.iot.mapper.IotDeviceStatusMapper">
+
+</mapper>