From d9dda54ccedb9dbf9ea13dc1190f95a136f55db5 Mon Sep 17 00:00:00 2001 From: alwayssuper <12851801+alwayssuper@user.noreply.gitee.com> Date: Fri, 10 Jan 2025 20:42:00 +0800 Subject: [PATCH 1/7] local --- .../dal/tdengine/IotDeviceLogDataMapper.java | 39 +++++++++++++++++++ .../device/IotDeviceLogDataService.java | 22 +++++++++++ .../src/main/resources/application-local.yaml | 31 ++++++++++----- .../src/main/resources/application.yaml | 5 ++- 4 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java new file mode 100644 index 0000000000..194218b7f8 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.iot.dal.tdengine; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; +import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * IoT 设备日志 Mapper + * + * @author alwayssuper + */ +@Mapper +@TDengineDS +@InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错 +public interface IotDeviceLogDataMapper { + + /** + * 创建设备日志超级表 + * 初始化只创建一次 + */ + void createDeviceLogSTable(); + + /** + * 创建设备日志子表 + * + * @param deviceKey 设备标识 + */ + void createDeviceLogTable( @Param("deviceKey") String deviceKey); + + /** + * 插入设备日志数据 + * + * @param log 设备日志数据 + */ + void insert(@Param("log") IotDeviceLogDO log); + +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java new file mode 100644 index 0000000000..166727dec7 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.iot.service.device; + +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; + +/** + * IoT 设备日志数据 Service 接口 + * + * @author alwayssuper + */ +public interface IotDeviceLogDataService { + + /** + * 初始化 TDengine 表 + */ + void initTDengineSTable(); + + /** + * 模拟设备创建设备日志 + * @param simulatorReqVO 模拟设备信息 + */ + void createDeviceLog(IotDeviceDataSimulatorSaveReqVO simulatorReqVO); +} diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index e5ae6d195a..fec1ad3506 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -45,7 +45,7 @@ spring: primary: master datasource: master: - url: jdbc:mysql://127.0.0.1:3307/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + url: jdbc:mysql://chaojiniu.top:23306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # 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 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 @@ -53,8 +53,8 @@ spring: # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例 # url: jdbc:kingbase8://127.0.0.1:54321/test # 人大金仓 KingbaseES 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 连接的示例 - username: root - password: ahh@123456 + username: ruoyi-vue-pro + password: ruoyi-@h2ju02hebp # username: sa # SQL Server 连接的示例 # password: Yudao@2024 # SQL Server 连接的示例 # username: SYSDBA # DM 连接的示例 @@ -63,17 +63,25 @@ spring: # password: Yudao@2024 # OpenGauss 连接的示例 slave: # 模拟从库,可根据自己需要修改 lazy: true # 开启懒加载,保证启动速度 - url: jdbc:mysql://127.0.0.1:3307/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://chaojiniu.top:23306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + username: ruoyi-vue-pro + password: ruoyi-@h2ju02hebp + tdengine: # IOT 数据库 +# lazy: true # 开启懒加载,保证启动速度 + url: jdbc:TAOS-RS://chaojiniu.top:6041/ruoyi_vue_pro + driver-class-name: com.taosdata.jdbc.rs.RestfulDriver username: root - password: ahh@123456 + password: taosdata + druid: + validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 data: redis: - host: 127.0.0.1 # 地址 + host: chaojiniu.top # 地址 port: 6379 # 端口 - database: 0 # 数据库索引 -# password: dev # 密码,建议生产环境开启 + database: 15 # 数据库索引 + password: fsknKD7UvQYZsyf2hXXn # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### @@ -175,8 +183,10 @@ logging: cn.iocoder.yudao.module.crm.dal.mysql: debug cn.iocoder.yudao.module.erp.dal.mysql: debug cn.iocoder.yudao.module.iot.dal.mysql: debug + cn.iocoder.yudao.module.iot.dal.tdengine: DEBUG cn.iocoder.yudao.module.ai.dal.mysql: debug org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示 + com.taosdata: DEBUG # TDengine 的日志级别 debug: false @@ -259,7 +269,7 @@ justauth: iot: emq: # 账号 - username: anhaohao + username: haohao # 密码 password: ahh@123456 # 主机地址 @@ -271,4 +281,5 @@ iot: # 保持连接 keepalive: 60 # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息) - clearSession: true \ No newline at end of file + clearSession: true + diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index baf68657e0..933e024356 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -328,4 +328,7 @@ yudao: key: pLXUGAwK5305 customer: E77DF18BE109F454A5CD319E44BF5177 -debug: false \ No newline at end of file +debug: false +# 插件配置 +pf4j: + pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录 \ No newline at end of file From 62a868f497874f5d755ec1bff4b74a08c8bb05a5 Mon Sep 17 00:00:00 2001 From: alwayssuper <12851801+alwayssuper@user.noreply.gitee.com> Date: Sun, 12 Jan 2025 20:13:41 +0800 Subject: [PATCH 2/7] feat:simulator1 --- .../dal/tdengine/IotDeviceLogDataMapper.java | 34 +++++-------------- .../tdengine/TdThingModelMessageMapper.java | 31 ----------------- .../TDengineTableInitConfiguration.java | 13 +++---- .../device/IotDeviceLogDataService.java | 2 +- .../device/IotDeviceLogDataServiceImpl.java | 19 +++++++++-- .../mapper/device/IotDeviceLogDataMapper.xml | 9 +++-- .../src/main/resources/application-local.yaml | 6 ++-- 7 files changed, 40 insertions(+), 74 deletions(-) delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java index 9584262dff..42dcc0cf38 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java @@ -21,32 +21,10 @@ public interface IotDeviceLogDataMapper { /** * 创建设备日志超级表 -<<<<<<< HEAD * 初始化只创建一次 */ void createDeviceLogSTable(); -======= - * - * 注意:初始化时只需创建一次 - */ - void createDeviceLogSTable(); - - // TODO @super:是不是删除哈 ->>>>>>> deab8c1cc6bb7864d9c40e0c369f649f6f9bfa41 - /** - * 创建设备日志子表 - * - * @param deviceKey 设备标识 - */ -<<<<<<< HEAD - void createDeviceLogTable( @Param("deviceKey") String deviceKey); - - /** - * 插入设备日志数据 - * -======= - void createDeviceLogTable(@Param("deviceKey") String deviceKey); // TODO @super:单个参数,不用加 @Param /** @@ -54,10 +32,9 @@ public interface IotDeviceLogDataMapper { * * 如果子表不存在,会自动创建子表 * ->>>>>>> deab8c1cc6bb7864d9c40e0c369f649f6f9bfa41 * @param log 设备日志数据 */ - void insert(@Param("log") IotDeviceLogDO log); + void insert(IotDeviceLogDO log); /** * 获得设备日志分页 @@ -65,7 +42,7 @@ public interface IotDeviceLogDataMapper { * @param reqVO 分页查询条件 * @return 设备日志列表 */ - List selectPage(@Param("reqVO") IotDeviceLogPageReqVO reqVO); + List selectPage(IotDeviceLogPageReqVO reqVO); /** * 获得设备日志总数 @@ -73,6 +50,11 @@ public interface IotDeviceLogDataMapper { * @param reqVO 查询条件 * @return 日志总数 */ - Long selectCount(@Param("reqVO") IotDeviceLogPageReqVO reqVO); + Long selectCount(IotDeviceLogPageReqVO reqVO); + /** + * 查询设备日志表是否存在 + * + */ + Object checkDeviceLogTableExists(); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java deleted file mode 100644 index cbc6e88366..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.tdengine; - -import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; -import com.baomidou.mybatisplus.annotation.InterceptorIgnore; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -/** - * 处理 TD 中物模型消息日志的操作 - */ -@Mapper -@Deprecated // TODO super:什么时候,删除下哈。 -@TDengineDS -@InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错 -public interface TdThingModelMessageMapper { - - /** - * 创建物模型消息日志超级表超级表 - * - */ - - void createSuperTable(@Param("productKey") String productKey); - - /** - * 创建子表 - * - */ - - void createTableWithTag(@Param("productKey") String productKey,@Param("deviceKey") String deviceKey); - -} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/config/TDengineTableInitConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/config/TDengineTableInitConfiguration.java index e0057e1808..c9f08903e8 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/config/TDengineTableInitConfiguration.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/config/TDengineTableInitConfiguration.java @@ -25,18 +25,13 @@ public class TDengineTableInitConfiguration implements ApplicationRunner { public void run(ApplicationArguments args) { try { // 初始化设备日志表 - deviceLogService.initTDengineSTable(); + deviceLogService.defineDeviceLog(); // TODO @super:这个日志,是不是不用打,不然重复啦!!! - log.info("[run]初始化 设备日志表 TDengine 表结构成功"); } catch (Exception ex) { // TODO @super:初始化失败,打印 error 日志,退出系统。。不然跑起来,就初始啦!!! - if (ex.getMessage().contains("Table already exists")) { - log.info("TDengine 设备日志超级表已存在,跳过创建"); - return; - } else{ - log.error("初始化 设备日志表 TDengine 表结构失败", ex); - } - throw ex; + // 初始化失败时打印错误日志并退出系统 + log.error("[TDengine] 初始化设备日志表结构失败,系统无法正常运行,即将退出", ex); + System.exit(1); } } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java index 1a3b48503c..a92d46bf49 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java @@ -17,7 +17,7 @@ public interface IotDeviceLogDataService { * *系统启动时,会自动初始化一次 */ - void initTDengineSTable(); + void defineDeviceLog(); /** * 插入设备日志 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index d0659e5073..769821e3e4 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -28,9 +28,24 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // TODO @super:方法名。defineDeviceLog。。未来,有可能别人使用别的记录日志,例如说 es 之类的。 @Override - public void initTDengineSTable() { + public void defineDeviceLog() { // TODO @super:改成不存在才创建。 - iotDeviceLogDataMapper.createDeviceLogSTable(); +// try { +// // 创建超级表(使用 IF NOT EXISTS 语句避免重复创建错误) +// iotDeviceLogDataMapper.createDeviceLogSTable(); +// } catch (Exception e) { +// if (e.getMessage().contains("already exists")) { +// log.info("[TDengine] 设备日志超级表已存在,跳过创建"); +// return; +// } +// throw e; +// } + if(iotDeviceLogDataMapper.checkDeviceLogTableExists()==null){ + log.info("[TDengine] 设备日志超级表不存在,开始创建 {}",iotDeviceLogDataMapper.checkDeviceLogTableExists()); + iotDeviceLogDataMapper.createDeviceLogSTable(); + }else{ + log.info("[TDengine] 设备日志超级表已存在,跳过创建"); + } } @Override diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml index 09e5dd4681..1554b7d1e0 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml @@ -6,13 +6,13 @@ - CREATE STABLE device_log ( + CREATE STABLE IF NOT EXISTS device_log ( ts TIMESTAMP, id NCHAR(50), product_key NCHAR(50), type NCHAR(50), - subType NCHAR(50), + sub_type NCHAR(50), content NCHAR(1024), report_time TIMESTAMP ) TAGS ( @@ -75,4 +75,9 @@ + + + \ No newline at end of file diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 518aa69a4c..08918a667b 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -283,9 +283,9 @@ iot: # MQTT-RPC 配置 mqtt: - broker: tcp://127.0.0.1:1883 - username: root - password: 123456 + broker: tcp://chaojiniu.top:1883 + username: haohao + password: ahh@123456 clientId: mqtt-rpc-server-${random.int} requestTopic: rpc/request responseTopicPrefix: rpc/response/ From 9f3730d5d943e4bd30acfcc21223a43791cb995a Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Mon, 20 Jan 2025 16:31:37 +0800 Subject: [PATCH 3/7] =?UTF-8?q?[fix]=EF=BC=9Acode=20=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IotDeviceDataSimulatorSaveReqVO.java | 10 ++- .../dal/dataobject/device/IotDeviceLogDO.java | 5 ++ .../dal/tdengine/IotDeviceLogDataMapper.java | 19 +++- .../device/IotDeviceLogDataServiceImpl.java | 6 +- .../iot/service/plugin/ExampleService.java | 86 +++++++++---------- .../mapper/device/IotDeviceLogDataMapper.xml | 6 +- 6 files changed, 77 insertions(+), 55 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java index c4f9d1f55d..5e2b085437 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java @@ -14,16 +14,18 @@ public class IotDeviceDataSimulatorSaveReqVO { private String id; // TODO @super:不用传递 productKey,因为 deviceKey 可以推导出来 - @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") - @NotEmpty(message = "产品ID不能为空") + // TODO 讨论: 日志记录的时候要记录一下productKey,目前是前端已经有productKey了,所以前端传入,如果不传入的话,后端要根据deviceKey查询productKey,感觉直传是不是效率高一些 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") + @NotEmpty(message = "产品标识不能为空") private String productKey; // TODO @super:中文写作规范,中英文之间,要有空格。例如说,设备 ID。ps:这里应该是设备标识 - @Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") - @NotEmpty(message = "设备ID不能为空") + @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") + @NotEmpty(message = "设备标识不能为空") private String deviceKey; // TODO @super:type、subType,是不是不用传递,因为模拟只有属性??? + // TODO 讨论: 不只模拟属性 @Schema(description = "消息/日志类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property") @NotEmpty(message = "消息类型不能为空") private String type; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java index dd811ee323..609c9c43ad 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.device; +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -27,12 +28,16 @@ public class IotDeviceLogDO { // TODO @super:关联要 @下 /** * 产品标识 + *

+ * 关联 {@link IotProductDO#getProductKey()} */ private String productKey; // TODO @super:关联要 @下 /** * 设备标识 + *

+ * 关联 {@link IotDeviceDO#getDeviceKey()}} */ private String deviceKey; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java index 42dcc0cf38..40516c7944 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java @@ -27,6 +27,19 @@ public interface IotDeviceLogDataMapper { // TODO @super:单个参数,不用加 @Param + //讨论:艿菇这里有些特殊情况,我也学习了一下这块知识: + // 如果使用的是Java 8及以上版本,并且编译器保留了参数名(通过编译器选项-parameters启用),则可以去掉@Param注解。MyBatis会自动使用参数的实际名称 + // 但在TDengine中 @Param去掉后TDengine会报错,以下是大模型的回答: + // 不用加 @Param在普通的 MySQL 场景下是正确的 - 对于 MyBatis,当方法只有一个参数时,确实可以不用添加 @Param 注解。 + //但是在 TDengine 的场景下,情况不同: + //TDengine 的特殊性: + //TDengine 使用特殊的 SQL 语法 + //需要处理超级表(STable)和子表的概念 + //参数绑定的方式与普通 MySQL 不同 + //为什么这里必须要 @Param: + //XML 中使用了 ${log.deviceKey} 这样的参数引用方式 + //需要在 SQL 中动态构建表名(device_log_${log.deviceKey}) + //没有 @Param("log") 的话,MyBatis 无法正确解析参数 /** * 插入设备日志数据 * @@ -34,7 +47,7 @@ public interface IotDeviceLogDataMapper { * * @param log 设备日志数据 */ - void insert(IotDeviceLogDO log); + void insert(@Param("log") IotDeviceLogDO log); /** * 获得设备日志分页 @@ -42,7 +55,7 @@ public interface IotDeviceLogDataMapper { * @param reqVO 分页查询条件 * @return 设备日志列表 */ - List selectPage(IotDeviceLogPageReqVO reqVO); + List selectPage(@Param("reqVO") IotDeviceLogPageReqVO reqVO); /** * 获得设备日志总数 @@ -50,7 +63,7 @@ public interface IotDeviceLogDataMapper { * @param reqVO 查询条件 * @return 日志总数 */ - Long selectCount(IotDeviceLogPageReqVO reqVO); + Long selectCount(@Param("reqVO") IotDeviceLogPageReqVO reqVO); /** * 查询设备日志表是否存在 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index 769821e3e4..85f950d5dd 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -55,16 +55,18 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // 2. 处理时间字段 // TODO @super:一次性的字段,不用单独给个变量 - long currentTime = System.currentTimeMillis(); +// long currentTime = System.currentTimeMillis(); // 2.1 设置时序时间为当前时间 - iotDeviceLogDO.setTs(currentTime); // TODO @super:TS在SQL中直接NOW 咱们的TS数据获取是走哪一种;走 now() +// iotDeviceLogDO.setTs(currentTime); // TODO @super:TS在SQL中直接NOW 咱们的TS数据获取是走哪一种;走 now() // 3. 插入数据 // TODO @super:不要直接调用对方的 IotDeviceLogDataMapper,通过 service 哈! + // 讨论:艿菇 这就是iotDeviceLogDataService的Impl iotDeviceLogDataMapper.insert(iotDeviceLogDO); } // TODO @super:在 iotDeviceLogDataService 写 + // 讨论:艿菇 这就是iotDeviceLogDataService的Impl @Override public PageResult getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { // 查询数据 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/ExampleService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/ExampleService.java index 22ebe8b4f2..13810bbd50 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/ExampleService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/ExampleService.java @@ -1,43 +1,43 @@ -package cn.iocoder.yudao.module.iot.service.plugin; - -import cn.iocoder.yudao.module.iot.mqttrpc.server.RpcServer; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; - -@Service -@RequiredArgsConstructor -public class ExampleService { - - private final RpcServer rpcServer; - - @PostConstruct - public void registerMethods() { - rpcServer.registerMethod("add", params -> { - if (params.length != 2) { - throw new IllegalArgumentException("add方法需要两个参数"); - } - int a = ((Number) params[0]).intValue(); - int b = ((Number) params[1]).intValue(); - return add(a, b); - }); - - rpcServer.registerMethod("concat", params -> { - if (params.length != 2) { - throw new IllegalArgumentException("concat方法需要两个参数"); - } - String str1 = params[0].toString(); - String str2 = params[1].toString(); - return concat(str1, str2); - }); - } - - private int add(int a, int b) { - return a + b; - } - - private String concat(String a, String b) { - return a + b; - } -} \ No newline at end of file +//package cn.iocoder.yudao.module.iot.service.plugin; +// +//import cn.iocoder.yudao.module.iot.mqttrpc.server.RpcServer; +//import lombok.RequiredArgsConstructor; +//import org.springframework.stereotype.Service; +// +//import javax.annotation.PostConstruct; +// +//@Service +//@RequiredArgsConstructor +//public class ExampleService { +// +// private final RpcServer rpcServer; +// +// @PostConstruct +// public void registerMethods() { +// rpcServer.registerMethod("add", params -> { +// if (params.length != 2) { +// throw new IllegalArgumentException("add方法需要两个参数"); +// } +// int a = ((Number) params[0]).intValue(); +// int b = ((Number) params[1]).intValue(); +// return add(a, b); +// }); +// +// rpcServer.registerMethod("concat", params -> { +// if (params.length != 2) { +// throw new IllegalArgumentException("concat方法需要两个参数"); +// } +// String str1 = params[0].toString(); +// String str2 = params[1].toString(); +// return concat(str1, str2); +// }); +// } +// +// private int add(int a, int b) { +// return a + b; +// } +// +// private String concat(String a, String b) { +// return a + b; +// } +//} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml index 1554b7d1e0..4a60f8f78d 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml @@ -27,11 +27,11 @@ - INSERT INTO device_log_${log.deviceKey} (ts, id, product_key, type, subType, content, report_time) + INSERT INTO device_log_${log.deviceKey} (id, product_key, type, subType, content, report_time) USING device_log TAGS ('${log.deviceKey}') VALUES ( - #{log.ts}, + NOW, #{log.id}, #{log.productKey}, #{log.type}, @@ -77,7 +77,7 @@ \ No newline at end of file From 0707792755e5e416d13664f4c34d302b8f2be154 Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Wed, 22 Jan 2025 16:59:00 +0800 Subject: [PATCH 4/7] =?UTF-8?q?[fix]=EF=BC=9Acode=20=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deviceconsumer/DeviceConsumer.java | 37 +++++++++++++++++++ .../simulatesend/SimulateSendConsumer.java | 1 - .../module/iot/mq/message/package-info.java | 4 ++ .../simulatesend/SimulateSendProducer.java | 9 +++++ .../device/IotDeviceLogDataService.java | 4 ++ .../device/IotDeviceLogDataServiceImpl.java | 6 +++ .../device/IotDevicePropertyDataService.java | 9 +++++ .../IotDevicePropertyDataServiceImpl.java | 9 +++++ 8 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/message/package-info.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java new file mode 100644 index 0000000000..63e0fed7fd --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.iot.mq.consumer.deviceconsumer; + + +import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; +import cn.iocoder.yudao.module.iot.service.device.IotDeviceLogDataService; +import cn.iocoder.yudao.module.iot.service.device.IotDevicePropertyDataService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 针对 {@link ThingModelMessage} 的消费者 + * + * @author alwayssuper + */ +@Component +@Slf4j +public class DeviceConsumer { + @Resource + private IotDeviceLogDataService iotDeviceLogDataService; + @Resource + private IotDevicePropertyDataService deviceDataService; + + // TODO @芋艿:这块先用ThingModelMessage,后续看看用啥替代 + @EventListener + @Async + public void onMessage(ThingModelMessage message) { + log.info("[onMessage][消息内容({})]", message); + deviceDataService.saveDeviceDataTest(message); + iotDeviceLogDataService.saveDeviceLog(message); + } + +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java index 111cf50073..1003fe7f4c 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java @@ -4,7 +4,6 @@ package cn.iocoder.yudao.module.iot.mq.consumer.simulatesend; * TODO @alwayssuper:记得实现,还有类注释哈 * * @author alwayssuper - * @since 2024/12/20 8:04 */ public class SimulateSendConsumer { } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/message/package-info.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/message/package-info.java new file mode 100644 index 0000000000..c3adf7c061 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/message/package-info.java @@ -0,0 +1,4 @@ +/** + * 消息队列的消息 + */ +package cn.iocoder.yudao.module.iot.mq.message; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java index 411ddd6f2b..1fb0c80c00 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.iot.mq.producer.simulatesend; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; @@ -19,4 +20,12 @@ public class SimulateSendProducer { @Resource private ApplicationContext applicationContext; + /** + * 发送 {@link ThingModelMessage} 消息 + * + * @param thingModelMessage 物模型消息 + */ + public void sendSimulateMessage(ThingModelMessage thingModelMessage) { + applicationContext.publishEvent(thingModelMessage); + } } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java index a92d46bf49..2ddf1113aa 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; /** * IoT 设备日志数据 Service 接口 @@ -36,4 +37,7 @@ public interface IotDeviceLogDataService { */ PageResult getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO); + + void saveDeviceLog(ThingModelMessage msg); + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index 85f950d5dd..e514d20491 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogDataMapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -76,4 +77,9 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ return new PageResult<>(list, total); } + @Override + public void saveDeviceLog(ThingModelMessage msg) { + + } + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java index 396cbf79fd..63cb5d6d93 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import jakarta.validation.Valid; import java.util.List; @@ -30,6 +31,14 @@ public interface IotDevicePropertyDataService { */ void saveDeviceData(IotDevicePropertyReportReqDTO createDTO); + + /** + * 保存设备数据 + * + * @param thingModelMessage 设备数据 + */ + void saveDeviceDataTest(ThingModelMessage thingModelMessage); + /** * 获得设备属性最新数据 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java index aefaac6960..c89f27346f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java @@ -150,6 +150,15 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe thingModelMessageService.saveThingModelMessage(device, thingModelMessage); } + //TODO:后续捋一捋这块逻辑,先借鉴一下目前的代码 + @Override + public void saveDeviceDataTest(ThingModelMessage thingModelMessage) { + // 1. 根据产品 key 和设备名称,获得设备信息 + IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceName(thingModelMessage.getProductKey(), thingModelMessage.getDeviceName()); + // 2. 保存数据 + thingModelMessageService.saveThingModelMessage(device, thingModelMessage); + } + @Override public List getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) { List list = new ArrayList<>(); From 2b27085ec2284b0db8ad42da553c0678f08ce526 Mon Sep 17 00:00:00 2001 From: alwayssuper <12851801+alwayssuper@user.noreply.gitee.com> Date: Wed, 22 Jan 2025 22:08:10 +0800 Subject: [PATCH 5/7] feat:simulator2 --- .../admin/device/IotDeviceDataController.java | 6 +++-- .../device/IotDevicePropertyDataService.java | 9 +++++++ .../IotDevicePropertyDataServiceImpl.java | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java index be451f17a0..7879698e3a 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.*; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; @@ -54,10 +55,11 @@ public class IotDeviceDataController { // TODO:数据权限 @PostMapping("/simulator") @Operation(summary = "模拟设备") - public CommonResult simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulatorReqVO) { + public CommonResult simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulcatorReqVO) { //TODO:先生成一下设备日志 后续完善模拟设备代码逻辑 // TODO @super:应该 deviceDataService 里面有个 simulatorDevice,然后里面去 insert 日志! - iotDeviceLogDataService.createDeviceLog(simulatorReqVO); + IotDevicePropertyReportReqDTO simulatorReqVO = new IotDevicePropertyReportReqDTO(); + deviceDataService.simulateSend(simulatorReqVO); return success(true); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java index 63cb5d6d93..4e535c9f26 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.service.device; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import jakarta.validation.Valid; @@ -39,6 +40,14 @@ public interface IotDevicePropertyDataService { */ void saveDeviceDataTest(ThingModelMessage thingModelMessage); + /** + * 模拟设备 + * + * @param simulatorReqVO 设备数据 + */ + + void simulateSend(IotDevicePropertyReportReqDTO simulatorReqVO); + /** * 获得设备属性最新数据 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java index c89f27346f..00b29f07e6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java @@ -8,6 +8,7 @@ import cn.hutool.json.JSONObject; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; @@ -22,6 +23,7 @@ import cn.iocoder.yudao.module.iot.enums.IotConstants; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; +import cn.iocoder.yudao.module.iot.mq.producer.simulatesend.SimulateSendProducer; import cn.iocoder.yudao.module.iot.service.product.IotProductService; import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; @@ -76,6 +78,9 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe @Resource private IotProductService productService; + @Resource + private SimulateSendProducer simulateSendProducer; + @Resource private TdEngineDMLMapper tdEngineDMLMapper; @@ -159,6 +164,27 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe thingModelMessageService.saveThingModelMessage(device, thingModelMessage); } + //TODO: copy了saveDeviceData的逻辑,后续看看这块怎么优化 + @Override + public void simulateSend(IotDevicePropertyReportReqDTO simulatorReqVO) { + // 1. 根据产品 key 和设备名称,获得设备信息 + IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceName(simulatorReqVO.getProductKey(), simulatorReqVO.getDeviceName()); + // 2. 解析消息,保存数据 + JSONObject jsonObject = new JSONObject(simulatorReqVO.getParams()); + log.info("[saveDeviceData][productKey({}) deviceName({}) data({})]", simulatorReqVO.getProductKey(), simulatorReqVO.getDeviceName(), jsonObject); + ThingModelMessage thingModelMessage = ThingModelMessage.builder() + .id(jsonObject.getStr("id")) + .sys(jsonObject.get("sys")) + .method(jsonObject.getStr("method")) + .params(jsonObject.get("params")) + .time(jsonObject.getLong("time") == null ? System.currentTimeMillis() : jsonObject.getLong("time")) + .productKey(simulatorReqVO.getProductKey()) + .deviceName(simulatorReqVO.getDeviceName()) + .deviceKey(device.getDeviceKey()) + .build(); + simulateSendProducer.sendSimulateMessage(thingModelMessage); + } + @Override public List getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) { List list = new ArrayList<>(); From 4f962bd1f73fed4b7fb1c4186300ecd3ca0ac59f Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Thu, 23 Jan 2025 16:54:45 +0800 Subject: [PATCH 6/7] =?UTF-8?q?[fix]=EF=BC=9Acode=20=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/iot/enums/ErrorCodeConstants.java | 1 + .../admin/device/IotDeviceDataController.java | 7 ++-- .../IotDeviceDataSimulatorSaveReqVO.java | 1 - .../deviceconsumer/DeviceConsumer.java | 4 +- .../simulatesend/SimulateSendConsumer.java | 9 ----- .../device/IotDeviceLogDataService.java | 6 ++- .../device/IotDeviceLogDataServiceImpl.java | 14 +++++++ .../device/IotDevicePropertyDataService.java | 2 +- .../IotDevicePropertyDataServiceImpl.java | 39 ++++++++++++------- .../iot/service/device/IotDeviceService.java | 9 +++++ .../service/device/IotDeviceServiceImpl.java | 5 +++ .../mapper/device/IotDeviceLogDataMapper.xml | 2 +- 12 files changed, 68 insertions(+), 31 deletions(-) delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 4539f12591..305aa6c7fd 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -30,6 +30,7 @@ public interface ErrorCodeConstants { ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!"); + ErrorCode DEVICE_DATA_CONTENT_JSON_PARSE_ERROR = new ErrorCode(1_050_003_007, "导入设备数据格式错误!"); // ========== 产品分类 1-050-004-000 ========== ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在"); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java index 7879698e3a..f78a96b248 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java @@ -55,11 +55,10 @@ public class IotDeviceDataController { // TODO:数据权限 @PostMapping("/simulator") @Operation(summary = "模拟设备") - public CommonResult simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulcatorReqVO) { - //TODO:先生成一下设备日志 后续完善模拟设备代码逻辑 + public CommonResult simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulatorReqVO) { + //TODO:先使用 IotDeviceDataSimulatorSaveReqVO 另外content里数据类型的效验前端也没做,后端应该要要效验一下,这块后续看看怎么安排 // TODO @super:应该 deviceDataService 里面有个 simulatorDevice,然后里面去 insert 日志! - IotDevicePropertyReportReqDTO simulatorReqVO = new IotDevicePropertyReportReqDTO(); - deviceDataService.simulateSend(simulatorReqVO); + deviceDataService.simulatorSend(simulatorReqVO); return success(true); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java index 5e2b085437..4d09808b14 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java @@ -38,7 +38,6 @@ public class IotDeviceDataSimulatorSaveReqVO { @NotEmpty(message = "数据内容不能为空") private String content; - // TODO @芋艿:需要讨论下,reportTime 到底以那个为准! @Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED) private Long reportTime; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java index 63e0fed7fd..862fb4d826 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java @@ -30,7 +30,9 @@ public class DeviceConsumer { @Async public void onMessage(ThingModelMessage message) { log.info("[onMessage][消息内容({})]", message); - deviceDataService.saveDeviceDataTest(message); + // 设备数据记录 +// deviceDataService.saveDeviceDataTest(message); + // 设备日志记录 iotDeviceLogDataService.saveDeviceLog(message); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java deleted file mode 100644 index 1003fe7f4c..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.module.iot.mq.consumer.simulatesend; - -/** - * TODO @alwayssuper:记得实现,还有类注释哈 - * - * @author alwayssuper - */ -public class SimulateSendConsumer { -} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java index 2ddf1113aa..2d7bf98500 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java @@ -37,7 +37,11 @@ public interface IotDeviceLogDataService { */ PageResult getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO); - + /** + * 插入设备日志 + * + * @param msg 设备数据 + */ void saveDeviceLog(ThingModelMessage msg); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index e514d20491..bee966e72c 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.iot.service.device; +import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; @@ -12,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.Date; import java.util.List; /** @@ -79,7 +81,19 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ @Override public void saveDeviceLog(ThingModelMessage msg) { + // 1. 构建设备日志对象 + IotDeviceLogDO iotDeviceLogDO = IotDeviceLogDO.builder() + .id(msg.getId()) // 消息ID + .deviceKey(msg.getDeviceKey()) // 设备标识 + .productKey(msg.getProductKey()) // 产品标识 + .type(msg.getMethod()) // 消息类型,使用method作为类型 + .subType("property") // TODO:这块先写死,后续优化 + .content(JSONUtil.toJsonStr(msg)) // TODO:后续优化 + .reportTime(msg.getTime()) // 上报时间 + .build(); + // 2. 插入设备日志 + iotDeviceLogDataMapper.insert(iotDeviceLogDO); } } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java index 4e535c9f26..92a64c28f8 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java @@ -46,7 +46,7 @@ public interface IotDevicePropertyDataService { * @param simulatorReqVO 设备数据 */ - void simulateSend(IotDevicePropertyReportReqDTO simulatorReqVO); + void simulatorSend(IotDeviceDataSimulatorSaveReqVO simulatorReqVO); /** * 获得设备属性最新数据 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java index 00b29f07e6..134803c8e9 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java @@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.iot.service.device; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO; @@ -39,8 +41,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DATA_CONTENT_JSON_PARSE_ERROR; /** * IoT 设备【属性】数据 Service 实现类 @@ -164,24 +168,33 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe thingModelMessageService.saveThingModelMessage(device, thingModelMessage); } - //TODO: copy了saveDeviceData的逻辑,后续看看这块怎么优化 + //TODO: copy 了 saveDeviceData 的逻辑,后续看看这块怎么优化 @Override - public void simulateSend(IotDevicePropertyReportReqDTO simulatorReqVO) { - // 1. 根据产品 key 和设备名称,获得设备信息 - IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceName(simulatorReqVO.getProductKey(), simulatorReqVO.getDeviceName()); - // 2. 解析消息,保存数据 - JSONObject jsonObject = new JSONObject(simulatorReqVO.getParams()); - log.info("[saveDeviceData][productKey({}) deviceName({}) data({})]", simulatorReqVO.getProductKey(), simulatorReqVO.getDeviceName(), jsonObject); + public void simulatorSend(IotDeviceDataSimulatorSaveReqVO simulatorReqVO) { + // 1. 根据设备 key ,获得设备信息 + IotDeviceDO device = deviceService.getDeviceByDeviceKey(simulatorReqVO.getDeviceKey()); + + // 2. 解析 content 为 JSON 对象 + JSONObject contentJson; + try { + contentJson = JSONUtil.parseObj(simulatorReqVO.getContent()); + } catch (Exception e) { + throw exception(DEVICE_DATA_CONTENT_JSON_PARSE_ERROR); + } + + // 3. 构建物模型消息 ThingModelMessage thingModelMessage = ThingModelMessage.builder() - .id(jsonObject.getStr("id")) - .sys(jsonObject.get("sys")) - .method(jsonObject.getStr("method")) - .params(jsonObject.get("params")) - .time(jsonObject.getLong("time") == null ? System.currentTimeMillis() : jsonObject.getLong("time")) + .id(IdUtil.fastSimpleUUID()) // TODO:后续优化 + .sys(null)// TODO:这块先写死,后续优化 + .method("thing.event.property.post") // TODO:这块先写死,后续优化 + .params(contentJson) // 将 content 作为 params + .time(simulatorReqVO.getReportTime()) // 使用上报时间 .productKey(simulatorReqVO.getProductKey()) - .deviceName(simulatorReqVO.getDeviceName()) + .deviceName(device.getDeviceName()) .deviceKey(device.getDeviceKey()) .build(); + + // 4. 发送模拟消息 simulateSendProducer.sendSimulateMessage(thingModelMessage); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java index b8a3511cdd..adf3304d02 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java @@ -72,6 +72,15 @@ public interface IotDeviceService { */ IotDeviceDO getDevice(Long id); + + /** + * 根据设备 key 获得设备 + * + * @param deviceKey 编号 + * @return IoT 设备 + */ + IotDeviceDO getDeviceByDeviceKey(String deviceKey); + /** * ��得设备分页 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java index 1896b98b7d..6a28b27f34 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java @@ -197,6 +197,11 @@ public class IotDeviceServiceImpl implements IotDeviceService { return deviceMapper.selectById(id); } + @Override + public IotDeviceDO getDeviceByDeviceKey(String deviceKey) { + return deviceMapper.selectByDeviceKey(deviceKey); + } + @Override public PageResult getDevicePage(IotDevicePageReqVO pageReqVO) { return deviceMapper.selectPage(pageReqVO); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml index 4a60f8f78d..1e9b3fdfff 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml @@ -27,7 +27,7 @@ - INSERT INTO device_log_${log.deviceKey} (id, product_key, type, subType, content, report_time) + INSERT INTO device_log_${log.deviceKey} (ts, id, product_key, type, subType, content, report_time) USING device_log TAGS ('${log.deviceKey}') VALUES ( From 03d4f60e8027b2e6125e2db4077d87c72ba72ccf Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Fri, 24 Jan 2025 15:56:01 +0800 Subject: [PATCH 7/7] =?UTF-8?q?[fix]=EF=BC=9Acode=20=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataobject/tdengine/SelectVisualDO.java | 3 ++ .../dal/dataobject/tdengine/TdTableDO.java | 4 ++ .../dal/tdengine/IotDeviceLogDataMapper.java | 11 ++++- .../tdengine/IotDevicePropertyDataMapper.java | 43 +++++++++++++++++++ .../deviceconsumer/DeviceConsumer.java | 4 +- .../device/IotDeviceLogDataServiceImpl.java | 8 +++- .../IotDevicePropertyDataServiceImpl.java | 5 ++- .../IotThingModelMessageServiceImpl.java | 23 +++++++--- .../mapper/device/IotDeviceLogDataMapper.xml | 8 +++- .../device/IotDevicePropertyDataMapper.xml | 42 ++++++++++++++++++ 10 files changed, 138 insertions(+), 13 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java index 584562bfa6..c9ac20af22 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java @@ -19,6 +19,9 @@ public class SelectVisualDO { */ private String tableName; + + private String deviceKey; + /** * 属性 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java index 3265c3ebed..104be26837 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java @@ -33,6 +33,10 @@ public class TdTableDO { */ private String tableName; + private String productKey; + + private String deviceKey; + /** * COLUMN 字段 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java index 40516c7944..2d8230f1f6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java @@ -68,6 +68,15 @@ public interface IotDeviceLogDataMapper { /** * 查询设备日志表是否存在 * + * @return 不存在返回null */ - Object checkDeviceLogTableExists(); + Object checkDeviceLogSTableExists(); + + /** + * 检查设备日志子表是否存在 + * + * @param deviceKey 设备标识 + * @return 不存在返回null + */ + Object checkDeviceLogTableExists(@Param("deviceKey") String deviceKey); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java index 6053444fea..1599ce957c 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.iot.dal.tdengine; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; import com.baomidou.mybatisplus.annotation.InterceptorIgnore; @@ -10,6 +13,7 @@ import org.apache.ibatis.annotations.Param; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Mapper @@ -74,4 +78,43 @@ public interface IotDevicePropertyDataMapper { void alterProductPropertySTableDropField(@Param("productKey") String productKey, @Param("field") TDengineTableField field); + //TODO:先参考一下老逻辑,后续改进 + /** + * 插入数据 - 指定列插入数据 + * + * @param table 数据 + * productKey 产品 key + * deviceKey 设备 key + * columns 列 + */ + void insertDevicePropertyData(TdTableDO table); + + //TODO:先参考一下老逻辑,后续改进 + /** + * 查看超级表 - 获取超级表的结构信息 + * SQL:DESCRIBE [db_name.]stb_name; + * + * @param superTable 超级表信息 + * productKey 产品 key + */ + List> describeSuperTable(TdTableDO superTable); + + /** + * 获取历史数据列表 + * + * @param selectVisualDO 查询条件 + * @return 历史数据列表 + */ + @TenantIgnore + List> selectHistoryDataList(SelectVisualDO selectVisualDO); + + /** + * 获取历史数据条数 + * + * @param selectVisualDO 查询条件 + * @return 数据条数 + */ + @TenantIgnore + Long selectHistoryCount(SelectVisualDO selectVisualDO); + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java index 862fb4d826..1daa05f920 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java @@ -30,8 +30,10 @@ public class DeviceConsumer { @Async public void onMessage(ThingModelMessage message) { log.info("[onMessage][消息内容({})]", message); + //TODO:数据插入这块整体写的比较混乱,整体借鉴了浩浩哥之前写的逻辑,目前是通过模拟设备科插入数据了,但之前的逻辑有大量弃用的部分,后续看看怎么完善 + // 设备数据记录 -// deviceDataService.saveDeviceDataTest(message); + deviceDataService.saveDeviceDataTest(message); // 设备日志记录 iotDeviceLogDataService.saveDeviceLog(message); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index bee966e72c..f66bcc8ad2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -43,8 +43,8 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // } // throw e; // } - if(iotDeviceLogDataMapper.checkDeviceLogTableExists()==null){ - log.info("[TDengine] 设备日志超级表不存在,开始创建 {}",iotDeviceLogDataMapper.checkDeviceLogTableExists()); + if(iotDeviceLogDataMapper.checkDeviceLogSTableExists()==null){ + log.info("[TDengine] 设备日志超级表不存在,开始创建"); iotDeviceLogDataMapper.createDeviceLogSTable(); }else{ log.info("[TDengine] 设备日志超级表已存在,跳过创建"); @@ -72,6 +72,10 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // 讨论:艿菇 这就是iotDeviceLogDataService的Impl @Override public PageResult getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { + // 当设备日志表未创建时,查询会出现报错 + if(iotDeviceLogDataMapper.checkDeviceLogTableExists(pageReqVO.getDeviceKey())==null){ + return null; + } // 查询数据 List list = iotDeviceLogDataMapper.selectPage(pageReqVO); Long total = iotDeviceLogDataMapper.selectCount(pageReqVO); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java index 134803c8e9..2b998e7886 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java @@ -244,6 +244,7 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe SelectVisualDO selectVisualDO = new SelectVisualDO(); selectVisualDO.setDataBaseName(getDatabaseName()); selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())); + selectVisualDO.setDeviceKey(device.getDeviceKey()); selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier()); selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime()); selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime()); @@ -251,8 +252,8 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe params.put("rows", deviceDataReqVO.getPageSize()); params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize()); selectVisualDO.setParams(params); - pageResult.setList(tdEngineDMLMapper.selectHistoryDataList(selectVisualDO)); - pageResult.setTotal(tdEngineDMLMapper.selectHistoryCount(selectVisualDO)); + pageResult.setList(devicePropertyDataMapper.selectHistoryDataList(selectVisualDO)); + pageResult.setTotal(devicePropertyDataMapper.selectHistoryCount(selectVisualDO)); return pageResult; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java index e094b34cb6..c35bb3a28b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; +import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyDataMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper; import cn.iocoder.yudao.module.iot.enums.IotConstants; @@ -61,6 +62,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @Resource private TdEngineDMLMapper tdEngineDMLMapper; + @Resource + private IotDevicePropertyDataMapper iotDevicePropertyDataMapper; + @Resource private DeviceDataRedisDAO deviceDataRedisDAO; @@ -71,7 +75,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 1. 判断设备状态,如果为未激活状态,创建数据表并更新设备状态 if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) { // 1.1 创建设备表 - createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); +// createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO() .setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus())); } @@ -85,14 +89,20 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 3. 过滤并收集有效的属性字段,缓存设备属性 List schemaFieldValues = filterAndCollectValidFields(params, thingModelList, device, thingModelMessage.getTime()); - if (schemaFieldValues.size() == 1) { // 仅有时间字段,无需保存 + if (schemaFieldValues.size() == 0) { // 没有字段,无需保存 return; } // 4. 构建并保存设备属性数据 - tdEngineDMLMapper.insertData(TdTableDO.builder() - .dataBaseName(getDatabaseName()) - .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())) +// tdEngineDMLMapper.insertData(TdTableDO.builder() +// .dataBaseName(getDatabaseName()) +// .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())) +// .columns(schemaFieldValues) +// .build()); + // TODO:复用了旧逻辑,先过渡一下 + iotDevicePropertyDataMapper.insertDevicePropertyData(TdTableDO.builder() + .productKey(device.getProductKey()) + .deviceKey(device.getDeviceKey()) .columns(schemaFieldValues) .build()); } @@ -145,7 +155,8 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 3. 过滤并收集有效的属性字段 List schemaFieldValues = new ArrayList<>(); - schemaFieldValues.add(new TdFieldDO(TIME, time)); + //TODO:新版本是使用ts字段 +// schemaFieldValues.add(new TdFieldDO(TIME, time)); params.forEach((key, val) -> { if (propertyIdentifiers.contains(key)) { schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val)); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml index 1e9b3fdfff..828522ed70 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml @@ -76,8 +76,14 @@ - SHOW STABLES LIKE 'device_log' + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml index 9894e27a0e..3ac238d751 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml @@ -42,4 +42,46 @@ DROP COLUMN ${field.field} + + INSERT INTO device_property_${deviceKey} + USING product_property_${productKey} + TAGS ('${deviceKey}') + (ts + + ,${item.fieldName} + + ) + VALUES + (NOW + + ,#{item.fieldValue} + + ) + + + + + + + + + + + \ No newline at end of file