【功能新增】IoT:OTA 升级的下行消息的实现
This commit is contained in:
parent
795e06bc8f
commit
4919439b96
|
@ -0,0 +1,66 @@
|
||||||
|
package cn.iocoder.yudao.module.iot.api.device.dto.control.downstream;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IoT 设备【OTA】升级下发 Request DTO(更新固件消息)
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IotDeviceOtaUpgradeReqDTO extends IotDeviceDownstreamAbstractReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件编号
|
||||||
|
*/
|
||||||
|
private Long firmwareId;
|
||||||
|
/**
|
||||||
|
* 固件版本
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名方式
|
||||||
|
*
|
||||||
|
* 例如说:MD5、SHA256
|
||||||
|
*/
|
||||||
|
private String signMethod;
|
||||||
|
/**
|
||||||
|
* 固件文件签名
|
||||||
|
*/
|
||||||
|
private String fileSign;
|
||||||
|
/**
|
||||||
|
* 固件文件大小
|
||||||
|
*/
|
||||||
|
private Long fileSize;
|
||||||
|
/**
|
||||||
|
* 固件文件 URL
|
||||||
|
*/
|
||||||
|
private String fileUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义信息,建议使用 JSON 格式
|
||||||
|
*/
|
||||||
|
private String information;
|
||||||
|
|
||||||
|
public static IotDeviceOtaUpgradeReqDTO build(Map<?, ?> map) {
|
||||||
|
return new IotDeviceOtaUpgradeReqDTO()
|
||||||
|
.setFirmwareId(MapUtil.getLong(map, "firmwareId")).setVersion((String) map.get("version"))
|
||||||
|
.setSignMethod((String) map.get("signMethod")).setFileSign((String) map.get("fileSign"))
|
||||||
|
.setFileSize(MapUtil.getLong(map, "fileSize")).setFileUrl((String) map.get("fileUrl"))
|
||||||
|
.setInformation((String) map.get("information"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<?, ?> build(IotDeviceOtaUpgradeReqDTO dto) {
|
||||||
|
return MapUtil.builder()
|
||||||
|
.put("firmwareId", dto.getFirmwareId()).put("version", dto.getVersion())
|
||||||
|
.put("signMethod", dto.getSignMethod()).put("fileSign", dto.getFileSign())
|
||||||
|
.put("fileSize", dto.getFileSize()).put("fileUrl", dto.getFileUrl())
|
||||||
|
.put("information", dto.getInformation())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/progress
|
||||||
|
/**
|
||||||
|
* IoT 设备【OTA】升级进度 Request DTO(上报更新固件进度)
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IotDeviceOtaProgressReqDTO extends IotDeviceUpstreamAbstractReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件编号
|
||||||
|
*/
|
||||||
|
private Long firmwareId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级状态
|
||||||
|
*
|
||||||
|
* 枚举 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
/**
|
||||||
|
* 升级进度,百分比
|
||||||
|
*/
|
||||||
|
private Integer progress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级进度描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||||
|
|
||||||
|
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/pull
|
||||||
|
/**
|
||||||
|
* IoT 设备【OTA】升级下拉 Request DTO(拉取固件更新)
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class IotDeviceOtaPullReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件编号
|
||||||
|
*/
|
||||||
|
private Long firmwareId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件版本
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
|
||||||
|
|
||||||
|
// TODO @芋艿:待实现:/ota/${productKey}/${deviceName}/report
|
||||||
|
/**
|
||||||
|
* IoT 设备【OTA】上报 Request DTO(上报固件版本)
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class IotDeviceOtaReportReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件编号
|
||||||
|
*/
|
||||||
|
private Long firmwareId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件版本
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,12 @@ public enum IotDeviceMessageIdentifierEnum {
|
||||||
CONFIG_SET("set"), // 下行
|
CONFIG_SET("set"), // 下行
|
||||||
|
|
||||||
SERVICE_INVOKE("${identifier}"), // 下行
|
SERVICE_INVOKE("${identifier}"), // 下行
|
||||||
SERVICE_REPLY_SUFFIX("_reply"); // 芋艿:TODO 芋艿:【讨论】上行 or 下行
|
SERVICE_REPLY_SUFFIX("_reply"), // 芋艿:TODO 芋艿:【讨论】上行 or 下行
|
||||||
|
|
||||||
|
OTA_UPGRADE("upgrade"), // 下行
|
||||||
|
OTA_PULL("pull"), // 上行
|
||||||
|
OTA_PROGRESS("progress"), // 上行
|
||||||
|
OTA_REPORT("report"),; // 上行
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标志符
|
* 标志符
|
||||||
|
|
|
@ -17,7 +17,8 @@ public enum IotDeviceMessageTypeEnum implements ArrayValuable<String> {
|
||||||
PROPERTY("property"), // 设备属性
|
PROPERTY("property"), // 设备属性
|
||||||
EVENT("event"), // 设备事件
|
EVENT("event"), // 设备事件
|
||||||
SERVICE("service"), // 设备服务
|
SERVICE("service"), // 设备服务
|
||||||
CONFIG("config"); // 设备配置
|
CONFIG("config"), // 设备配置
|
||||||
|
OTA("ota"),; // 设备 OTA
|
||||||
|
|
||||||
public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new);
|
public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new);
|
||||||
|
|
||||||
|
|
|
@ -51,4 +51,25 @@ Authorization: Bearer {{token}}
|
||||||
"id": 25,
|
"id": 25,
|
||||||
"type": "config",
|
"type": "config",
|
||||||
"identifier": "set"
|
"identifier": "set"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 请求 /iot/device/downstream 接口(OTA 升级) => 成功
|
||||||
|
POST {{baseUrl}}/iot/device/downstream
|
||||||
|
Content-Type: application/json
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 25,
|
||||||
|
"type": "ota",
|
||||||
|
"identifier": "upgrade",
|
||||||
|
"data": {
|
||||||
|
"firmwareId": 1,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"signMethod": "MD5",
|
||||||
|
"fileSign": "d41d8cd98f00b204e9800998ecf8427e",
|
||||||
|
"fileSize": 1024,
|
||||||
|
"fileUrl": "http://example.com/firmware.bin",
|
||||||
|
"information": "{\"desc\":\"升级到最新版本\"}"
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -80,11 +80,15 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
}
|
}
|
||||||
// 配置下发
|
// 配置下发
|
||||||
if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType())
|
if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType())
|
||||||
&& Objects.equals(downstreamReqVO.getIdentifier(), IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) {
|
&& Objects.equals(downstreamReqVO.getIdentifier(),
|
||||||
|
IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) {
|
||||||
return setDeviceConfig(downstreamReqVO, device, parentDevice);
|
return setDeviceConfig(downstreamReqVO, device, parentDevice);
|
||||||
}
|
}
|
||||||
// TODO 芋艿:ota 升级
|
// OTA 升级
|
||||||
return null;
|
if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.OTA.getType())) {
|
||||||
|
return otaUpgrade(downstreamReqVO, device, parentDevice);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("不支持的下行消息类型:" + downstreamReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +101,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO,
|
private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO,
|
||||||
IotDeviceDO device, IotDeviceDO parentDevice) {
|
IotDeviceDO device, IotDeviceDO parentDevice) {
|
||||||
// 1. 参数校验
|
// 1. 参数校验
|
||||||
if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) {
|
if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) {
|
||||||
throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
|
throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
|
||||||
|
@ -105,9 +109,10 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
// TODO @super:【可优化】过滤掉不合法的服务
|
// TODO @super:【可优化】过滤掉不合法的服务
|
||||||
|
|
||||||
// 2. 发送请求
|
// 2. 发送请求
|
||||||
String url = String.format( "sys/%s/%s/thing/service/%s",
|
String url = String.format("sys/%s/%s/thing/service/%s",
|
||||||
getProductKey(device, parentDevice), getDeviceName(device, parentDevice), downstreamReqVO.getIdentifier());
|
getProductKey(device, parentDevice), getDeviceName(device, parentDevice),
|
||||||
IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO()
|
downstreamReqVO.getIdentifier());
|
||||||
|
IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO()
|
||||||
.setParams((Map<String, Object>) downstreamReqVO.getData());
|
.setParams((Map<String, Object>) downstreamReqVO.getData());
|
||||||
CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
|
CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
|
||||||
|
|
||||||
|
@ -144,7 +149,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
// TODO @super:【可优化】过滤掉不合法的属性
|
// TODO @super:【可优化】过滤掉不合法的属性
|
||||||
|
|
||||||
// 2. 发送请求
|
// 2. 发送请求
|
||||||
String url = String.format( "sys/%s/%s/thing/service/property/set",
|
String url = String.format("sys/%s/%s/thing/service/property/set",
|
||||||
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
||||||
IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO()
|
IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO()
|
||||||
.setProperties((Map<String, Object>) downstreamReqVO.getData());
|
.setProperties((Map<String, Object>) downstreamReqVO.getData());
|
||||||
|
@ -184,7 +189,7 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
// TODO @super:【可优化】过滤掉不合法的属性
|
// TODO @super:【可优化】过滤掉不合法的属性
|
||||||
|
|
||||||
// 2. 发送请求
|
// 2. 发送请求
|
||||||
String url = String.format( "sys/%s/%s/thing/service/property/get",
|
String url = String.format("sys/%s/%s/thing/service/property/get",
|
||||||
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
||||||
IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO()
|
IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO()
|
||||||
.setIdentifiers((List<String>) downstreamReqVO.getData());
|
.setIdentifiers((List<String>) downstreamReqVO.getData());
|
||||||
|
@ -214,14 +219,14 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
* @param parentDevice 父设备
|
* @param parentDevice 父设备
|
||||||
* @return 下发消息
|
* @return 下发消息
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "unused"})
|
@SuppressWarnings({ "unchecked", "unused" })
|
||||||
private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO,
|
private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO,
|
||||||
IotDeviceDO device, IotDeviceDO parentDevice) {
|
IotDeviceDO device, IotDeviceDO parentDevice) {
|
||||||
// 1. 参数转换,无需校验
|
// 1. 参数转换,无需校验
|
||||||
Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class);
|
Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class);
|
||||||
|
|
||||||
// 2. 发送请求
|
// 2. 发送请求
|
||||||
String url = String.format( "sys/%s/%s/thing/service/config/set",
|
String url = String.format("sys/%s/%s/thing/service/config/set",
|
||||||
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
||||||
IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO()
|
IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO()
|
||||||
.setConfig(config);
|
.setConfig(config);
|
||||||
|
@ -243,16 +248,54 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备 OTA 升级
|
||||||
|
*
|
||||||
|
* @param downstreamReqVO 下行请求
|
||||||
|
* @param device 设备
|
||||||
|
* @param parentDevice 父设备
|
||||||
|
* @return 下发消息
|
||||||
|
*/
|
||||||
|
private IotDeviceMessage otaUpgrade(IotDeviceDownstreamReqVO downstreamReqVO,
|
||||||
|
IotDeviceDO device, IotDeviceDO parentDevice) {
|
||||||
|
// 1. 参数校验
|
||||||
|
if (!(downstreamReqVO.getData() instanceof Map<?, ?> data)) {
|
||||||
|
throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 发送请求
|
||||||
|
String url = String.format("ota/%s/%s/upgrade",
|
||||||
|
getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
|
||||||
|
IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data);
|
||||||
|
CommonResult<Boolean> result = requestPlugin(url, reqDTO, device);
|
||||||
|
|
||||||
|
// 3. 发送设备消息
|
||||||
|
IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
|
||||||
|
.setType(IotDeviceMessageTypeEnum.OTA.getType())
|
||||||
|
.setIdentifier(IotDeviceMessageIdentifierEnum.OTA_UPGRADE.getIdentifier())
|
||||||
|
.setData(downstreamReqVO.getData());
|
||||||
|
sendDeviceMessage(message, device, result.getCode());
|
||||||
|
|
||||||
|
// 4. 如果不成功,抛出异常,提示用户
|
||||||
|
if (result.isError()) {
|
||||||
|
log.error("[otaUpgrade][设备({}) OTA 升级失败,请求参数:({}),响应结果:({})]",
|
||||||
|
device.getDeviceKey(), reqDTO, result);
|
||||||
|
throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg());
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求插件
|
* 请求插件
|
||||||
*
|
*
|
||||||
* @param url URL
|
* @param url URL
|
||||||
* @param reqDTO 请求参数,只需要设置子类的参数!
|
* @param reqDTO 请求参数,只需要设置子类的参数!
|
||||||
* @param device 设备
|
* @param device 设备
|
||||||
* @return 响应结果
|
* @return 响应结果
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "HttpUrlsUsage"})
|
@SuppressWarnings({ "unchecked", "HttpUrlsUsage" })
|
||||||
private CommonResult<Boolean> requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO, IotDeviceDO device) {
|
private CommonResult<Boolean> requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO,
|
||||||
|
IotDeviceDO device) {
|
||||||
// 获得设备对应的插件实例
|
// 获得设备对应的插件实例
|
||||||
IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey());
|
IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey());
|
||||||
if (pluginInstance == null) {
|
if (pluginInstance == null) {
|
||||||
|
@ -266,7 +309,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
|
||||||
ResponseEntity<CommonResult<Boolean>> responseEntity;
|
ResponseEntity<CommonResult<Boolean>> responseEntity;
|
||||||
try {
|
try {
|
||||||
responseEntity = restTemplate.postForEntity(
|
responseEntity = restTemplate.postForEntity(
|
||||||
String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(), url),
|
String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(),
|
||||||
|
url),
|
||||||
reqDTO, (Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
|
reqDTO, (Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class);
|
||||||
Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(),
|
Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(),
|
||||||
"HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode());
|
"HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode());
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO;
|
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IoT 设备下行处理器
|
* IoT 设备下行处理器
|
||||||
|
@ -47,4 +44,12 @@ public interface IotDeviceDownstreamHandler {
|
||||||
*/
|
*/
|
||||||
CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO);
|
CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级设备 OTA
|
||||||
|
*
|
||||||
|
* @param upgradeReqDTO 升级设备 OTA 的请求
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
package cn.iocoder.yudao.module.iot.plugin.common.downstream;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;
|
import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties;
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceConfigSetVertxHandler;
|
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.*;
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertyGetVertxHandler;
|
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDevicePropertySetVertxHandler;
|
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.router.IotDeviceServiceInvokeVertxHandler;
|
|
||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.core.http.HttpServer;
|
import io.vertx.core.http.HttpServer;
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
|
@ -39,6 +36,8 @@ public class IotDeviceDownstreamServer {
|
||||||
.handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler));
|
.handler(new IotDevicePropertyGetVertxHandler(deviceDownstreamHandler));
|
||||||
router.post(IotDeviceConfigSetVertxHandler.PATH)
|
router.post(IotDeviceConfigSetVertxHandler.PATH)
|
||||||
.handler(new IotDeviceConfigSetVertxHandler(deviceDownstreamHandler));
|
.handler(new IotDeviceConfigSetVertxHandler(deviceDownstreamHandler));
|
||||||
|
router.post(IotDeviceOtaUpgradeVertxHandler.PATH)
|
||||||
|
.handler(new IotDeviceOtaUpgradeVertxHandler(deviceDownstreamHandler));
|
||||||
// 创建 HttpServer 实例
|
// 创建 HttpServer 实例
|
||||||
this.server = vertx.createHttpServer().requestHandler(router);
|
this.server = vertx.createHttpServer().requestHandler(router);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.yudao.module.iot.plugin.common.downstream.router;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||||
|
import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
|
||||||
|
import io.vertx.core.Handler;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IotDeviceOtaUpgradeVertxHandler implements Handler<RoutingContext> {
|
||||||
|
|
||||||
|
public static final String PATH = "/ota/:productKey/:deviceName/upgrade";
|
||||||
|
|
||||||
|
private final IotDeviceDownstreamHandler deviceDownstreamHandler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(RoutingContext routingContext) {
|
||||||
|
// 1. 解析参数
|
||||||
|
IotDeviceOtaUpgradeReqDTO reqDTO;
|
||||||
|
try {
|
||||||
|
String productKey = routingContext.pathParam("productKey");
|
||||||
|
String deviceName = routingContext.pathParam("deviceName");
|
||||||
|
JsonObject body = routingContext.body().asJsonObject();
|
||||||
|
String requestId = body.getString("requestId");
|
||||||
|
Long firmwareId = body.getLong("firmwareId");
|
||||||
|
String version = body.getString("version");
|
||||||
|
String signMethod = body.getString("signMethod");
|
||||||
|
String fileSign = body.getString("fileSign");
|
||||||
|
Long fileSize = body.getLong("fileSize");
|
||||||
|
String fileUrl = body.getString("fileUrl");
|
||||||
|
String information = body.getString("information");
|
||||||
|
reqDTO = ((IotDeviceOtaUpgradeReqDTO) new IotDeviceOtaUpgradeReqDTO()
|
||||||
|
.setRequestId(requestId).setProductKey(productKey).setDeviceName(deviceName))
|
||||||
|
.setFirmwareId(firmwareId).setVersion(version)
|
||||||
|
.setSignMethod(signMethod).setFileSign(fileSign).setFileSize(fileSize).setFileUrl(fileUrl)
|
||||||
|
.setInformation(information);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[handle][路径参数({}) 解析参数失败]", routingContext.pathParams(), e);
|
||||||
|
IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(BAD_REQUEST));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用处理器
|
||||||
|
try {
|
||||||
|
CommonResult<Boolean> result = deviceDownstreamHandler.upgradeDeviceOta(reqDTO);
|
||||||
|
IotPluginCommonUtils.writeJson(routingContext, result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[handle][请求参数({}) OTA 升级异常]", reqDTO, e);
|
||||||
|
IotPluginCommonUtils.writeJson(routingContext, CommonResult.error(INTERNAL_SERVER_ERROR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.iot.plugin.http.downstream;
|
package cn.iocoder.yudao.module.iot.plugin.http.downstream;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO;
|
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertySetReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
|
||||||
|
@ -39,4 +36,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性");
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {
|
||||||
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(), "HTTP 不支持设置设备属性");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue