Commit 0fb6f2b590c65ddc7159236b8f131fd2020966b8
1 parent
af1f993a
feat:【IoT 物联网】实现 OTA updateOtaRecordProgress
Showing
11 changed files
with
134 additions
and
9 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskRecordMapper.java
| @@ -67,6 +67,12 @@ public interface IotOtaTaskRecordMapper extends BaseMapperX<IotOtaTaskRecordDO> | @@ -67,6 +67,12 @@ public interface IotOtaTaskRecordMapper extends BaseMapperX<IotOtaTaskRecordDO> | ||
| 67 | .inIfPresent(IotOtaTaskRecordDO::getStatus, statuses)); | 67 | .inIfPresent(IotOtaTaskRecordDO::getStatus, statuses)); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | + default List<IotOtaTaskRecordDO> selectListByDeviceIdAndStatus(Long deviceId, Set<Integer> statuses) { | ||
| 71 | + return selectList(new LambdaQueryWrapperX<IotOtaTaskRecordDO>() | ||
| 72 | + .eqIfPresent(IotOtaTaskRecordDO::getDeviceId, deviceId) | ||
| 73 | + .inIfPresent(IotOtaTaskRecordDO::getStatus, statuses)); | ||
| 74 | + } | ||
| 75 | + | ||
| 70 | default List<IotOtaTaskRecordDO> selectListByStatus(Integer status) { | 76 | default List<IotOtaTaskRecordDO> selectListByStatus(Integer status) { |
| 71 | return selectList(IotOtaTaskRecordDO::getStatus, status); | 77 | return selectList(IotOtaTaskRecordDO::getStatus, status); |
| 72 | } | 78 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
| @@ -61,6 +61,7 @@ public interface ErrorCodeConstants { | @@ -61,6 +61,7 @@ public interface ErrorCodeConstants { | ||
| 61 | 61 | ||
| 62 | ErrorCode OTA_TASK_RECORD_NOT_EXISTS = new ErrorCode(1_050_008_200, "升级记录不存在"); | 62 | ErrorCode OTA_TASK_RECORD_NOT_EXISTS = new ErrorCode(1_050_008_200, "升级记录不存在"); |
| 63 | ErrorCode OTA_TASK_RECORD_CANCEL_FAIL_STATUS_ERROR = new ErrorCode(1_050_008_201, "取消 OTA 升级记录失败,原因:记录状态不是进行中"); | 63 | ErrorCode OTA_TASK_RECORD_CANCEL_FAIL_STATUS_ERROR = new ErrorCode(1_050_008_201, "取消 OTA 升级记录失败,原因:记录状态不是进行中"); |
| 64 | + ErrorCode OTA_TASK_RECORD_UPDATE_PROGRESS_FAIL_NO_EXISTS = new ErrorCode(1_050_008_202, "更新 OTA 升级记录进度失败,原因:该设备没有进行中的升级记录"); | ||
| 64 | 65 | ||
| 65 | // ========== IoT 数据流转规则 1-050-010-000 ========== | 66 | // ========== IoT 数据流转规则 1-050-010-000 ========== |
| 66 | ErrorCode DATA_RULE_NOT_EXISTS = new ErrorCode(1_050_010_000, "数据流转规则不存在"); | 67 | ErrorCode DATA_RULE_NOT_EXISTS = new ErrorCode(1_050_010_000, "数据流转规则不存在"); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaTaskRecordStatusEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.ota; | 1 | package cn.iocoder.yudao.module.iot.enums.ota; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | +import cn.hutool.core.util.ArrayUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.core.ArrayValuable; | 5 | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; |
| 6 | import lombok.Getter; | 7 | import lombok.Getter; |
| @@ -49,4 +50,8 @@ public enum IotOtaTaskRecordStatusEnum implements ArrayValuable<Integer> { | @@ -49,4 +50,8 @@ public enum IotOtaTaskRecordStatusEnum implements ArrayValuable<Integer> { | ||
| 49 | return ARRAYS; | 50 | return ARRAYS; |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 53 | + public static IotOtaTaskRecordStatusEnum of(Integer status) { | ||
| 54 | + return ArrayUtil.firstMatch(o -> o.getStatus().equals(status), values()); | ||
| 55 | + } | ||
| 56 | + | ||
| 52 | } | 57 | } |
| 53 | \ No newline at end of file | 58 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| @@ -263,4 +263,12 @@ public interface IotDeviceService { | @@ -263,4 +263,12 @@ public interface IotDeviceService { | ||
| 263 | return convertMap(getDeviceList(ids), IotDeviceDO::getId); | 263 | return convertMap(getDeviceList(ids), IotDeviceDO::getId); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | + /** | ||
| 267 | + * 更新设备固件版本 | ||
| 268 | + * | ||
| 269 | + * @param deviceId 设备编号 | ||
| 270 | + * @param firmwareId 固件编号 | ||
| 271 | + */ | ||
| 272 | + void updateDeviceFirmware(Long deviceId, Long firmwareId); | ||
| 273 | + | ||
| 266 | } | 274 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
| @@ -485,6 +485,19 @@ public class IotDeviceServiceImpl implements IotDeviceService { | @@ -485,6 +485,19 @@ public class IotDeviceServiceImpl implements IotDeviceService { | ||
| 485 | return deviceMapper.selectByIds(ids); | 485 | return deviceMapper.selectByIds(ids); |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | + @Override | ||
| 489 | + public void updateDeviceFirmware(Long deviceId, Long firmwareId) { | ||
| 490 | + // 1. 校验设备是否存在 | ||
| 491 | + IotDeviceDO device = validateDeviceExists(deviceId); | ||
| 492 | + | ||
| 493 | + // 2. 更新设备固件版本 | ||
| 494 | + IotDeviceDO updateObj = new IotDeviceDO().setId(deviceId).setFirmwareId(firmwareId); | ||
| 495 | + deviceMapper.updateById(updateObj); | ||
| 496 | + | ||
| 497 | + // 3. 清空对应缓存 | ||
| 498 | + deleteDeviceCache(device); | ||
| 499 | + } | ||
| 500 | + | ||
| 488 | private IotDeviceServiceImpl getSelf() { | 501 | private IotDeviceServiceImpl getSelf() { |
| 489 | return SpringUtil.getBean(getClass()); | 502 | return SpringUtil.getBean(getClass()); |
| 490 | } | 503 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java
| @@ -22,11 +22,13 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceMessageDO; | @@ -22,11 +22,13 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceMessageDO; | ||
| 22 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceMessageMapper; | 22 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceMessageMapper; |
| 23 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 23 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 24 | import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService; | 24 | import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService; |
| 25 | +import cn.iocoder.yudao.module.iot.service.ota.IotOtaTaskRecordService; | ||
| 25 | import com.baomidou.mybatisplus.core.metadata.IPage; | 26 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 26 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 27 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 27 | import com.google.common.base.Objects; | 28 | import com.google.common.base.Objects; |
| 28 | import jakarta.annotation.Resource; | 29 | import jakarta.annotation.Resource; |
| 29 | import lombok.extern.slf4j.Slf4j; | 30 | import lombok.extern.slf4j.Slf4j; |
| 31 | +import org.springframework.context.annotation.Lazy; | ||
| 30 | import org.springframework.scheduling.annotation.Async; | 32 | import org.springframework.scheduling.annotation.Async; |
| 31 | import org.springframework.stereotype.Service; | 33 | import org.springframework.stereotype.Service; |
| 32 | import org.springframework.validation.annotation.Validated; | 34 | import org.springframework.validation.annotation.Validated; |
| @@ -54,6 +56,9 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { | @@ -54,6 +56,9 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { | ||
| 54 | private IotDeviceService deviceService; | 56 | private IotDeviceService deviceService; |
| 55 | @Resource | 57 | @Resource |
| 56 | private IotDevicePropertyService devicePropertyService; | 58 | private IotDevicePropertyService devicePropertyService; |
| 59 | + @Resource | ||
| 60 | + @Lazy // 延迟加载,避免循环依赖 | ||
| 61 | + private IotOtaTaskRecordService otaTaskRecordService; | ||
| 57 | 62 | ||
| 58 | @Resource | 63 | @Resource |
| 59 | private IotDeviceMessageMapper deviceMessageMapper; | 64 | private IotDeviceMessageMapper deviceMessageMapper; |
| @@ -192,6 +197,12 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { | @@ -192,6 +197,12 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { | ||
| 192 | return null; | 197 | return null; |
| 193 | } | 198 | } |
| 194 | 199 | ||
| 200 | + // OTA 上报升级进度 | ||
| 201 | + if (Objects.equal(message.getMethod(), IotDeviceMessageMethodEnum.OTA_PROGRESS.getMethod())) { | ||
| 202 | + otaTaskRecordService.updateOtaRecordProgress(device, message); | ||
| 203 | + return null; | ||
| 204 | + } | ||
| 205 | + | ||
| 195 | // TODO @芋艿:这里可以按需,添加别的逻辑; | 206 | // TODO @芋艿:这里可以按需,添加别的逻辑; |
| 196 | return null; | 207 | return null; |
| 197 | } | 208 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareService.java
| @@ -7,12 +7,12 @@ import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwa | @@ -7,12 +7,12 @@ import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwa | ||
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; |
| 8 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 9 | 9 | ||
| 10 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 11 | - | ||
| 12 | import java.util.Collection; | 10 | import java.util.Collection; |
| 13 | import java.util.List; | 11 | import java.util.List; |
| 14 | import java.util.Map; | 12 | import java.util.Map; |
| 15 | 13 | ||
| 14 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 15 | + | ||
| 16 | /** | 16 | /** |
| 17 | * OTA 固件管理 Service 接口 | 17 | * OTA 固件管理 Service 接口 |
| 18 | * | 18 | * |
| @@ -44,6 +44,15 @@ public interface IotOtaFirmwareService { | @@ -44,6 +44,15 @@ public interface IotOtaFirmwareService { | ||
| 44 | IotOtaFirmwareDO getOtaFirmware(Long id); | 44 | IotOtaFirmwareDO getOtaFirmware(Long id); |
| 45 | 45 | ||
| 46 | /** | 46 | /** |
| 47 | + * 根据产品、版本号,获取 OTA 固件信息 | ||
| 48 | + * | ||
| 49 | + * @param productId 产品编号 | ||
| 50 | + * @param version 版本号 | ||
| 51 | + * @return OTA 固件信息 | ||
| 52 | + */ | ||
| 53 | + IotOtaFirmwareDO getOtaFirmwareByProductIdAndVersion(Long productId, String version); | ||
| 54 | + | ||
| 55 | + /** | ||
| 47 | * 获取 OTA 固件信息列表 | 56 | * 获取 OTA 固件信息列表 |
| 48 | * | 57 | * |
| 49 | * @param ids 固件编号集合 | 58 | * @param ids 固件编号集合 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareServiceImpl.java
| @@ -21,10 +21,8 @@ import java.io.ByteArrayInputStream; | @@ -21,10 +21,8 @@ import java.io.ByteArrayInputStream; | ||
| 21 | import java.util.Collection; | 21 | import java.util.Collection; |
| 22 | import java.util.Collections; | 22 | import java.util.Collections; |
| 23 | import java.util.List; | 23 | import java.util.List; |
| 24 | -import java.util.Map; | ||
| 25 | 24 | ||
| 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 25 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 27 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 28 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_NOT_EXISTS; | 26 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_NOT_EXISTS; |
| 29 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE; | 27 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE; |
| 30 | 28 | ||
| @@ -82,6 +80,11 @@ public class IotOtaFirmwareServiceImpl implements IotOtaFirmwareService { | @@ -82,6 +80,11 @@ public class IotOtaFirmwareServiceImpl implements IotOtaFirmwareService { | ||
| 82 | } | 80 | } |
| 83 | 81 | ||
| 84 | @Override | 82 | @Override |
| 83 | + public IotOtaFirmwareDO getOtaFirmwareByProductIdAndVersion(Long productId, String version) { | ||
| 84 | + return otaFirmwareMapper.selectByProductIdAndVersion(productId, version); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + @Override | ||
| 85 | public List<IotOtaFirmwareDO> getOtaFirmwareList(Collection<Long> ids) { | 88 | public List<IotOtaFirmwareDO> getOtaFirmwareList(Collection<Long> ids) { |
| 86 | if (ids == null || ids.isEmpty()) { | 89 | if (ids == null || ids.isEmpty()) { |
| 87 | return Collections.emptyList(); | 90 | return Collections.emptyList(); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordService.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.ota; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.ota; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO; |
| @@ -91,4 +92,12 @@ public interface IotOtaTaskRecordService { | @@ -91,4 +92,12 @@ public interface IotOtaTaskRecordService { | ||
| 91 | */ | 92 | */ |
| 92 | boolean pushOtaTaskRecord(IotOtaTaskRecordDO record, IotOtaFirmwareDO fireware, IotDeviceDO device); | 93 | boolean pushOtaTaskRecord(IotOtaTaskRecordDO record, IotOtaFirmwareDO fireware, IotDeviceDO device); |
| 93 | 94 | ||
| 95 | + /** | ||
| 96 | + * 更新 OTA 升级记录进度 | ||
| 97 | + * | ||
| 98 | + * @param device 设备信息 | ||
| 99 | + * @param message 设备消息 | ||
| 100 | + */ | ||
| 101 | + void updateOtaRecordProgress(IotDeviceDO device, IotDeviceMessage message); | ||
| 102 | + | ||
| 94 | } | 103 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordServiceImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.service.ota; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.service.ota; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.convert.Convert; | 4 | import cn.hutool.core.convert.Convert; |
| 5 | import cn.hutool.core.lang.Assert; | 5 | import cn.hutool.core.lang.Assert; |
| 6 | +import cn.hutool.core.map.MapUtil; | ||
| 6 | import cn.hutool.core.util.StrUtil; | 7 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 8 | import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; | 9 | import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; |
| @@ -17,14 +18,14 @@ import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageServic | @@ -17,14 +18,14 @@ import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageServic | ||
| 17 | import jakarta.annotation.Resource; | 18 | import jakarta.annotation.Resource; |
| 18 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
| 19 | import org.springframework.stereotype.Service; | 20 | import org.springframework.stereotype.Service; |
| 21 | +import org.springframework.transaction.annotation.Transactional; | ||
| 20 | import org.springframework.validation.annotation.Validated; | 22 | import org.springframework.validation.annotation.Validated; |
| 21 | 23 | ||
| 22 | import java.util.*; | 24 | import java.util.*; |
| 23 | 25 | ||
| 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 25 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 27 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 26 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_TASK_RECORD_NOT_EXISTS; | ||
| 27 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_TASK_RECORD_CANCEL_FAIL_STATUS_ERROR; | 28 | +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; |
| 28 | 29 | ||
| 29 | /** | 30 | /** |
| 30 | * OTA 升级任务记录 Service 实现类 | 31 | * OTA 升级任务记录 Service 实现类 |
| @@ -38,6 +39,8 @@ public class IotOtaTaskRecordServiceImpl implements IotOtaTaskRecordService { | @@ -38,6 +39,8 @@ public class IotOtaTaskRecordServiceImpl implements IotOtaTaskRecordService { | ||
| 38 | private IotOtaTaskRecordMapper otaTaskRecordMapper; | 39 | private IotOtaTaskRecordMapper otaTaskRecordMapper; |
| 39 | 40 | ||
| 40 | @Resource | 41 | @Resource |
| 42 | + private IotOtaFirmwareService otaFirmwareService; | ||
| 43 | + @Resource | ||
| 41 | private IotOtaTaskService otaTaskService; | 44 | private IotOtaTaskService otaTaskService; |
| 42 | @Resource | 45 | @Resource |
| 43 | private IotDeviceMessageService deviceMessageService; | 46 | private IotDeviceMessageService deviceMessageService; |
| @@ -158,6 +161,57 @@ public class IotOtaTaskRecordServiceImpl implements IotOtaTaskRecordService { | @@ -158,6 +161,57 @@ public class IotOtaTaskRecordServiceImpl implements IotOtaTaskRecordService { | ||
| 158 | return upgradeRecord; | 161 | return upgradeRecord; |
| 159 | } | 162 | } |
| 160 | 163 | ||
| 164 | + @Override | ||
| 165 | + @Transactional(rollbackFor = Exception.class) | ||
| 166 | + @SuppressWarnings("unchecked") | ||
| 167 | + public void updateOtaRecordProgress(IotDeviceDO device, IotDeviceMessage message) { | ||
| 168 | + // 1.1 参数解析 | ||
| 169 | + Map<String, Object> params = (Map<String, Object>) message.getParams(); | ||
| 170 | + String version = MapUtil.getStr(params, "version"); | ||
| 171 | + Assert.notBlank(version, "version 不能为空"); | ||
| 172 | + Integer status = MapUtil.getInt(params, "status"); | ||
| 173 | + Assert.notNull(status, "status 不能为空"); | ||
| 174 | + Assert.notNull(IotOtaTaskRecordStatusEnum.of(status), "status 状态不正确"); | ||
| 175 | + String description = MapUtil.getStr(params, "description"); | ||
| 176 | + Integer progress = MapUtil.getInt(params, "progress"); | ||
| 177 | + Assert.notNull(progress, "progress 不能为空"); | ||
| 178 | + Assert.isTrue(progress >= 0 && progress <= 100, "progress 必须在 0-100 之间"); | ||
| 179 | + // 1.2 查询 OTA 升级记录 | ||
| 180 | + List<IotOtaTaskRecordDO> records = otaTaskRecordMapper.selectListByDeviceIdAndStatus( | ||
| 181 | + device.getId(), IotOtaTaskRecordStatusEnum.IN_PROCESS_STATUSES); | ||
| 182 | + if (CollUtil.isEmpty(records)) { | ||
| 183 | + throw exception(OTA_TASK_RECORD_UPDATE_PROGRESS_FAIL_NO_EXISTS); | ||
| 184 | + } | ||
| 185 | + if (records.size() > 1) { | ||
| 186 | + log.warn("[updateOtaRecordProgress][message({}) 对应升级记录过多({})]", message, records); | ||
| 187 | + } | ||
| 188 | + IotOtaTaskRecordDO record = CollUtil.getFirst(records); | ||
| 189 | + // 1.3 查询 OTA 固件 | ||
| 190 | + IotOtaFirmwareDO firmware = otaFirmwareService.getOtaFirmwareByProductIdAndVersion( | ||
| 191 | + device.getProductId(), version); | ||
| 192 | + if (firmware == null) { | ||
| 193 | + throw exception(OTA_FIRMWARE_NOT_EXISTS); | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + // 2. 更新 OTA 升级记录状态 | ||
| 197 | + int updateCount = otaTaskRecordMapper.updateByIdAndStatus( | ||
| 198 | + record.getId(), IotOtaTaskRecordStatusEnum.IN_PROCESS_STATUSES, | ||
| 199 | + IotOtaTaskRecordDO.builder().status(status).description(description).progress(progress).build()); | ||
| 200 | + if (updateCount == 0) { | ||
| 201 | + throw exception(OTA_TASK_RECORD_UPDATE_PROGRESS_FAIL_NO_EXISTS); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + // 3. 如果升级成功,则更新设备固件版本 | ||
| 205 | + if (IotOtaTaskRecordStatusEnum.SUCCESS.getStatus().equals(status)) { | ||
| 206 | + deviceService.updateDeviceFirmware(device.getId(), firmware.getId()); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + // 4. 如果状态是“已结束”(非进行中),则更新任务状态 | ||
| 210 | + if (!IotOtaTaskRecordStatusEnum.IN_PROCESS_STATUSES.contains(status)) { | ||
| 211 | + checkAndUpdateOtaTaskStatus(record.getTaskId()); | ||
| 212 | + } | ||
| 213 | + } | ||
| 214 | + | ||
| 161 | /** | 215 | /** |
| 162 | * 检查并更新任务状态 | 216 | * 检查并更新任务状态 |
| 163 | * 如果任务下没有进行中的记录,则将任务状态更新为已结束 | 217 | * 如果任务下没有进行中的记录,则将任务状态更新为已结束 |
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceMessageMethodEnum.java
| @@ -30,10 +30,12 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | @@ -30,10 +30,12 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | ||
| 30 | PROPERTY_SET("thing.property.set", "属性设置", false), | 30 | PROPERTY_SET("thing.property.set", "属性设置", false), |
| 31 | 31 | ||
| 32 | // ========== 设备事件 ========== | 32 | // ========== 设备事件 ========== |
| 33 | + // 可参考:https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services | ||
| 33 | 34 | ||
| 34 | EVENT_POST("thing.event.post", "事件上报", true), | 35 | EVENT_POST("thing.event.post", "事件上报", true), |
| 35 | 36 | ||
| 36 | // ========== 设备服务调用 ========== | 37 | // ========== 设备服务调用 ========== |
| 38 | + // 可参考:https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services | ||
| 37 | 39 | ||
| 38 | SERVICE_INVOKE("thing.service.invoke", "服务调用", false), | 40 | SERVICE_INVOKE("thing.service.invoke", "服务调用", false), |
| 39 | 41 | ||
| @@ -43,9 +45,10 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | @@ -43,9 +45,10 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | ||
| 43 | CONFIG_PUSH("thing.config.push", "配置推送", true), | 45 | CONFIG_PUSH("thing.config.push", "配置推送", true), |
| 44 | 46 | ||
| 45 | // ========== OTA 固件 ========== | 47 | // ========== OTA 固件 ========== |
| 48 | + // 可参考:https://help.aliyun.com/zh/iot/user-guide/perform-ota-updates | ||
| 46 | 49 | ||
| 47 | - OTA_UPGRADE("thing.ota.upgrade", "OTA 推送固定信息", false), | ||
| 48 | - OTA_PROGRESS("thing.ota.progress", "OTA 上报升级进度", true), | 50 | + OTA_UPGRADE("thing.ota.upgrade", "OTA 固定信息推送", false), |
| 51 | + OTA_PROGRESS("thing.ota.progress", "OTA 升级进度上报", true), | ||
| 49 | ; | 52 | ; |
| 50 | 53 | ||
| 51 | public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageMethodEnum::getMethod) | 54 | public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageMethodEnum::getMethod) |
| @@ -54,7 +57,10 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | @@ -54,7 +57,10 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | ||
| 54 | /** | 57 | /** |
| 55 | * 不进行 reply 回复的方法集合 | 58 | * 不进行 reply 回复的方法集合 |
| 56 | */ | 59 | */ |
| 57 | - public static final Set<String> REPLY_DISABLED = Set.of(STATE_UPDATE.getMethod()); | 60 | + public static final Set<String> REPLY_DISABLED = Set.of( |
| 61 | + STATE_UPDATE.getMethod(), | ||
| 62 | + OTA_PROGRESS.getMethod() // 参考阿里云,OTA 升级进度上报,不进行回复 | ||
| 63 | + ); | ||
| 58 | 64 | ||
| 59 | private final String method; | 65 | private final String method; |
| 60 | 66 |