Commit 2f1598a5daf6320a9096ca92d51d739f44864508

Authored by YunaiV
1 parent 5110948d

【代码优化】IoT:重构设备 upstream 为 message,包括上行 + 下行

Showing 12 changed files with 147 additions and 59 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java
... ... @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceEventReportReqDTO;
5 5 import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
6 6 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceStateUpdateReqDTO;
7   -import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
  7 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceUpstreamService;
8 8 import org.springframework.validation.annotation.Validated;
9 9 import org.springframework.web.bind.annotation.RestController;
10 10  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
... ... @@ -7,8 +7,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
  10 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceSimulationUpstreamReqVO;
10 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
11 12 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
  13 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceDownstreamService;
  14 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceUpstreamService;
12 15 import io.swagger.v3.oas.annotations.Operation;
13 16 import io.swagger.v3.oas.annotations.Parameter;
14 17 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -37,6 +40,10 @@ public class IotDeviceController {
37 40  
38 41 @Resource
39 42 private IotDeviceService deviceService;
  43 + @Resource
  44 + private IotDeviceUpstreamService deviceUpstreamService;
  45 + @Resource
  46 + private IotDeviceDownstreamService deviceDownstreamService;
40 47  
41 48 @PostMapping("/create")
42 49 @Operation(summary = "创建设备")
... ... @@ -151,11 +158,21 @@ public class IotDeviceController {
151 158 ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list);
152 159 }
153 160  
154   - @PostMapping("/simulation-report")
155   - @Operation(summary = "模拟设备上报")
156   - @PreAuthorize("@ss.hasPermission('iot:device:simulation-report')")
157   - public CommonResult<Boolean> simulationReportDevice(@Valid @RequestBody IotDeviceSimulationReportReqVO simulatorReqVO) {
158   - deviceService.simulationReportDevice(simulatorReqVO);
  161 + @PostMapping("/simulation-upstream")
  162 + @Operation(summary = "模拟设备上行")
  163 + @PreAuthorize("@ss.hasPermission('iot:device:simulation')")
  164 + public CommonResult<Boolean> simulationDeviceUpstream(
  165 + @Valid @RequestBody IotDeviceSimulationUpstreamReqVO upstreamReqVO) {
  166 + deviceUpstreamService.simulationDeviceUpstream(upstreamReqVO);
  167 + return success(true);
  168 + }
  169 +
  170 + @PostMapping("/simulation-downstream")
  171 + @Operation(summary = "模拟设备下行")
  172 + @PreAuthorize("@ss.hasPermission('iot:device:simulation')")
  173 + public CommonResult<Boolean> simulationDownstreamDevice(
  174 + @Valid @RequestBody IotDeviceSimulationUpstreamReqVO downstreamReqVO) {
  175 + deviceDownstreamService.simulationDeviceDownstream(downstreamReqVO);
159 176 return success(true);
160 177 }
161 178  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/message/IotDeviceSimulationDownstreamReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import lombok.Data;
  9 +
  10 +@Schema(description = "管理后台 - IoT 模拟设备下行 Request VO") // 服务调用、属性设置、属性获取等
  11 +@Data
  12 +public class IotDeviceSimulationDownstreamReqVO {
  13 +
  14 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
  15 + @NotNull(message = "设备编号不能为空")
  16 + private Long id;
  17 +
  18 + @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property")
  19 + @NotEmpty(message = "消息类型不能为空")
  20 + @InEnum(IotDeviceMessageTypeEnum.class)
  21 + private String type;
  22 +
  23 + @Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "report")
  24 + @NotEmpty(message = "标识符不能为空")
  25 + private String identifier; // 参见 IotDeviceMessageIdentifierEnum 枚举类
  26 +
  27 + @Schema(description = "请求参数", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private Object data; // 例如说:服务调用的 params、属性设置的 properties
  29 +
  30 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceSimulationReportReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/message/IotDeviceSimulationUpstreamReqVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.message;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 4 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
... ... @@ -7,9 +7,9 @@ import jakarta.validation.constraints.NotEmpty;
7 7 import jakarta.validation.constraints.NotNull;
8 8 import lombok.Data;
9 9  
10   -@Schema(description = "管理后台 - IoT 模拟设备上报 Request VO") // 属性上报、事件上报、状态变更等
  10 +@Schema(description = "管理后台 - IoT 模拟设备上行 Request VO") // 属性上报、事件上报、状态变更等
11 11 @Data
12   -public class IotDeviceSimulationReportReqVO {
  12 +public class IotDeviceSimulationUpstreamReqVO {
13 13  
14 14 @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
15 15 @NotNull(message = "设备编号不能为空")
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/device/IotDeviceOfflineCheckJob.java
... ... @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
10 10 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
11 11 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
12 12 import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
13   -import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
  13 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceUpstreamService;
14 14 import jakarta.annotation.Resource;
15 15 import org.springframework.stereotype.Component;
16 16  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceOnlineMessageConsumer.java
... ... @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
9 9 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
10 10 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
11 11 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
12   -import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
  12 +import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceUpstreamService;
13 13 import jakarta.annotation.Resource;
14 14 import lombok.extern.slf4j.Slf4j;
15 15 import org.springframework.context.event.EventListener;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
... ... @@ -144,11 +144,4 @@ public interface IotDeviceService {
144 144 */
145 145 IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport);
146 146  
147   - /**
148   - * 模拟设备上报
149   - *
150   - * @param reportReqVO 上报信息
151   - */
152   - void simulationReportDevice(IotDeviceSimulationReportReqVO reportReqVO);
153   -
154 147 }
155 148 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
... ... @@ -10,18 +10,14 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
10 10 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
11 11 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
12 12 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
13   -import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
14   -import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceStateUpdateReqDTO;
15 13 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
16 14 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
17 15 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO;
18 16 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
19 17 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
20 18 import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
21   -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
22 19 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
23 20 import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
24   -import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
25 21 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
26 22 import jakarta.annotation.Resource;
27 23 import jakarta.validation.ConstraintViolationException;
... ... @@ -59,9 +55,6 @@ public class IotDeviceServiceImpl implements IotDeviceService {
59 55 @Resource
60 56 @Lazy // 延迟加载,解决循环依赖
61 57 private IotDeviceGroupService deviceGroupService;
62   - @Resource
63   - @Lazy // 延迟加载,解决循环依赖
64   - private IotDeviceUpstreamService deviceUpstreamService;
65 58  
66 59 @Override
67 60 public Long createDevice(IotDeviceSaveReqVO createReqVO) {
... ... @@ -395,38 +388,6 @@ public class IotDeviceServiceImpl implements IotDeviceService {
395 388 return respVO;
396 389 }
397 390  
398   - // TODO @芋艿:要不改成 simulationUpstream,原因:里面不只有上报,还有更新状态,那么 upstream 更适合
399   - @Override
400   - @SuppressWarnings("unchecked")
401   - public void simulationReportDevice(IotDeviceSimulationReportReqVO reportReqVO) {
402   - // 1. 校验存在
403   - IotDeviceDO device = validateDeviceExists(reportReqVO.getId());
404   -
405   - // 2.1 情况一:属性上报
406   - String requestId = IdUtil.fastSimpleUUID();
407   - if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) {
408   - deviceUpstreamService.reportDeviceProperty(((IotDevicePropertyReportReqDTO)
409   - new IotDevicePropertyReportReqDTO().setRequestId(requestId).setReportTime(LocalDateTime.now())
410   - .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()))
411   - .setProperties((Map<String, Object>) reportReqVO.getData()));
412   - return;
413   - }
414   - // 2.2 情况二:事件上报
415   - if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.EVENT.getType())) {
416   - // TODO 芋艿:待实现
417   - return;
418   - }
419   - // 2.3 情况三:状态变更
420   - if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) {
421   - deviceUpstreamService.updateDeviceState(((IotDeviceStateUpdateReqDTO)
422   - new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID()).setReportTime(LocalDateTime.now())
423   - .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()))
424   - .setState((Integer) reportReqVO.getData()));
425   - return;
426   - }
427   - throw new IllegalArgumentException("未知的类型:" + reportReqVO.getType());
428   - }
429   -
430 391 private void deleteDeviceCache(IotDeviceDO device) {
431 392 // 保证在 @CacheEvict 之前,忽略租户
432 393 TenantUtils.executeIgnore(() -> getSelf().deleteDeviceCache0(device));
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceDownstreamService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.device.message;
  2 +
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceSimulationUpstreamReqVO;
  4 +import jakarta.validation.Valid;
  5 +
  6 +/**
  7 + * 设备下行 Service 接口
  8 + *
  9 + * 目的:服务端 -> 插件 -> 设备
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +public interface IotDeviceDownstreamService {
  14 +
  15 + /**
  16 + * 模拟设备下行
  17 + *
  18 + * @param downstreamReqVO 设备下行请求 VO
  19 + */
  20 + void simulationDeviceDownstream(@Valid IotDeviceSimulationUpstreamReqVO downstreamReqVO);
  21 +
  22 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceDownstreamServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.device.message;
  2 +
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceSimulationUpstreamReqVO;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.springframework.stereotype.Service;
  6 +import org.springframework.validation.annotation.Validated;
  7 +
  8 +/**
  9 + * 设备下行 Service 实现类
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Service
  14 +@Validated
  15 +@Slf4j
  16 +public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamService {
  17 +
  18 + @Override
  19 + public void simulationDeviceDownstream(IotDeviceSimulationUpstreamReqVO downstreamReqVO) {
  20 +
  21 + }
  22 +
  23 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/upstream/IotDeviceUpstreamService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceUpstreamService.java
1   -package cn.iocoder.yudao.module.iot.service.device.upstream;
  1 +package cn.iocoder.yudao.module.iot.service.device.message;
2 2  
3 3 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceEventReportReqDTO;
4 4 import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
5 5 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceStateUpdateReqDTO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceSimulationUpstreamReqVO;
  7 +import jakarta.validation.Valid;
6 8  
7 9 /**
8 10 * 设备上行 Service 接口
... ... @@ -14,6 +16,13 @@ import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceStateUpdateReqDTO;
14 16 public interface IotDeviceUpstreamService {
15 17  
16 18 /**
  19 + * 模拟设备上行
  20 + *
  21 + * @param simulatorReqVO 设备上行请求 VO
  22 + */
  23 + void simulationDeviceUpstream(@Valid IotDeviceSimulationUpstreamReqVO simulatorReqVO);
  24 +
  25 + /**
17 26 * 更新设备状态
18 27 *
19 28 * @param updateReqDTO 更新设备状态 DTO
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/upstream/IotDeviceUpstreamServiceImpl.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceUpstreamServiceImpl.java
1   -package cn.iocoder.yudao.module.iot.service.device.upstream;
  1 +package cn.iocoder.yudao.module.iot.service.device.message;
2 2  
3 3 import cn.hutool.core.lang.Assert;
4 4 import cn.hutool.core.util.IdUtil;
... ... @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceEventReportReqDTO;
11 11 import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
12 12 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceStateUpdateReqDTO;
13 13 import cn.iocoder.yudao.module.iot.api.device.dto.IotDeviceUpstreamAbstractReqDTO;
  14 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceSimulationUpstreamReqVO;
14 15 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
15 16 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
16 17 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
... ... @@ -25,6 +26,7 @@ import org.springframework.stereotype.Service;
25 26 import org.springframework.validation.annotation.Validated;
26 27  
27 28 import java.time.LocalDateTime;
  29 +import java.util.Map;
28 30 import java.util.Objects;
29 31  
30 32 /**
... ... @@ -46,6 +48,37 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
46 48 private IotDeviceProducer deviceProducer;
47 49  
48 50 @Override
  51 + @SuppressWarnings("unchecked")
  52 + public void simulationDeviceUpstream(IotDeviceSimulationUpstreamReqVO simulatorReqVO) {
  53 + // 1. 校验存在
  54 + IotDeviceDO device = deviceService.validateDeviceExists(simulatorReqVO.getId());
  55 +
  56 + // 2.1 情况一:属性上报
  57 + String requestId = IdUtil.fastSimpleUUID();
  58 + if (Objects.equals(simulatorReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) {
  59 + reportDeviceProperty(((IotDevicePropertyReportReqDTO)
  60 + new IotDevicePropertyReportReqDTO().setRequestId(requestId).setReportTime(LocalDateTime.now())
  61 + .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()))
  62 + .setProperties((Map<String, Object>) simulatorReqVO.getData()));
  63 + return;
  64 + }
  65 + // 2.2 情况二:事件上报
  66 + if (Objects.equals(simulatorReqVO.getType(), IotDeviceMessageTypeEnum.EVENT.getType())) {
  67 + // TODO 芋艿:待实现
  68 + return;
  69 + }
  70 + // 2.3 情况三:状态变更
  71 + if (Objects.equals(simulatorReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) {
  72 + updateDeviceState(((IotDeviceStateUpdateReqDTO)
  73 + new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID()).setReportTime(LocalDateTime.now())
  74 + .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()))
  75 + .setState((Integer) simulatorReqVO.getData()));
  76 + return;
  77 + }
  78 + throw new IllegalArgumentException("未知的类型:" + simulatorReqVO.getType());
  79 + }
  80 +
  81 + @Override
49 82 public void updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) {
50 83 Assert.isTrue(ObjectUtils.equalsAny(updateReqDTO.getState(),
51 84 IotDeviceStateEnum.ONLINE.getState(), IotDeviceStateEnum.OFFLINE.getState()),
... ...