Commit 5fbfe49305425ced4fc318daa9f37b6bcfa67507

Authored by YunaiV
1 parent eb2d4fdb

【功能优化】Bpm:设备属性上报

Showing 18 changed files with 147 additions and 137 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/IotDeviceUpstreamApi.java
... ... @@ -35,7 +35,7 @@ public interface IotDeviceUpstreamApi {
35 35 * @param reportReqDTO 上报设备属性数据 DTO
36 36 */
37 37 @PostMapping(PREFIX + "/report-property")
38   - CommonResult<Boolean> reportDevicePropertyData(@Valid @RequestBody IotDevicePropertyReportReqDTO reportReqDTO);
  38 + CommonResult<Boolean> reportDeviceProperty(@Valid @RequestBody IotDevicePropertyReportReqDTO reportReqDTO);
39 39  
40 40 /**
41 41 * 上报设备事件数据
... ... @@ -43,6 +43,6 @@ public interface IotDeviceUpstreamApi {
43 43 * @param reportReqDTO 设备事件
44 44 */
45 45 @PostMapping(PREFIX + "/report-event")
46   - CommonResult<Boolean> reportDeviceEventData(@Valid @RequestBody IotDeviceEventReportReqDTO reportReqDTO);
  46 + CommonResult<Boolean> reportDeviceEvent(@Valid @RequestBody IotDeviceEventReportReqDTO reportReqDTO);
47 47  
48 48 }
49 49 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
... ... @@ -30,7 +30,6 @@ public interface ErrorCodeConstants {
30 30 ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在");
31 31 ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备");
32 32 ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!");
33   - ErrorCode DEVICE_DATA_CONTENT_JSON_PARSE_ERROR = new ErrorCode(1_050_003_007, "导入设备数据格式错误!");
34 33  
35 34 // ========== 产品分类 1-050-004-000 ==========
36 35 ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在");
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageTypeEnum.java
1 1 package cn.iocoder.yudao.module.iot.enums.device;
2 2  
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
3 4 import lombok.Getter;
4 5 import lombok.RequiredArgsConstructor;
5 6  
  7 +import java.util.Arrays;
  8 +
6 9 /**
7 10 * IoT 设备消息类型枚举
8 11 */
9 12 @Getter
10 13 @RequiredArgsConstructor
11   -public enum IotDeviceMessageTypeEnum {
  14 +public enum IotDeviceMessageTypeEnum implements ArrayValuable<String> {
12 15  
13 16 STATE("state"), // 设备状态
14 17 PROPERTY("property"), // 设备属性
15 18 EVENT("event"); // 设备事件
16 19  
  20 + public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageTypeEnum::getType).toArray(String[]::new);
  21 +
17 22 /**
18 23 * 属性
19 24 */
20 25 private final String type;
21 26  
  27 + @Override
  28 + public String[] array() {
  29 + return ARRAYS;
  30 + }
  31 +
22 32 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java
... ... @@ -29,14 +29,14 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi {
29 29 }
30 30  
31 31 @Override
32   - public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) {
33   - deviceUpstreamService.reportDevicePropertyData(reportReqDTO);
  32 + public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
  33 + deviceUpstreamService.reportDeviceProperty(reportReqDTO);
34 34 return success(true);
35 35 }
36 36  
37 37 @Override
38   - public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) {
39   - deviceUpstreamService.reportDeviceEventData(reportReqDTO);
  38 + public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
  39 + deviceUpstreamService.reportDeviceEvent(reportReqDTO);
40 40 return success(true);
41 41 }
42 42  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
... ... @@ -159,4 +159,12 @@ public class IotDeviceController {
159 159 ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list);
160 160 }
161 161  
  162 + @PostMapping("/simulation-report")
  163 + @Operation(summary = "模拟设备上报")
  164 + @PreAuthorize("@ss.hasPermission('iot:device:simulation-report')")
  165 + public CommonResult<Boolean> simulationReportDevice(@Valid @RequestBody IotDeviceSimulationReportReqVO simulatorReqVO) {
  166 + deviceService.simulationReportDevice(simulatorReqVO);
  167 + return success(true);
  168 + }
  169 +
162 170 }
163 171 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java
... ... @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 6 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.*;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
8 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
  8 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
