Commit 4919439b960f09f03b836d3d4d7b2a07b892b695

Authored by YunaiV
1 parent 795e06bc

【功能新增】IoT:OTA 升级的下行消息的实现

Showing 12 changed files with 311 additions and 31 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/downstream/IotDeviceOtaUpgradeReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import lombok.Data;
  5 +
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * IoT 设备【OTA】升级下发 Request DTO(更新固件消息)
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class IotDeviceOtaUpgradeReqDTO extends IotDeviceDownstreamAbstractReqDTO {
  15 +
  16 + /**
  17 + * 固件编号
  18 + */
  19 + private Long firmwareId;
  20 + /**
  21 + * 固件版本
  22 + */
  23 + private String version;
  24 +
  25 + /**
  26 + * 签名方式
  27 + *
  28 + * 例如说:MD5、SHA256
  29 + */
  30 + private String signMethod;
  31 + /**
  32 + * 固件文件签名
  33 + */
  34 + private String fileSign;
  35 + /**
  36 + * 固件文件大小
  37 + */
  38 + private Long fileSize;
  39 + /**
  40 + * 固件文件 URL
  41 + */
  42 + private String fileUrl;
  43 +
  44 + /**
  45 + * 自定义信息,建议使用 JSON 格式
  46 + */
  47 + private String information;
  48 +
  49 + public static IotDeviceOtaUpgradeReqDTO build(Map<?, ?> map) {
  50 + return new IotDeviceOtaUpgradeReqDTO()
  51 + .setFirmwareId(MapUtil.getLong(map, "firmwareId")).setVersion((String) map.get("version"))
  52 + .setSignMethod((String) map.get("signMethod")).setFileSign((String) map.get("fileSign"))
  53 + .setFileSize(MapUtil.getLong(map, "fileSize")).setFileUrl((String) map.get("fileUrl"))
  54 + .setInformation((String) map.get("information"));
  55 + }
  56 +
  57 + public static Map<?, ?> build(IotDeviceOtaUpgradeReqDTO dto) {
  58 + return MapUtil.builder()
  59 + .put("firmwareId", dto.getFirmwareId()).put("version", dto.getVersion())
  60 + .put("signMethod", dto.getSignMethod()).put("fileSign", dto.getFileSign())
  61 + .put("fileSize", dto.getFileSize()).put("fileUrl", dto.getFileUrl())
  62 + .put("information", dto.getInformation())
  63 + .build();
  64 + }
  65 +
  66 +}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceOtaProgressReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
  2 +
  3 +import lombok.Data;
  4 +
  5 +// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/progress
  6 +/**
  7 + * IoT 设备【OTA】升级进度 Request DTO(上报更新固件进度)
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Data
  12 +public class IotDeviceOtaProgressReqDTO extends IotDeviceUpstreamAbstractReqDTO {
  13 +
  14 + /**
  15 + * 固件编号
  16 + */
  17 + private Long firmwareId;
  18 +
  19 + /**
  20 + * 升级状态
  21 + *
  22 + * 枚举 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}
  23 + */
  24 + private Integer status;
  25 + /**
  26 + * 升级进度,百分比
  27 + */
  28 + private Integer progress;
  29 +
  30 + /**
  31 + * 升级进度描述
  32 + */
  33 + private String description;
  34 +
  35 +}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceOtaPullReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
  2 +
  3 +// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/pull
  4 +/**
  5 + * IoT 设备【OTA】升级下拉 Request DTO(拉取固件更新)
  6 + *
  7 + * @author 芋道源码
  8 + */
  9 +public class IotDeviceOtaPullReqDTO {
  10 +
  11 + /**
  12 + * 固件编号
  13 + */
  14 + private Long firmwareId;
  15 +
  16 + /**
  17 + * 固件版本
  18 + */
  19 + private String version;
  20 +
  21 +}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceOtaReportReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
  2 +
  3 +// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/report
  4 +/**
  5 + * IoT 设备【OTA】上报 Request DTO(上报固件版本)
  6 + *
  7 + * @author 芋道源码
  8 + */
  9 +public class IotDeviceOtaReportReqDTO {
  10 +
  11 + /**
  12 + * 固件编号
  13 + */
  14 + private Long firmwareId;
  15 +
  16 + /**
  17 + * 固件版本
  18 + */
  19 + private String version;
  20 +
  21 +}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageIdentifierEnum.java
