Commit 4cefea68809b5ca38903c6254357ac985b974810

Authored by 安浩浩
1 parent 4746281d

【功能完善】IoT: 添加 MQTT 消息处理器,重构设备属性和事件上报逻辑,优化消息处理流程

yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertySetVertxHandler.java
@@ -16,7 +16,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC @@ -16,7 +16,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
16 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR; 16 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
17 17
18 /** 18 /**
19 - * IoT 设备服务设置 Vertx Handler 19 + * IoT 设置设备属性 Vertx Handler
20 * 20 *
21 * 芋道源码 21 * 芋道源码
22 */ 22 */
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/config/IotPluginEmqxAutoConfiguration.java
1 package cn.iocoder.yudao.module.iot.plugin.emqx.config; 1 package cn.iocoder.yudao.module.iot.plugin.emqx.config;
2 2
3 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; 3 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
4 -import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;  
5 import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler; 4 import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
6 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer;  
7 import cn.iocoder.yudao.module.iot.plugin.emqx.downstream.IotDeviceDownstreamHandlerImpl; 5 import cn.iocoder.yudao.module.iot.plugin.emqx.downstream.IotDeviceDownstreamHandlerImpl;
8 import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.IotDeviceUpstreamServer; 6 import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.IotDeviceUpstreamServer;
9 import org.springframework.boot.context.properties.EnableConfigurationProperties; 7 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -21,10 +19,8 @@ public class IotPluginEmqxAutoConfiguration { @@ -21,10 +19,8 @@ public class IotPluginEmqxAutoConfiguration {
21 19
22 @Bean(initMethod = "start", destroyMethod = "stop") 20 @Bean(initMethod = "start", destroyMethod = "stop")
23 public IotDeviceUpstreamServer deviceUpstreamServer(IotDeviceUpstreamApi deviceUpstreamApi, 21 public IotDeviceUpstreamServer deviceUpstreamServer(IotDeviceUpstreamApi deviceUpstreamApi,
24 - IotPluginCommonProperties commonProperties,  
25 - IotPluginEmqxProperties emqxProperties,  
26 - IotDeviceDownstreamServer deviceDownstreamServer) {  
27 - return new IotDeviceUpstreamServer(commonProperties, emqxProperties, deviceUpstreamApi, deviceDownstreamServer); 22 + IotPluginEmqxProperties emqxProperties) {
  23 + return new IotDeviceUpstreamServer(emqxProperties, deviceUpstreamApi);
28 } 24 }
29 25
30 @Bean 26 @Bean
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/downstream/IotDeviceDownstreamHandlerImpl.java
@@ -14,6 +14,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -14,6 +14,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
14 14
15 @Override 15 @Override
16 public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) { 16 public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) {
  17 + // 设备服务调用
  18 + // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}
  19 + // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply
17 return CommonResult.success(true); 20 return CommonResult.success(true);
18 } 21 }
19 22
@@ -24,6 +27,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -24,6 +27,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
24 27
25 @Override 28 @Override
26 public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) { 29 public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) {
  30 + // 设置设备属性 标准 JSON
  31 + // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/property/set
  32 + // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/property/set_reply
27 return CommonResult.success(true); 33 return CommonResult.success(true);
28 } 34 }
29 35
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/IotDeviceUpstreamServer.java
1 package cn.iocoder.yudao.module.iot.plugin.emqx.upstream; 1 package cn.iocoder.yudao.module.iot.plugin.emqx.upstream;
2 2
3 import cn.hutool.core.util.IdUtil; 3 import cn.hutool.core.util.IdUtil;
4 -import cn.hutool.json.JSONObject;  
5 -import cn.hutool.json.JSONUtil;  
6 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; 4 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
7 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO;  
8 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO;  
9 -import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;  
10 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer;  
11 -import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;  
12 import cn.iocoder.yudao.module.iot.plugin.emqx.config.IotPluginEmqxProperties; 5 import cn.iocoder.yudao.module.iot.plugin.emqx.config.IotPluginEmqxProperties;
13 import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router.IotDeviceAuthVertxHandler; 6 import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router.IotDeviceAuthVertxHandler;
  7 +import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router.IotDeviceMqttMessageHandler;
  8 +import io.netty.handler.codec.mqtt.MqttQoS;