9 9 import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService;
10 10 import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
11 11 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -13,7 +13,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
13 13 import jakarta.annotation.Resource;
14 14 import jakarta.validation.Valid;
15 15 import org.springframework.validation.annotation.Validated;
16   -import org.springframework.web.bind.annotation.*;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RestController;
17 19  
18 20 import java.util.List;
19 21 import java.util.Map;
... ... @@ -48,16 +50,6 @@ public class IotDeviceDataController {
48 50 }
49 51  
50 52 // TODO:功能权限
51   - @PostMapping("/simulator")
52   - @Operation(summary = "模拟设备")
53   - public CommonResult<Boolean> simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulatorReqVO) {
54   - //TODO:先使用 IotDeviceDataSimulatorSaveReqVO 另外content里数据类型的效验前端也没做,后端应该要要效验一下,这块后续看看怎么安排
55   - // TODO @super:应该 deviceDataService 里面有个 simulatorDevice,然后里面去 insert 日志!
56   - deviceDataService.simulatorSend(simulatorReqVO);
57   - return success(true);
58   - }
59   -
60   - // TODO:功能权限
61 53 @GetMapping("/log/page")
62 54 @Operation(summary = "获得设备日志分页")
63 55 public CommonResult<PageResult<IotDeviceLogRespVO>> getDeviceLogPage(@Valid IotDeviceLogPageReqVO pageReqVO) {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceSimulationReportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
  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 IotDeviceSimulationReportReqVO {
  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; // 例如说:属性上报的 properties、事件上报的 params
  29 +
  30 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java deleted
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotEmpty;
5   -import lombok.Data;
6   -
7   -// TODO super: SaveReqVO => ReqVO
8   -@Schema(description = "管理后台 - IoT 模拟设备数据 Request VO")
9   -@Data
10   -public class IotDeviceDataSimulatorSaveReqVO {
11   -
12   - // TODO @super:感觉后端随机更合适?
13   - @Schema(description = "消息 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "msg123")
14   - private String id;
15   -
16   - // TODO @super:不用传递 productKey,因为 deviceKey 可以推导出来
17   - // TODO 讨论: 日志记录的时候要记录一下productKey,目前是前端已经有productKey了,所以前端传入,如果不传入的话,后端要根据deviceKey查询productKey,感觉直传是不是效率高一些
18   - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123")
19   - @NotEmpty(message = "产品标识不能为空")
20   - private String productKey;
21   -
22   - @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123")
23   - @NotEmpty(message = "设备标识不能为空")
24   - private String deviceKey;
25   -
26   - // TODO @super:type、subType,是不是不用传递,因为模拟只有属性???
27   - // TODO 讨论: 不只模拟属性
28   - @Schema(description = "消息/日志类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property")
29   - @NotEmpty(message = "消息类型不能为空")
30   - private String type;
31   -
32   - @Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature")
33   - @NotEmpty(message = "标识符不能为空")
34   - private String subType;
35   -
36   - @Schema(description = "数据内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"value\": 25.6}")
37   - @NotEmpty(message = "数据内容不能为空")
38   - private String content;
39   -
40   - // TODO @芋艿:需要讨论下,reportTime 到底以那个为准!
41   - @Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED)
42   - private Long reportTime;
43   -
44   -}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/UnifiedConfiguration.java
... ... @@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Value;
7 7 import org.springframework.context.annotation.Bean;
8 8 import org.springframework.context.annotation.Configuration;
9 9  
  10 +import java.nio.file.Paths;
  11 +
10 12 // TODO @芋艿:需要 review 下
11 13 @Slf4j
12 14 @Configuration
... ... @@ -19,8 +21,8 @@ public class UnifiedConfiguration {
19 21 // @DependsOn("deviceDataApiImpl")
20 22 public SpringPluginManager pluginManager() {
21 23 log.info("[init][实例化 SpringPluginManager]");
22   -// SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
23   - SpringPluginManager springPluginManager = new SpringPluginManager() {
  24 + SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
  25 +// SpringPluginManager springPluginManager = new SpringPluginManager() {
24 26  
25 27 @Override
26 28 public void startPlugins() {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
1 1 package cn.iocoder.yudao.module.iot.service.device;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
6   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
7   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceUpdateGroupReqVO;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
8 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
9   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceImportRespVO;
10   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceImportExcelVO;
11 6 import jakarta.validation.Valid;
12 7  
13 8 import javax.annotation.Nullable;
... ... @@ -133,4 +128,11 @@ public interface IotDeviceService {
133 128 */
134 129 IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport);
135 130  
  131 + /**
  132 + * 模拟设备上报
  133 + *
  134 + * @param reportReqVO 上报信息
  135 + */
  136 + void simulationReportDevice(IotDeviceSimulationReportReqVO reportReqVO);
  137 +
136 138 }
137 139 \ 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
... ... @@ -11,14 +11,17 @@ 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.aop.TenantIgnore;
13 13 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
  14 +import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
14 15 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
15 16 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
16 17 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO;
17 18 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
18 19 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
19 20 import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
  21 +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
20 22 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
21 23 import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
  24 +import cn.iocoder.yudao.module.iot.service.device.upstream.IotDeviceUpstreamService;
22 25 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
23 26 import jakarta.annotation.Resource;
24 27 import jakarta.validation.ConstraintViolationException;
... ... @@ -56,6 +59,9 @@ public class IotDeviceServiceImpl implements IotDeviceService {
56 59 @Resource
57 60 @Lazy // 延迟加载,解决循环依赖
58 61 private IotDeviceGroupService deviceGroupService;
  62 + @Resource
  63 + @Lazy // 延迟加载,解决循环依赖
  64 + private IotDeviceUpstreamService deviceUpstreamService;
59 65  
60 66 @Override
61 67 public Long createDevice(IotDeviceSaveReqVO createReqVO) {
... ... @@ -84,6 +90,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
84 90  
85 91 // 2.1 转换 VO 为 DO
86 92 // TODO @芋艿:state 相关的参数。另外,到底叫 state,还是 status 好!
  93 + // TODO @芋艿:各种 mqtt 是不是可以简化!
87 94 IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class, o -> {
88 95 o.setProductKey(product.getProductKey()).setDeviceType(product.getDeviceType());
89 96 // 生成并设置必要的字段
... ... @@ -392,6 +399,36 @@ public class IotDeviceServiceImpl implements IotDeviceService {
392 399 return respVO;
393 400 }
394 401  
  402 + @Override
  403 + @SuppressWarnings("unchecked")
  404 + public void simulationReportDevice(IotDeviceSimulationReportReqVO reportReqVO) {
  405 + // 1. 校验存在
  406 + IotDeviceDO device = validateDeviceExists(reportReqVO.getId());
  407 +
  408 + // 2.1 情况一:属性上报
  409 + String requestId = IdUtil.fastSimpleUUID();
  410 + if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) {
  411 + deviceUpstreamService.reportDeviceProperty(IotDevicePropertyReportReqDTO.builder()
  412 + .requestId(requestId).reportTime(LocalDateTime.now())
  413 + .productKey(device.getProductKey()).deviceName(device.getDeviceName())
  414 + .properties((Map<String, Object>) reportReqVO.getData()).build());
  415 + return;
  416 + }
  417 + // 2.2 情况二:事件上报
  418 + if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.EVENT.getType())) {
  419 + // TODO 芋艿:待实现
  420 + return;
  421 + }
  422 + // 2.3 情况三:状态变更
  423 + if (Objects.equals(reportReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) {
  424 + // TODO 芋艿:待实现
  425 + updateDeviceStatus(new IotDeviceStatusUpdateReqVO().setId(device.getId())
  426 + .setStatus((Integer) reportReqVO.getData()));
  427 + return;
  428 + }
  429 + throw new IllegalArgumentException("未知的类型:" + reportReqVO.getType());
  430 + }
  431 +
395 432 private void deleteDeviceCache(IotDeviceDO device) {
396 433 // 保证在 @CacheEvict 之前,忽略租户
397 434 TenantUtils.executeIgnore(() -> getSelf().deleteDeviceCache0(device));
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyService.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.iot.service.device.data;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO;
6 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
7 6 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
8 7 import jakarta.validation.Valid;
... ... @@ -32,13 +31,6 @@ public interface IotDevicePropertyService {
32 31 void saveDeviceProperty(IotDeviceMessage message);
33 32  
34 33 /**
35   - * 模拟设备
36   - *
37   - * @param simulatorReqVO 设备数据
38   - */
39   - void simulatorSend(IotDeviceDataSimulatorSaveReqVO simulatorReqVO);
40   -
41   - /**
42 34 * 获得设备属性最新数据
43 35 *
44 36 * @param deviceId 设备编号
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyServiceImpl.java
... ... @@ -4,12 +4,9 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.date.LocalDateTimeUtil;
5 5 import cn.hutool.core.map.MapUtil;
6 6 import cn.hutool.core.util.StrUtil;
7   -import cn.hutool.json.JSONObject;
8   -import cn.hutool.json.JSONUtil;
9 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
10 8 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
11 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
12   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO;
13 10 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
14 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
15 12 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
... ... @@ -34,9 +31,7 @@ import java.util.HashMap;
34 31 import java.util.List;
35 32 import java.util.Map;
36 33  
37   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
38 34 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
39   -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DATA_CONTENT_JSON_PARSE_ERROR;
40 35  
41 36 /**
42 37 * IoT 设备【属性】数据 Service 实现类
... ... @@ -155,33 +150,6 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
155 150 entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build()));
156 151 }
157 152  
158   - //TODO @芋艿:copy 了 saveDeviceData 的逻辑,后续看看这块怎么优化
159   - @Override
160   - public void simulatorSend(IotDeviceDataSimulatorSaveReqVO simulatorReqVO) {
161   - // 1. 根据设备 key ,获得设备信息
162   - IotDeviceDO device = deviceService.getDeviceByDeviceKey(simulatorReqVO.getDeviceKey());
163   -
164   - // 2. 解析 content 为 JSON 对象
165   - JSONObject contentJson;
166   - try {
167   - contentJson = JSONUtil.parseObj(simulatorReqVO.getContent());
168   - } catch (Exception e) {
169   - throw exception(DEVICE_DATA_CONTENT_JSON_PARSE_ERROR);
170   - }
171   -
172   - // TODO @芋艿:后续优化
173   - // 3. 构建物模型消息
174   -// IotDeviceMessage thingModelMessage = IotDeviceMessage.builder()
175   -// .params(contentJson) // 将 content 作为 params
176   -// .time(simulatorReqVO.getReportTime()) // 使用上报时间
177   -// .productKey(simulatorReqVO.getProductKey())
178   -// .deviceName(device.getDeviceName())
179   -// .build();
180   -
181   - // 4. 发送模拟消息
182   -// simulateSendProducer.sendDeviceMessage(thingModelMessage);
183   - }
184   -
185 153 @Override
186 154 public List<IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
187 155 // List<IotDevicePropertyDO> list = new ArrayList<>();
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/upstream/IotDeviceUpstreamService.java
... ... @@ -25,13 +25,13 @@ public interface IotDeviceUpstreamService {
25 25 *
26 26 * @param reportReqDTO 上报设备属性数据 DTO
27 27 */
28   - void reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO);
  28 + void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO);
29 29  
30 30 /**
31 31 * 上报设备事件数据
32 32 *
33 33 * @param reportReqDTO 设备事件
34 34 */
35   - void reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO);
  35 + void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO);
36 36  
37 37 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/upstream/IotDeviceUpstreamServiceImpl.java
... ... @@ -43,7 +43,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
43 43 }
44 44  
45 45 @Override
46   - public void reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) {
  46 + public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
47 47 // 1.1 获得设备
48 48 log.info("[reportDevicePropertyData][上报设备属性数据: {}]", reportReqDTO);
49 49 IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache(
... ... @@ -65,7 +65,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
65 65 }
66 66  
67 67 @Override
68   - public void reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) {
  68 + public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
69 69 log.info("[reportDeviceEventData][上报设备事件数据: {}]", reportReqDTO);
70 70  
71 71 // TODO 芋艿:待实现
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/api/DeviceDataApiClient.java
... ... @@ -35,13 +35,13 @@ public class DeviceDataApiClient implements IotDeviceUpstreamApi {
35 35 }
36 36  
37 37 @Override
38   - public CommonResult<Boolean> reportDeviceEventData(IotDeviceEventReportReqDTO reportReqDTO) {
  38 + public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) {
39 39 String url = deviceDataUrl + URL_PREFIX + "/report-event";
40 40 return doPost(url, reportReqDTO, "reportDeviceEventData");
41 41 }
42 42  
43 43 @Override
44   - public CommonResult<Boolean> reportDevicePropertyData(IotDevicePropertyReportReqDTO reportReqDTO) {
  44 + public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) {
45 45 String url = deviceDataUrl + URL_PREFIX + "/report-property";
46 46 return doPost(url, reportReqDTO, "reportDevicePropertyData");
47 47 }
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/service/HttpVertxHandler.java
... ... @@ -49,7 +49,7 @@ public class HttpVertxHandler implements Handler&lt;RoutingContext&gt; {
49 49 .properties((Map<String, Object>) requestBody.asJsonObject().getMap().get("properties"))
50 50 .build();
51 51  
52   - deviceDataApi.reportDevicePropertyData(reportReqDTO);
  52 + deviceDataApi.reportDeviceProperty(reportReqDTO);
53 53  
54 54 ctx.response()
55 55 .setStatusCode(200)
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -45,16 +45,16 @@ spring:
45 45 primary: master
46 46 datasource:
47 47 master:
48   - url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
49   - # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例
  48 + url: jdbc:mysql://chaojiniu.top:23306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
  49 + # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
50 50 # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
51 51 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
52 52 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
53 53 # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
54 54 # url: jdbc:kingbase8://127.0.0.1:54321/test # 人大金仓 KingbaseES 连接的示例
55 55 # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 连接的示例
56   - username: root
57   - password: 123456
  56 + username: ruoyi-vue-pro
  57 + password: ruoyi-@h2ju02hebp
58 58 # username: sa # SQL Server 连接的示例
59 59 # password: Yudao@2024 # SQL Server 连接的示例
60 60 # username: SYSDBA # DM 连接的示例
... ... @@ -63,17 +63,25 @@ spring:
63 63 # password: Yudao@2024 # OpenGauss 连接的示例
64 64 slave: # 模拟从库,可根据自己需要修改
65 65 lazy: true # 开启懒加载,保证启动速度
66   - url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
  66 + url: jdbc:mysql://chaojiniu.top:23306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
  67 + username: ruoyi-vue-pro
  68 + password: ruoyi-@h2ju02hebp
  69 + tdengine: # IOT 数据库
  70 + # lazy: true # 开启懒加载,保证启动速度
  71 + url: jdbc:TAOS-RS://chaojiniu.top:6041/ruoyi_vue_pro
  72 + driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
67 73 username: root
68   - password: 123456
  74 + password: taosdata
  75 + druid:
  76 + validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL
69 77  
70 78 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
71 79 data:
72 80 redis:
73 81 host: 127.0.0.1 # 地址
74 82 port: 6379 # 端口
75   - database: 0 # 数据库索引
76   -# password: dev # 密码,建议生产环境开启
  83 + database: 1 # 数据库索引
  84 + # password: 123456 # 密码,建议生产环境开启
77 85  
78 86 --- #################### 定时任务相关配置 ####################
79 87  
... ... @@ -175,20 +183,22 @@ logging:
175 183 cn.iocoder.yudao.module.crm.dal.mysql: debug
176 184 cn.iocoder.yudao.module.erp.dal.mysql: debug
177 185 cn.iocoder.yudao.module.iot.dal.mysql: debug
  186 + cn.iocoder.yudao.module.iot.dal.tdengine: DEBUG
178 187 cn.iocoder.yudao.module.ai.dal.mysql: debug
179 188 org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
  189 + com.taosdata: DEBUG # TDengine 的日志级别
180 190  
181 191 debug: false
182 192  
183 193 --- #################### 微信公众号、小程序相关配置 ####################
184 194 wx:
185 195 mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
186   - # app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
187   - # secret: 5abee519483bc9f8cb37ce280e814bd0
  196 +# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
  197 +# secret: 5abee519483bc9f8cb37ce280e814bd0
188 198 app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
189 199 secret: 2a7b3b20c537e52e74afd395eb85f61f
190   - # app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
191   - # secret: bd4f9fab889591b62aeac0d7b8d8b4a0
  200 +# app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
  201 +# secret: bd4f9fab889591b62aeac0d7b8d8b4a0
192 202 # 存储配置,解决 AccessToken 的跨节点的共享
193 203 config-storage:
194 204 type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
... ... @@ -197,10 +207,10 @@ wx:
197 207 miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
198 208 # appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
199 209 # secret: 333ae72f41552af1e998fe1f54e1584a
200   - # appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
201   - # secret: 6f270509224a7ae1296bbf1c8cb97aed
202   - # appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
203   - # secret: 4a1a04e07f6a4a0751b39c3064a92c8b
  210 +# appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
  211 +# secret: 6f270509224a7ae1296bbf1c8cb97aed
  212 +# appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
  213 +# secret: 4a1a04e07f6a4a0751b39c3064a92c8b
204 214 appid: wx66186af0759f47c9 # 测试号(puhui 提供的)
205 215 secret: 3218bcbd112cbc614c7264ceb20144ac
206 216 config-storage:
... ... @@ -260,7 +270,7 @@ justauth:
260 270 iot:
261 271 emq:
262 272 # 账号
263   - username: anhaohao
  273 + username: haohao
264 274 # 密码
265 275 password: ahh@123456
266 276 # 主机地址
... ... @@ -272,4 +282,8 @@ iot:
272 282 # 保持连接
273 283 keepalive: 60
274 284 # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
275   - clearSession: true
276 285 \ No newline at end of file
  286 + clearSession: true
  287 +
  288 +pf4j:
  289 +# pluginsDir: /tmp/
  290 + pluginsDir: ../plugins
277 291 \ No newline at end of file
... ...