@@ -21,7 +21,12 @@ public enum IotDeviceMessageIdentifierEnum { @@ -21,7 +21,12 @@ public enum IotDeviceMessageIdentifierEnum {
21 CONFIG_SET("set"), // 下行 21 CONFIG_SET("set"), // 下行
22 22
23 SERVICE_INVOKE("${identifier}"), // 下行 23 SERVICE_INVOKE("${identifier}"), // 下行
24 - SERVICE_REPLY_SUFFIX("_reply"); // 芋艿:TODO 芋艿:【讨论】上行 or 下行 24 + SERVICE_REPLY_SUFFIX("_reply"), // 芋艿:TODO 芋艿:【讨论】上行 or 下行
  25 +
  26 + OTA_UPGRADE("upgrade"), // 下行
  27 + OTA_PULL("pull"), // 上行
  28 + OTA_PROGRESS("progress"), // 上行
  29 + OTA_REPORT("report"),; // 上行
25 30
26 /** 31 /**
27 * 标志符 32 * 标志符
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageTypeEnum.java
@@ -17,7 +17,8 @@ public enum IotDeviceMessageTypeEnum implements ArrayValuable&lt;String&gt; { @@ -17,7 +17,8 @@ public enum IotDeviceMessageTypeEnum implements ArrayValuable&lt;String&gt; {
17 PROPERTY("property"), // 设备属性 17 PROPERTY("property"), // 设备属性
18 EVENT("event"), // 设备事件 18 EVENT("event"), // 设备事件
19 SERVICE("service"), // 设备服务 19 SERVICE("service"), // 设备服务
20 - CONFIG("config"); // 设备配置 20 + CONFIG("config"), // 设备配置
  21 + OTA("ota"),; // 设备 OTA
21 22
22 public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new); 23 public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new);
23 24
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.http
@@ -51,4 +51,25 @@ Authorization: Bearer {{token}} @@ -51,4 +51,25 @@ Authorization: Bearer {{token}}
51 "id": 25, 51 "id": 25,
52 "type": "config", 52 "type": "config",
53 "identifier": "set" 53 "identifier": "set"
  54 +}
  55 +
  56 +### 请求 /iot/device/downstream 接口(OTA 升级) => 成功
  57 +POST {{baseUrl}}/iot/device/downstream
  58 +Content-Type: application/json
  59 +tenant-id: {{adminTenentId}}
  60 +Authorization: Bearer {{token}}
  61 +
  62 +{
  63 + "id": 25,
  64 + "type": "ota",
  65 + "identifier": "upgrade",
  66 + "data": {
  67 + "firmwareId": 1,
  68 + "version": "1.0.0",
  69 + "signMethod": "MD5",
  70 + "fileSign": "d41d8cd98f00b204e9800998ecf8427e",
  71 + "fileSize": 1024,
  72 + "fileUrl": "http://example.com/firmware.bin",
  73 + "information": "{\"desc\":\"升级到最新版本\"}"
  74 + }
54 } 75 }
55 \ No newline at end of file 76 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java
@@ -80,11 +80,15 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -80,11 +80,15 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
80 } 80 }
81 // 配置下发 81 // 配置下发
82 if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType()) 82 if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType())
83 - && Objects.equals(downstreamReqVO.getIdentifier(), IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) { 83 + && Objects.equals(downstreamReqVO.getIdentifier(),
  84 + IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) {
84 return setDeviceConfig(downstreamReqVO, device, parentDevice); 85 return setDeviceConfig(downstreamReqVO, device, parentDevice);
85 } 86 }
86 - // TODO 芋艿:ota 升级  
87 - return null; 87 + // OTA 升级
  88 + if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.OTA.getType())) {
  89 + return otaUpgrade(downstreamReqVO, device, parentDevice);
  90 + }
  91 + throw new IllegalArgumentException("不支持的下行消息类型:" + downstreamReqVO);
88 } 92 }
89 93
90 /** 94 /**
@@ -97,7 +101,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -97,7 +101,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
97 */ 101 */
98 @SuppressWarnings("unchecked") 102 @SuppressWarnings("unchecked")
99 private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO, 103 private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO,
100 - IotDeviceDO device, IotDeviceDO parentDevice) { 104 + IotDeviceDO device, IotDeviceDO parentDevice) {
101 // 1. 参数校验 105 // 1. 参数校验
102 if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { 106 if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) {
103 throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); 107 throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
@@ -105,9 +109,10 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -105,9 +109,10 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
105 // TODO @super:【可优化】过滤掉不合法的服务 109 // TODO @super:【可优化】过滤掉不合法的服务
106 110
107 // 2. 发送请求 111 // 2. 发送请求
108 - String url = String.format( "sys/%s/%s/thing/service/%s",  
109 - getProductKey(device, parentDevice), getDeviceName(device, parentDevice), downstreamReqVO.getIdentifier());  
110 - IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() 112 + String url = String.format("sys/%s/%s/thing/service/%s",
  113 + getProductKey(device, parentDevice), getDeviceName(device, parentDevice),
  114 + downstreamReqVO.getIdentifier());
  115 + IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO()
111 .setParams((Map<String, Object>) downstreamReqVO.getData()); 116 .setParams((Map<String, Object>) downstreamReqVO.getData());
112 CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); 117 CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
113 118
@@ -144,7 +149,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -144,7 +149,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
144 // TODO @super:【可优化】过滤掉不合法的属性 149 // TODO @super:【可优化】过滤掉不合法的属性
145 150
146 // 2. 发送请求 151 // 2. 发送请求
147 - String url = String.format( "sys/%s/%s/thing/service/property/set", 152 + String url = String.format("sys/%s/%s/thing/service/property/set",
148 getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); 153 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
149 IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO() 154 IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO()
150 .setProperties((Map<String, Object>) downstreamReqVO.getData()); 155 .setProperties((Map<String, Object>) downstreamReqVO.getData());
@@ -184,7 +189,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -184,7 +189,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
184 // TODO @super:【可优化】过滤掉不合法的属性 189 // TODO @super:【可优化】过滤掉不合法的属性
185 190
186 // 2. 发送请求 191 // 2. 发送请求
187 - String url = String.format( "sys/%s/%s/thing/service/property/get", 192 + String url = String.format("sys/%s/%s/thing/service/property/get",
188 getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); 193 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
189 IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() 194 IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO()
190 .setIdentifiers((List<String>) downstreamReqVO.getData()); 195 .setIdentifiers((List<String>) downstreamReqVO.getData());
@@ -214,14 +219,14 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -214,14 +219,14 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
214 * @param parentDevice 父设备 219 * @param parentDevice 父设备
215 * @return 下发消息 220 * @return 下发消息
216 */ 221 */
217 - @SuppressWarnings({"unchecked", "unused"}) 222 + @SuppressWarnings({ "unchecked", "unused" })
218 private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO, 223 private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO,
219 IotDeviceDO device, IotDeviceDO parentDevice) { 224 IotDeviceDO device, IotDeviceDO parentDevice) {
220 // 1. 参数转换,无需校验 225 // 1. 参数转换,无需校验
221 Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class); 226 Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class);
222 227
223 // 2. 发送请求 228 // 2. 发送请求
224 - String url = String.format( "sys/%s/%s/thing/service/config/set", 229 + String url = String.format("sys/%s/%s/thing/service/config/set",
225 getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); 230 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
226 IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() 231 IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO()
227 .setConfig(config); 232 .setConfig(config);
@@ -244,15 +249,53 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -244,15 +249,53 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
244 } 249 }
245 250
246 /** 251 /**
  252 + * 设备 OTA 升级
  253 + *
  254 + * @param downstreamReqVO 下行请求
  255 + * @param device 设备
  256 + * @param parentDevice 父设备
  257 + * @return 下发消息
  258 + */
  259 + private IotDeviceMessage otaUpgrade(IotDeviceDownstreamReqVO downstreamReqVO,
  260 + IotDeviceDO device, IotDeviceDO parentDevice) {
  261 + // 1. 参数校验
  262 + if (!(downstreamReqVO.getData() instanceof Map<?, ?> data)) {
  263 + throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
  264 + }
  265 +
  266 + // 2. 发送请求
  267 + String url = String.format("ota/%s/%s/upgrade",
  268 + getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
  269 + IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data);
  270 + CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
  271 +
  272 + // 3. 发送设备消息
  273 + IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
  274 + .setType(IotDeviceMessageTypeEnum.OTA.getType())
  275 + .setIdentifier(IotDeviceMessageIdentifierEnum.OTA_UPGRADE.getIdentifier())
  276 + .setData(downstreamReqVO.getData());
  277 + sendDeviceMessage(message, device, result.getCode());
  278 +
  279 + // 4. 如果不成功,抛出异常,提示用户
  280 + if (result.isError()) {
  281 + log.error("[otaUpgrade][设备({}) OTA 升级失败,请求参数:({}),响应结果:({})]",
  282 + device.getDeviceKey(), reqDTO, result);
  283 + throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg());
  284 + }
  285 + return message;
  286 + }
  287 +
  288 + /**
247 * 请求插件 289 * 请求插件
248 * 290 *
249 - * @param url URL  
250 - * @param reqDTO 请求参数,只需要设置子类的参数!  
251 - * @param device 设备 291 + * @param url URL
  292 + * @param reqDTO 请求参数,只需要设置子类的参数!
  293 + * @param device 设备
252 * @return 响应结果 294 * @return 响应结果
253 */ 295 */
254 - @SuppressWarnings({"unchecked", "HttpUrlsUsage"})  
255 - private CommonResult<Boolean> requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO, IotDeviceDO device) { 296 + @SuppressWarnings({ "unchecked", "HttpUrlsUsage" })
  297 + private CommonResult<Boolean> requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO,
  298 + IotDeviceDO device) {
256 // 获得设备对应的插件实例 299 // 获得设备对应的插件实例
257 IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey()); 300 IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey());
258 if (pluginInstance == null) { 301 if (pluginInstance == null) {
@@ -266,7 +309,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @@ -266,7 +309,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
266 ResponseEntity<CommonResult<Boolean>> responseEntity; 309 ResponseEntity<CommonResult<Boolean>> responseEntity;
267 try { 310 try {
268 responseEntity = restTemplate.postForEntity( 311 responseEntity = restTemplate.postForEntity(
269 - String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(), url), 312 + String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(),
  313 + url),
270 reqDTO, (Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class); 314 reqDTO, (Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
271 Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(), 315 Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(),
272 "HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode()); 316 "HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode());
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/IotDeviceDownstreamHandler.java
1 package cn.iocoder.yudao.module.iot.plugin.common.downstream; 1 package cn.iocoder.yudao.module.iot.plugin.common.downstream;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO;  
5 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;  
6 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;  
7 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; 4 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;
8 5
9 /** 6 /**
10 * IoT 设备下行处理器 7 * IoT 设备下行处理器
@@ -47,4 +44,12 @@ public interface IotDeviceDownstreamHandler { @@ -47,4 +44,12 @@ public interface IotDeviceDownstreamHandler {
47 */ 44 */
48 CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO); 45 CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO);
49 46
  47 + /**
  48 + * 升级设备 OTA
  49 + *
  50 + * @param upgradeReqDTO 升级设备 OTA 的请求
  51 + * @return 是否成功
  52 + */
  53 + CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO);
  54 +
50 } 55 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/IotDeviceDownstreamServer.java
1 package cn.iocoder.yudao.module.iot.plugin.common.downstream; 1 package cn.iocoder.yudao.module.iot.plugin.common.downstream;
2 2
3 import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties; 3 import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;
4 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceConfigSetVertxHandler;  
5 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertyGetVertxHandler;  
6 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertySetVertxHandler;  
7 -import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceServiceInvokeVertxHandler; 4 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.*;
8 import io.vertx.core.Vertx; 5 import io.vertx.core.Vertx;
9 import io.vertx.core.http.HttpServer; 6 import io.vertx.core.http.HttpServer;
10 import io.vertx.ext.web.Router; 7 import io.vertx.ext.web.Router;
@@ -39,6 +36,8 @@ public class IotDeviceDownstreamServer { @@ -39,6 +36,8 @@ public class IotDeviceDownstreamServer {
39 .handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler)); 36 .handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler));
40 router.post(IotDeviceConfigSetVertxHandler.PATH) 37 router.post(IotDeviceConfigSetVertxHandler.PATH)
41 .handler(new IotDeviceConfigSetVertxHandler(deviceDownstreamHandler)); 38 .handler(new IotDeviceConfigSetVertxHandler(deviceDownstreamHandler));
  39 + router.post(IotDeviceOtaUpgradeVertxHandler.PATH)
  40 + .handler(new IotDeviceOtaUpgradeVertxHandler(deviceDownstreamHandler));
