From 067130ecde7211d2063ba0e2a83e03daf7ab9e5e Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Thu, 19 Dec 2024 16:43:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E7=89=A9=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=97=A5=E5=BF=97=E5=BB=BA=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/iot/enums/IotConstants.java | 7 ++ .../model/dataType/ThinkModelArgument.java | 2 + .../tdengine/ThinkModelMessageDO.java | 66 +++++++++++++++++++ .../tdengine/TdThinkModelMessageMapper.java | 29 ++++++++ .../simulatesend/SimulateSendProducer.java | 20 ++++++ .../product/IotProductServiceImpl.java | 10 ++- .../tdengine/IotThinkModelMessageService.java | 8 +++ .../IotThinkModelMessageServiceImpl.java | 61 +++++++++++++++-- .../module/iot/util/IotTdDatabaseUtils.java | 63 ++++++++++++++++++ .../tdengine/TdThinkModelMessageMapper.xml | 34 ++++++++++ 10 files changed, 292 insertions(+), 8 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThinkModelMessageDO.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThinkModelMessageMapper.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/util/IotTdDatabaseUtils.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdThinkModelMessageMapper.xml diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java index 5927f44b96..0762ade9de 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java @@ -35,4 +35,11 @@ public interface IotConstants { */ String DEVICE_STABLE_NAME_FORMAT = "device_%s"; + /** + * 获取物模型消息记录设备名 + *
+ * 格式为 thing_model_message_{productKey}_{deviceName}
+ */
+ String THINK_MODEL_MESSAGE_TABLE_NAME_FORMAT = "thing_model_message_%s_%s";
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodel/model/dataType/ThinkModelArgument.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodel/model/dataType/ThinkModelArgument.java
index 7b293ca79e..2ed260fdec 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodel/model/dataType/ThinkModelArgument.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodel/model/dataType/ThinkModelArgument.java
@@ -1,9 +1,11 @@
package cn.iocoder.yudao.module.iot.controller.admin.thinkmodel.model.dataType;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodel.model.ThinkModelProperty;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
public class ThinkModelArgument {
public static final String DIRECTION_INPUT = "input";
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThinkModelMessageDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThinkModelMessageDO.java
new file mode 100644
index 0000000000..13309c81ed
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThinkModelMessageDO.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.xmlbeans.impl.xb.xsdschema.Public;
+
+
+/**
+ * TD 物模型消息日志的数据库
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ThinkModelMessageDO {
+ /**
+ * 数据库名称
+ */
+ private String dataBaseName;
+
+ // TODO @haohao:superTableName 和 tableName 是不是合并。因为每个 mapper 操作的时候,有且只会使用到其中一个。
+ /**
+ * 超级表名称
+ */
+ private String superTableName;
+
+ /**
+ * 表名称
+ */
+ private String tableName;
+
+ /**
+ * 消息ID
+ */
+ private String id;
+
+ /**
+ * 扩展功能的参数
+ */
+ private Object sys;
+
+ /**
+ * 请求方法 例如:thing.event.property.post
+ */
+ private String method;
+
+ /**
+ * 请求参数
+ */
+ private Object params;
+
+ /**
+ * 属性上报时间戳
+ */
+ private Long time;
+
+
+ /**
+ * 设备 key
+ */
+ private String deviceKey;
+
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThinkModelMessageMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThinkModelMessageMapper.java
new file mode 100644
index 0000000000..4eb59975d8
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThinkModelMessageMapper.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iot.dal.tdengine;
+
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThinkModelMessageDO;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 处理 TD 中物模型消息日志的操作
+ */
+@Mapper
+@DS("tdengine")
+public interface TdThinkModelMessageMapper {
+
+ /**
+ * 创建物模型消息日志超级表超级表
+ *
+ */
+ @TenantIgnore
+ void createSuperTable(ThinkModelMessageDO superTable);
+
+ /**
+ * 创建子表
+ *
+ */
+ @TenantIgnore
+ void createTableWithTag(ThinkModelMessageDO table);
+}
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
new file mode 100644
index 0000000000..76cde71be7
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/simulatesend/SimulateSendProducer.java
@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iot.mq.producer.simulatesend;
+
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+/**
+ * SimulateSend 模拟设备上报的 Producer
+ *
+ * @author alwayssuper
+ * @since 2024/12/17 16:35
+ */
+@Slf4j
+@Component
+public class SimulateSendProducer {
+ @Resource
+ private ApplicationContext applicationContext;
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
index b26c2c123b..f26c964522 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProduc
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductMapper;
import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
+import cn.iocoder.yudao.module.iot.service.tdengine.IotThinkModelMessageService;
import cn.iocoder.yudao.module.iot.service.thinkmodel.IotProductThinkModelService;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import jakarta.annotation.Resource;
@@ -31,11 +32,12 @@ public class IotProductServiceImpl implements IotProductService {
@Resource
private IotProductMapper productMapper;
-
@Resource
@Lazy
private IotProductThinkModelService thinkModelFunctionService;
-
+ @Resource
+ @Lazy
+ private IotThinkModelMessageService thinkModelMessageService;
@Override
public Long createProduct(IotProductSaveReqVO createReqVO) {
// 1. 生成 ProductKey
@@ -114,8 +116,10 @@ public class IotProductServiceImpl implements IotProductService {
IotProductDO updateObj = IotProductDO.builder().id(id).status(status).build();
// 3. 产品是发布状态
if (Objects.equals(status, IotProductStatusEnum.PUBLISHED.getStatus())) {
- // 3.1 创建超级表数据模型
+ // 3.1 创建产品超级表数据模型
thinkModelFunctionService.createSuperTableDataModel(id);
+ // 3.2 创建物模型日志超级表数据模型
+ thinkModelMessageService.createSuperTable(id);
}
productMapper.updateById(updateObj);
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageService.java
index 67ee2b99ae..67df7045fb 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageService.java
@@ -15,4 +15,12 @@ public interface IotThinkModelMessageService {
* @param thingModelMessage 物模型消息
*/
void saveThinkModelMessage(IotDeviceDO device, ThinkModelMessage thingModelMessage);
+
+ /**
+ * 创建物模型消息日志超级表
+ *
+ * @param productId 产品编号
+ */
+ void createSuperTable(Long productId);
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageServiceImpl.java
index 3c2debfa49..3c6059f992 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThinkModelMessageServiceImpl.java
@@ -7,19 +7,20 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThinkModelMessage;
+import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodel.IotProductThinkModelDO;
import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper;
import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
+import cn.iocoder.yudao.module.iot.dal.tdengine.TdThinkModelMessageMapper;
import cn.iocoder.yudao.module.iot.enums.IotConstants;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.thinkmodel.IotProductThinkModelTypeEnum;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
+import cn.iocoder.yudao.module.iot.service.product.IotProductService;
import cn.iocoder.yudao.module.iot.service.thinkmodel.IotProductThinkModelService;
+import cn.iocoder.yudao.module.iot.util.IotTdDatabaseUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -54,19 +55,29 @@ public class IotThinkModelMessageServiceImpl implements IotThinkModelMessageServ
private TdEngineDDLMapper tdEngineDDLMapper;
@Resource
private TdEngineDMLMapper tdEngineDMLMapper;
-
+ @Resource
+ private IotProductService productService;
@Resource
private DeviceDataRedisDAO deviceDataRedisDAO;
+ @Resource
+ private IotTdDatabaseUtils iotTdDatabaseUtils;
+
+ @Resource
+ private TdThinkModelMessageMapper tdThinkModelMessageMapper;
+
// TODO @haohao:这个方法,可以考虑加下 1. 2. 3. 更有层次感
@Override
@TenantIgnore
public void saveThinkModelMessage(IotDeviceDO device, ThinkModelMessage thingModelMessage) {
// 1. 判断设备状态,如果为未激活状态,创建数据表并更新设备状态
if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) {
+ // 1.1 创建设备表
createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO()
.setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus()));
+ // 1.2 创建物模型日志设备表
+ createThinkModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
}
// 2. 获取设备属性并进行物模型校验,过滤非物模型属性
@@ -90,6 +101,22 @@ public class IotThinkModelMessageServiceImpl implements IotThinkModelMessageServ
.build());
}
+ @Override
+ @TenantIgnore
+ public void createSuperTable(Long productId) {
+ // 1. 查询产品
+ IotProductDO product = productService.getProduct(productId);
+
+ // 2. 获取超级表的名称和数据库名称
+ String databaseName = iotTdDatabaseUtils.getDatabaseName();
+ String superTableName = IotTdDatabaseUtils.getThinkModelMessageSuperTableName(product.getProductKey());
+
+ // 3. 创建超级表
+ tdThinkModelMessageMapper.createSuperTable(ThinkModelMessageDO.builder().build()
+ .setDataBaseName(databaseName)
+ .setSuperTableName(superTableName));
+ }
+
private List