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/thingmodel/model/dataType/ThingModelArgument.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArgument.java
index 7b3fb097c4..94c4b83d51 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArgument.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArgument.java
@@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
+import cn.iocoder.yudao.module.iot.controller.admin.thinkmodel.model.ThinkModelProperty;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
@Data
-public class ThingModelArgument {
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ThinkModelArgument {
public static final String DIRECTION_INPUT = "input";
public static final String DIRECTION_OUTPUT = "output";
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 4fd6cfff0a..dba26352ba 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,7 +7,8 @@ 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.thingmodel.IotProductThingModelService;
+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;
import org.springframework.context.annotation.Lazy;
@@ -33,8 +34,11 @@ public class IotProductServiceImpl implements IotProductService {
private IotProductMapper productMapper;
@Resource
- @Lazy
- private IotProductThingModelService thingModelService;
+ @Lazy // 延迟加载,解决循环依赖
+ private IotProductThinkModelService thinkModelFunctionService;
+ @Resource
+ @Lazy // 延迟加载,解决循环依赖
+ private IotThinkModelMessageService thinkModelMessageService;
@Override
public Long createProduct(IotProductSaveReqVO createReqVO) {
@@ -114,8 +118,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 创建超级表数据模型
- thingModelService.createSuperTableDataModel(id);
+ // 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/IotThingModelMessageService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
index ffcb3063c5..76b3dfe326 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.service.tdengine;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThinkModelMessage;
/**
* 物模型消息 Service
@@ -14,5 +14,13 @@ public interface IotThingModelMessageService {
* @param device 设备
* @param thingModelMessage 物模型消息
*/
- void saveThingModelMessage(IotDeviceDO device, ThingModelMessage 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/IotThingModelMessageServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
index f5d589287f..5870628916 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
@@ -12,14 +12,21 @@ 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.ThingModelMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
+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.thingmodel.IotProductThingModelTypeEnum;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.service.thingmodel.IotProductThingModelService;
+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;
@@ -56,19 +63,29 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
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 saveThingModelMessage(IotDeviceDO device, ThingModelMessage 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. 获取设备属性并进行物模型校验,过滤非物模型属性
@@ -95,6 +112,28 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
private List