Selaa lähdekoodia

【代码优化】IoT:实现 IotDeviceEventReportVertxHandler 事件上行

YunaiV 6 kuukautta sitten
vanhempi
sitoutus
a74459e94e

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamService.java

@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS
 import jakarta.validation.Valid;
 
 /**
- * 设备下行 Service 接口
+ * IoT 设备下行 Service 接口
  *
  * 目的:服务端 -> 插件 -> 设备
  *

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java

@@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DOWNSTREAM_FAILED;
 
 /**
- * 设备下行 Service 实现类
+ * IoT 设备下行 Service 实现类
  *
  * @author 芋道源码
  */

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamService.java

@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceS
 import jakarta.validation.Valid;
 
 /**
- * 设备上行 Service 接口
+ * IoT 设备上行 Service 接口
  *
  * 目的:设备 -> 插件 -> 服务端
  *

+ 5 - 5
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java

@@ -31,7 +31,7 @@ import java.util.Map;
 import java.util.Objects;
 
 /**
- * 设备上行 Service 实现类
+ * IoT 设备上行 Service 实现类
  *
  * @author 芋道源码
  */
@@ -123,11 +123,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
     @Override
     public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
         // 1.1 获得设备
-        log.info("[reportDevicePropertyData][上报设备属性: {}]", reportReqDTO);
+        log.info("[reportDeviceProperty][上报设备属性: {}]", reportReqDTO);
         IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache(
                 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
         if (device == null) {
-            log.error("[reportDevicePropertyData][设备({}/{})不存在]",
+            log.error("[reportDeviceProperty][设备({}/{})不存在]",
                     reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
             return;
         }
@@ -145,11 +145,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
     @Override
     public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
         // 1.1 获得设备
-        log.info("[reportDeviceEventData][上报设备事件: {}]", reportReqDTO);
+        log.info("[reportDeviceEvent][上报设备事件: {}]", reportReqDTO);
         IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache(
                 reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
         if (device == null) {
-            log.error("[reportDeviceEventData][设备({}/{})不存在]",
+            log.error("[reportDeviceEvent][设备({}/{})不存在]",
                     reportReqDTO.getProductKey(), reportReqDTO.getDeviceName());
             return;
         }

+ 3 - 0
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/IotDeviceUpstreamServer.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.iot.plugin.http.upstream;
 
 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
+import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDeviceEventReportVertxHandler;
 import cn.iocoder.yudao.module.iot.plugin.http.upstream.router.IotDevicePropertyReportVertxHandler;
 import io.vertx.core.Vertx;
 import io.vertx.core.http.HttpServer;
@@ -32,6 +33,8 @@ public class IotDeviceUpstreamServer {
         router.route().handler(BodyHandler.create()); // 处理 Body
         router.post(IotDevicePropertyReportVertxHandler.PATH)
                 .handler(new IotDevicePropertyReportVertxHandler(deviceUpstreamApi));
+        router.post(IotDeviceEventReportVertxHandler.PATH)
+                .handler(new IotDeviceEventReportVertxHandler(deviceUpstreamApi));
         // 创建 HttpServer 实例
         this.server = vertx.createHttpServer().requestHandler(router);
     }

+ 75 - 0
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDeviceEventReportVertxHandler.java

@@ -0,0 +1,75 @@
+package cn.iocoder.yudao.module.iot.plugin.http.upstream.router;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
+import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO;
+import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO;
+import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
+import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
+import io.vertx.core.Handler;
+import io.vertx.core.json.JsonObject;
+import io.vertx.ext.web.RoutingContext;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
+import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
+
+/**
+ * IoT 设备设备上报的 Vert.x Handler
+ */
+@RequiredArgsConstructor
+@Slf4j
+public class IotDeviceEventReportVertxHandler implements Handler<RoutingContext> {
+
+    public static final String PATH = "/sys/:productKey/:deviceName/thing/event/:identifier/post";
+
+    private final IotDeviceUpstreamApi deviceUpstreamApi;
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void handle(RoutingContext routingContext) {
+        // 1. 解析参数
+        IotDeviceEventReportReqDTO reportReqDTO;
+        try {
+            String productKey = routingContext.pathParam("productKey");
+            String deviceName = routingContext.pathParam("deviceName");
+            String identifier = routingContext.pathParam("identifier");
+            JsonObject body = routingContext.body().asJsonObject();
+            String id = ObjUtil.defaultIfBlank(body.getString("id"), IdUtil.fastSimpleUUID());
+            Map<String, Object> params = (Map<String, Object>) body.getMap().get("params");
+            reportReqDTO = ((IotDeviceEventReportReqDTO)
+                    new IotDeviceEventReportReqDTO().setRequestId(id)
+                            .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
+                            .setProductKey(productKey).setDeviceName(deviceName))
+                    .setIdentifier(identifier).setParams(params);
+        } catch (Exception e) {
+            log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
+            IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
+            return;
+        }
+
+        try {
+            // 2. 设备上线
+            deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
+                    new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID())
+                            .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
+                            .setProductKey(reportReqDTO.getProductKey()).setDeviceName(reportReqDTO.getDeviceName()))
+                    .setState(IotDeviceStateEnum.ONLINE.getState()));
+
+            // 3.1 属性上报
+            CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceEvent(reportReqDTO);
+            // 3.2 返回结果
+            IotPluginCommonUtils.writeJson(routingContext, result);
+        } catch (Exception e) {
+            log.error("[handle][请求参数({}) 时间上报异常]", reportReqDTO, e);
+            IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
+        }
+    }
+
+}

+ 5 - 1
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDevicePropertyReportVertxHandler.java

@@ -55,6 +55,10 @@ public class IotDevicePropertyReportVertxHandler implements Handler<RoutingConte
             return;
         }
 
+        // TODO @芋艿:secret 校验。目前的想法:
+        //      方案一:请求的时候,带上 secret 参数,然后进行校验,减少请求的频次。不过可能要看下 mqtt 能不能复用!
+        //      方案二:本地有设备信息的缓存,异步刷新。这样可能 mqtt 的校验,和 http 校验都容易适配。
+
         try {
             // 2. 设备上线
             deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
@@ -68,7 +72,7 @@ public class IotDevicePropertyReportVertxHandler implements Handler<RoutingConte
             // 3.2 返回结果
             IotPluginCommonUtils.writeJson(routingContext, result);
         } catch (Exception e) {
-            log.error("[handle][请求参数({}) 属性获取异常]", reportReqDTO, e);
+            log.error("[handle][请求参数({}) 属性上报异常]", reportReqDTO, e);
             IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
         }
     }