14 import io.vertx.core.Vertx; 9 import io.vertx.core.Vertx;
15 import io.vertx.core.http.HttpServer; 10 import io.vertx.core.http.HttpServer;
16 import io.vertx.ext.web.Router; 11 import io.vertx.ext.web.Router;
@@ -19,47 +14,28 @@ import io.vertx.mqtt.MqttClient; @@ -19,47 +14,28 @@ import io.vertx.mqtt.MqttClient;
19 import io.vertx.mqtt.MqttClientOptions; 14 import io.vertx.mqtt.MqttClientOptions;
20 import lombok.extern.slf4j.Slf4j; 15 import lombok.extern.slf4j.Slf4j;
21 16
22 -import java.time.LocalDateTime;  
23 -  
24 /** 17 /**
25 * IoT 设备下行服务端,接收来自 device 设备的请求,转发给 server 服务器 18 * IoT 设备下行服务端,接收来自 device 设备的请求,转发给 server 服务器
26 * <p> 19 * <p>
27 * 协议:HTTP、MQTT 20 * 协议:HTTP、MQTT
28 - * 参考:<a href=  
29 - * "https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.97a72915vRck44#section-g4j-5zg-12b">...</a>  
30 * 21 *
31 * @author haohao 22 * @author haohao
32 */ 23 */
33 @Slf4j 24 @Slf4j
34 public class IotDeviceUpstreamServer { 25 public class IotDeviceUpstreamServer {
35 26
36 - // 设备上报属性 标准 JSON  
37 - // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post  
38 - // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply  
39 - // 设备上报事件 标准 JSON  
40 - // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post  
41 - // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply  
42 -  
43 - private static final String SYS_TOPIC_PREFIX = "/sys/";  
44 - private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post";  
45 - private static final String EVENT_POST_TOPIC_PREFIX = "/thing/event/";  
46 - private static final String EVENT_POST_TOPIC_SUFFIX = "/post";  
47 -  
48 private static final int RECONNECT_DELAY = 5000; // 重连延迟时间(毫秒) 27 private static final int RECONNECT_DELAY = 5000; // 重连延迟时间(毫秒)
49 - private static final int QOS_LEVEL = 1;  
50 28
51 private final Vertx vertx; 29 private final Vertx vertx;
52 private final HttpServer server; 30 private final HttpServer server;
53 private final MqttClient client; 31 private final MqttClient client;
54 private final IotPluginEmqxProperties emqxProperties; 32 private final IotPluginEmqxProperties emqxProperties;
55 - private final IotDeviceUpstreamApi deviceUpstreamApi; 33 + private final IotDeviceMqttMessageHandler mqttMessageHandler;
56 34
57 - public IotDeviceUpstreamServer(IotPluginCommonProperties commonProperties,  
58 - IotPluginEmqxProperties emqxProperties,  
59 - IotDeviceUpstreamApi deviceUpstreamApi,  
60 - IotDeviceDownstreamServer deviceDownstreamServer) { 35 + public IotDeviceUpstreamServer(IotPluginEmqxProperties emqxProperties,
  36 + IotDeviceUpstreamApi deviceUpstreamApi) {
61 this.emqxProperties = emqxProperties; 37 this.emqxProperties = emqxProperties;
62 - this.deviceUpstreamApi = deviceUpstreamApi; 38 +
63 // 创建 Vertx 实例 39 // 创建 Vertx 实例
64 this.vertx = Vertx.vertx(); 40 this.vertx = Vertx.vertx();
65 // 创建 Router 实例 41 // 创建 Router 实例
@@ -77,6 +53,7 @@ public class IotDeviceUpstreamServer { @@ -77,6 +53,7 @@ public class IotDeviceUpstreamServer {
77 .setPassword(emqxProperties.getMqttPassword()) 53 .setPassword(emqxProperties.getMqttPassword())
78 .setSsl(emqxProperties.isMqttSsl()); 54 .setSsl(emqxProperties.isMqttSsl());
79 client = MqttClient.create(vertx, options); 55 client = MqttClient.create(vertx, options);
  56 + this.mqttMessageHandler = new IotDeviceMqttMessageHandler(deviceUpstreamApi, client);
80 } 57 }
81 58
82 /** 59 /**
@@ -108,109 +85,7 @@ public class IotDeviceUpstreamServer { @@ -108,109 +85,7 @@ public class IotDeviceUpstreamServer {
108 * 设置 MQTT 消息处理器 85 * 设置 MQTT 消息处理器
109 */ 86 */
110 private void setupMessageHandler() { 87 private void setupMessageHandler() {
111 - client.publishHandler(message -> {  
112 - String topic = message.topicName();  
113 - String payload = message.payload().toString();  
114 - log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload);  
115 -  
116 - try {  
117 - handleMessage(topic, payload);  
118 - } catch (Exception e) {  
119 - log.error("[messageHandler][处理消息失败][topic: {}][payload: {}]", topic, payload, e);  
120 - }  
121 - });  
122 - }  
123 -  
124 - /**  
125 - * 处理 MQTT 消息  
126 - */  
127 - private void handleMessage(String topic, String payload) {  
128 - // 校验前缀  
129 - if (!topic.startsWith(SYS_TOPIC_PREFIX)) {  
130 - log.warn("[handleMessage][未知的消息类型][topic: {}]", topic);  
131 - return;  
132 - }  
133 -  
134 - // 处理设备属性上报消息  
135 - if (topic.endsWith(PROPERTY_POST_TOPIC)) {  
136 - log.info("[handleMessage][接收到设备属性上报][topic: {}]", topic);  
137 - handlePropertyPost(topic, payload);  
138 - return;  
139 - }  
140 -  
141 - // 处理设备事件上报消息  
142 - if (topic.contains(EVENT_POST_TOPIC_PREFIX) && topic.endsWith(EVENT_POST_TOPIC_SUFFIX)) {  
143 - log.info("[handleMessage][接收到设备事件上报][topic: {}]", topic);  
144 - handleEventPost(topic, payload);  
145 - return;  
146 - }  
147 -  
148 - // 未知消息类型  
149 - log.warn("[handleMessage][未知的消息类型][topic: {}]", topic);  
150 - }  
151 -  
152 - /**  
153 - * 处理设备属性上报  
154 - */  
155 - private void handlePropertyPost(String topic, String payload) {  
156 - // /sys/${productKey}/${deviceName}/thing/event/property/post  
157 - // 解析消息内容  
158 - JSONObject jsonObject = JSONUtil.parseObj(payload);  
159 - String[] topicParts = topic.split("/");  
160 -  
161 - // 构建设备属性上报请求对象  
162 - IotDevicePropertyReportReqDTO reportReqDTO = buildPropertyReportDTO(jsonObject, topicParts);  
163 -  
164 - // 调用上游 API 处理设备上报数据  
165 - deviceUpstreamApi.reportDeviceProperty(reportReqDTO);  
166 - log.info("[handlePropertyPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]",  
167 - topic, JSONUtil.toJsonStr(reportReqDTO));  
168 - }  
169 -  
170 - /**  
171 - * 处理设备事件上报  
172 - */  
173 - private void handleEventPost(String topic, String payload) {  
174 - // /sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post  
175 - // 解析消息内容  
176 - JSONObject jsonObject = JSONUtil.parseObj(payload);  
177 - String[] topicParts = topic.split("/");  
178 -  
179 - // 构建设备事件上报请求对象  
180 - IotDeviceEventReportReqDTO reportReqDTO = buildEventReportDTO(jsonObject, topicParts);  
181 -  
182 - // 调用上游 API 处理设备上报数据  
183 - deviceUpstreamApi.reportDeviceEvent(reportReqDTO);  
184 - log.info("[handleEventPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]",  
185 - topic, JSONUtil.toJsonStr(reportReqDTO));  
186 - }  
187 -  
188 - /**  
189 - * 构建设备属性上报请求对象  
190 - */  
191 - private IotDevicePropertyReportReqDTO buildPropertyReportDTO(JSONObject jsonObject,  
192 - String[] topicParts) {  
193 - return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO()  
194 - .setRequestId(jsonObject.getStr("id"))  
195 - .setProcessId(IotPluginCommonUtils.getProcessId())  
196 - .setReportTime(LocalDateTime.now())  
197 - .setProductKey(topicParts[2])  
198 - .setDeviceName(topicParts[3]))  
199 - .setProperties(jsonObject.getJSONObject("params"));  
200 - }  
201 -  
202 - /**  
203 - * 构建设备事件上报请求对象  
204 - */  
205 - private IotDeviceEventReportReqDTO buildEventReportDTO(JSONObject jsonObject, String[] topicParts) {  
206 - return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO()  
207 - .setRequestId(jsonObject.getStr("id"))  
208 - .setProcessId(IotPluginCommonUtils.getProcessId())  
209 - .setReportTime(LocalDateTime.now())  
210 - .setProductKey(topicParts[2])  
211 - .setDeviceName(topicParts[3]))  
212 - .setIdentifier(topicParts[4])  
213 - .setParams(jsonObject.getJSONObject("params")); 88 + client.publishHandler(mqttMessageHandler::handle);
214 } 89 }
215 90
216 /** 91 /**
@@ -244,7 +119,7 @@ public class IotDeviceUpstreamServer { @@ -244,7 +119,7 @@ public class IotDeviceUpstreamServer {
244 private void subscribeToTopics() { 119 private void subscribeToTopics() {
245 String[] topics = emqxProperties.getMqttTopics().split(","); 120 String[] topics = emqxProperties.getMqttTopics().split(",");
246 for (String topic : topics) { 121 for (String topic : topics) {
247 - client.subscribe(topic, QOS_LEVEL) 122 + client.subscribe(topic, MqttQoS.AT_LEAST_ONCE.value())
248 .onSuccess(v -> log.info("[subscribeToTopics][成功订阅主题: {}]", topic)) 123 .onSuccess(v -> log.info("[subscribeToTopics][成功订阅主题: {}]", topic))
249 .onFailure(err -> log.error("[subscribeToTopics][订阅主题失败: {}]", topic, err)); 124 .onFailure(err -> log.error("[subscribeToTopics][订阅主题失败: {}]", topic, err));
250 } 125 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/router/IotDeviceMqttMessageHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router;
  2 +
  3 +import cn.hutool.json.JSONObject;
  4 +import cn.hutool.json.JSONUtil;
  5 +import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
  6 +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO;
  7 +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO;
  8 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
  9 +import io.netty.handler.codec.mqtt.MqttQoS;
  10 +import io.vertx.core.buffer.Buffer;
  11 +import io.vertx.mqtt.MqttClient;
  12 +import io.vertx.mqtt.messages.MqttPublishMessage;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +
  15 +import java.time.LocalDateTime;
  16 +
  17 +/**
  18 + * IoT 设备 MQTT 消息处理器
  19 + * <p>
  20 + * 参考:
  21 + * <p>
  22 + * "<a href="https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.97a72915vRck44#section-g4j-5zg-12b">...</a>">
  23 + */
  24 +@Slf4j
  25 +public class IotDeviceMqttMessageHandler {
  26 +
  27 + // 设备上报属性 标准 JSON
  28 + // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post
  29 + // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply
  30 + // 设备上报事件 标准 JSON
  31 + // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post
  32 + // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply
  33 +
  34 + private static final String SYS_TOPIC_PREFIX = "/sys/";
  35 + private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post";
  36 + private static final String EVENT_POST_TOPIC_PREFIX = "/thing/event/";
  37 + private static final String EVENT_POST_TOPIC_SUFFIX = "/post";
  38 +
  39 + private final IotDeviceUpstreamApi deviceUpstreamApi;
  40 + private final MqttClient mqttClient;
  41 +
  42 + public IotDeviceMqttMessageHandler(IotDeviceUpstreamApi deviceUpstreamApi, MqttClient mqttClient) {
  43 + this.deviceUpstreamApi = deviceUpstreamApi;
  44 + this.mqttClient = mqttClient;
  45 + }
  46 +
  47 + public void handle(MqttPublishMessage message) {
  48 + String topic = message.topicName();
  49 + String payload = message.payload().toString();
  50 + log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload);
  51 +
  52 + try {
  53 + handleMessage(topic, payload);
  54 + } catch (Exception e) {
  55 + log.error("[messageHandler][处理消息失败][topic: {}][payload: {}]", topic, payload, e);
  56 + }
  57 + }
  58 +
  59 + private void handleMessage(String topic, String payload) {
  60 + // 校验前缀
  61 + if (!topic.startsWith(SYS_TOPIC_PREFIX)) {
  62 + log.warn("[handleMessage][未知的消息类型][topic: {}]", topic);
  63 + return;
  64 + }
  65 +
  66 + // 处理设备属性上报消息
  67 + if (topic.endsWith(PROPERTY_POST_TOPIC)) {
  68 + log.info("[handleMessage][接收到设备属性上报][topic: {}]", topic);
  69 + handlePropertyPost(topic, payload);
  70 + return;
  71 + }
  72 +
  73 + // 处理设备事件上报消息
  74 + if (topic.contains(EVENT_POST_TOPIC_PREFIX) && topic.endsWith(EVENT_POST_TOPIC_SUFFIX)) {
  75 + log.info("[handleMessage][接收到设备事件上报][topic: {}]", topic);
  76 + handleEventPost(topic, payload);
  77 + return;
  78 + }
  79 +
  80 + // 未知消息类型
  81 + log.warn("[handleMessage][未知的消息类型][topic: {}]", topic);
  82 + }
  83 +
  84 + /**
  85 + * 处理设备属性上报消息
  86 + *
  87 + * @param topic 主题
  88 + * @param payload 消息内容
  89 + */
  90 + private void handlePropertyPost(String topic, String payload) {
  91 + // 解析消息内容
  92 + JSONObject jsonObject = JSONUtil.parseObj(payload);
  93 + String[] topicParts = topic.split("/");
  94 +
  95 + // 构建设备属性上报请求对象
  96 + IotDevicePropertyReportReqDTO reportReqDTO = buildPropertyReportDTO(jsonObject, topicParts);
  97 +
  98 + // 调用上游 API 处理设备上报数据
  99 + deviceUpstreamApi.reportDeviceProperty(reportReqDTO);
  100 + log.info("[handlePropertyPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]",
  101 + topic, JSONUtil.toJsonStr(reportReqDTO));
  102 +
  103 + // 发送响应消息
  104 + String replyTopic = topic + "_reply";
  105 + JSONObject response = new JSONObject()
  106 + .set("id", jsonObject.getStr("id"))
  107 + .set("code", 200)
  108 + .set("data", new JSONObject())
  109 + .set("message", "success")
  110 + .set("method", "thing.event.property.post");
  111 +
  112 + mqttClient.publish(replyTopic,
  113 + Buffer.buffer(response.toString()),
  114 + MqttQoS.AT_LEAST_ONCE,
  115 + false,
  116 + false);
  117 + log.info("[handlePropertyPost][发送响应消息成功][topic: {}][response: {}]",
  118 + replyTopic, response.toString());
  119 + }
  120 +
  121 + /**
  122 + * 处理设备事件上报消息
  123 + *
  124 + * @param topic 主题
  125 + * @param payload 消息内容
  126 + */
  127 + private void handleEventPost(String topic, String payload) {
  128 + // 解析消息内容
  129 + JSONObject jsonObject = JSONUtil.parseObj(payload);
  130 + String[] topicParts = topic.split("/");
  131 +
  132 + // 构建设备事件上报请求对象
  133 + IotDeviceEventReportReqDTO reportReqDTO = buildEventReportDTO(jsonObject, topicParts);
  134 +
  135 + // 调用上游 API 处理设备上报数据
  136 + deviceUpstreamApi.reportDeviceEvent(reportReqDTO);
  137 + log.info("[handleEventPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]",
  138 + topic, JSONUtil.toJsonStr(reportReqDTO));
  139 +
  140 + // 发送响应消息
  141 + String replyTopic = topic + "_reply";
  142 + String eventIdentifier = topicParts[6]; // 从 topic 中获取事件标识符
  143 + JSONObject response = new JSONObject()
  144 + .set("id", jsonObject.getStr("id"))
  145 + .set("code", 200)
  146 + .set("data", new JSONObject())
  147 + .set("message", "success")
  148 + .set("method", "thing.event." + eventIdentifier + ".post");
  149 +
  150 + mqttClient.publish(replyTopic,
  151 + Buffer.buffer(response.toString()),
  152 + MqttQoS.AT_LEAST_ONCE,
  153 + false,
  154 + false);
  155 + log.info("[handleEventPost][发送响应消息成功][topic: {}][response: {}]",
  156 + replyTopic, response.toString());
  157 + }
  158 +
  159 + /**
  160 + * 构建设备属性上报请求对象
  161 + *
  162 + * @param jsonObject 消息内容
  163 + * @param topicParts 主题部分
  164 + * @return 设备属性上报请求对象
  165 + */
  166 + private IotDevicePropertyReportReqDTO buildPropertyReportDTO(JSONObject jsonObject,
  167 + String[] topicParts) {
  168 + return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO()
  169 + .setRequestId(jsonObject.getStr("id"))
  170 + .setProcessId(IotPluginCommonUtils.getProcessId())
  171 + .setReportTime(LocalDateTime.now())
  172 + .setProductKey(topicParts[2])
  173 + .setDeviceName(topicParts[3]))
  174 + .setProperties(jsonObject.getJSONObject("params"));
  175 + }
  176 +
  177 + /**
  178 + * 构建设备事件上报请求对象
  179 + *
  180 + * @param jsonObject 消息内容
  181 + * @param topicParts 主题部分
  182 + * @return 设备事件上报请求对象
  183 + */
  184 + private IotDeviceEventReportReqDTO buildEventReportDTO(JSONObject jsonObject, String[] topicParts) {
  185 + return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO()
  186 + .setRequestId(jsonObject.getStr("id"))
  187 + .setProcessId(IotPluginCommonUtils.getProcessId())
  188 + .setReportTime(LocalDateTime.now())
  189 + .setProductKey(topicParts[2])
  190 + .setDeviceName(topicParts[3]))
  191 + .setIdentifier(topicParts[4])
  192 + .setParams(jsonObject.getJSONObject("params"));
  193 + }
  194 +}
0 \ No newline at end of file 195 \ No newline at end of file