42 // 创建 HttpServer 实例 41 // 创建 HttpServer 实例
43 this.server = vertx.createHttpServer().requestHandler(router); 42 this.server = vertx.createHttpServer().requestHandler(router);
44 } 43 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDeviceOtaUpgradeVertxHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO;
  5 +import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
  6 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
  7 +import io.vertx.core.Handler;
  8 +import io.vertx.ext.web.RoutingContext;
  9 +import lombok.RequiredArgsConstructor;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import io.vertx.core.json.JsonObject;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  14 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
  15 +
  16 +@Slf4j
  17 +@RequiredArgsConstructor
  18 +public class IotDeviceOtaUpgradeVertxHandler implements Handler<RoutingContext> {
  19 +
  20 + public static final String PATH = "/ota/:productKey/:deviceName/upgrade";
  21 +
  22 + private final IotDeviceDownstreamHandler deviceDownstreamHandler;
  23 +
  24 + @Override
  25 + public void handle(RoutingContext routingContext) {
  26 + // 1. 解析参数
  27 + IotDeviceOtaUpgradeReqDTO reqDTO;
  28 + try {
  29 + String productKey = routingContext.pathParam("productKey");
  30 + String deviceName = routingContext.pathParam("deviceName");
  31 + JsonObject body = routingContext.body().asJsonObject();
  32 + String requestId = body.getString("requestId");
  33 + Long firmwareId = body.getLong("firmwareId");
  34 + String version = body.getString("version");
  35 + String signMethod = body.getString("signMethod");
  36 + String fileSign = body.getString("fileSign");
  37 + Long fileSize = body.getLong("fileSize");
  38 + String fileUrl = body.getString("fileUrl");
  39 + String information = body.getString("information");
  40 + reqDTO = ((IotDeviceOtaUpgradeReqDTO) new IotDeviceOtaUpgradeReqDTO()
  41 + .setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
  42 + .setFirmwareId(firmwareId).setVersion(version)
  43 + .setSignMethod(signMethod).setFileSign(fileSign).setFileSize(fileSize).setFileUrl(fileUrl)
  44 + .setInformation(information);
  45 + } catch (Exception e) {
  46 + log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
  47 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
  48 + return;
  49 + }
  50 +
  51 + // 2. 调用处理器
  52 + try {
  53 + CommonResult<Boolean> result = deviceDownstreamHandler.upgradeDeviceOta(reqDTO);
  54 + IotPluginCommonUtils.writeJson(routingContext, result);
  55 + } catch (Exception e) {
  56 + log.error("[handle][请求参数({}) OTA 升级异常]", reqDTO, e);
  57 + IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
  58 + }
  59 + }
  60 +}
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/downstream/IotDeviceDownstreamHandlerImpl.java
1 package cn.iocoder.yudao.module.iot.plugin.http.downstream; 1 package cn.iocoder.yudao.module.iot.plugin.http.downstream;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO;  
5 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;  
6 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;  
7 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; 4 +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;
8 import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler; 5 import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
9 6
10 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED; 7 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
@@ -39,4 +36,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle @@ -39,4 +36,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
39 return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性"); 36 return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性");
40 } 37 }
41 38
  39 + @Override
  40 + public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {
  41 + return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性");
  42 + }
  43 +
42 } 44 }