Commit 624f5283b3ec89295f3562a068bd009881b1c487

Authored by 安浩浩
1 parent 3dafd31d

【新增功能】 设备数据存储和展示

Showing 20 changed files with 523 additions and 108 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductFunctionTypeEnum.java
... ... @@ -30,7 +30,7 @@ public enum IotProductFunctionTypeEnum implements IntArrayValuable {
30 30 */
31 31 private final String description;
32 32  
33   - public static IotProductFunctionTypeEnum valueOf(Integer type) {
  33 + public static IotProductFunctionTypeEnum valueOfType(Integer type) {
34 34 for (IotProductFunctionTypeEnum value : values()) {
35 35 if (value.getType().equals(type)) {
36 36 return value;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
... ... @@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.iot.controller.admin.device;
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
7   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO;
8   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
9   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceRespVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
10 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
11 11 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
12 12 import io.swagger.v3.oas.annotations.Operation;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
  8 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import jakarta.annotation.Resource;
  12 +import jakarta.validation.Valid;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.GetMapping;
  15 +import org.springframework.web.bind.annotation.RequestMapping;
  16 +import org.springframework.web.bind.annotation.RestController;
  17 +
  18 +import java.util.List;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +
  22 +@Tag(name = "管理后台 - IoT 设备数据")
  23 +@RestController
  24 +@RequestMapping("/iot/device/data")
  25 +@Validated
  26 +public class IotDeviceDataController {
  27 +
  28 + @Resource
  29 + private IotDeviceDataService deviceDataService;
  30 +
  31 + @GetMapping("/latest-data")
  32 + @Operation(summary = "获取设备属性最新数据")
  33 + public CommonResult<List<IotDeviceDataRespVO>> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
  34 + List<IotDeviceDataDO> list = deviceDataService.getDevicePropertiesLatestData(deviceDataReqVO);
  35 + return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
  36 + }
  37 +
  38 +}
0 39 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDevicePageReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDevicePageReqVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceRespVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceRespVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2  
3 3 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
4 4 import com.alibaba.excel.annotation.ExcelProperty;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceSaveReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceSaveReqVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceStatusUpdateReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceStatusUpdateReqVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 4 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "管理后台 - IoT 设备数据 Request VO")
  9 +@Data
  10 +public class IotDeviceDataReqVO {
  11 +
  12 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
  13 + private Long deviceId;
  14 +
  15 + @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
  16 + private String identifier;
  17 +
  18 + @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + private String name;
  20 +
  21 +}
0 22 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  4 +import com.alibaba.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Builder;
  7 +import lombok.Data;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +@Schema(description = "管理后台 - IoT 设备数据 Response VO")
  12 +@Data
  13 +public class IotDeviceDataRespVO {
  14 +
  15 + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
  16 + private Long deviceId;
  17 +
  18 + @Schema(description = "物模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
  19 + private Long thinkModelFunctionId;
  20 +
  21 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private String productKey;
  23 +
  24 + @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
  25 + private String deviceName;
  26 +
  27 + @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private String identifier;
  29 +
  30 + @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private String name;
  32 +
  33 + @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + private String dataType;
  35 +
  36 + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + private LocalDateTime updateTime;
  38 +
  39 + @Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + private String value;
  41 +
  42 +}
0 43 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/convert/device/IotDeviceDataConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.convert.device;
  2 +
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
  11 +import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
  12 +import org.mapstruct.Mapper;
  13 +import org.mapstruct.Mapping;
  14 +import org.mapstruct.factory.Mappers;
  15 +
  16 +import java.util.ArrayList;
  17 +import java.util.List;
  18 +import java.util.Map;
  19 +import java.util.Objects;
  20 +
  21 +@Mapper
  22 +public interface IotDeviceDataConvert {
  23 +
  24 + IotDeviceDataConvert INSTANCE = Mappers.getMapper(IotDeviceDataConvert.class);
  25 +
  26 +// default List<IotDeviceDataRespVO> convert(Map<String, Object> deviceData, IotDeviceDO device){
  27 +// List<IotDeviceDataRespVO> list = new ArrayList<>();
  28 +// deviceData.forEach((identifier, value) -> {
  29 +//// ThingModelProperty property = ThingModelService.INSTANCE.getProperty(device.getProductId(), identifier);
  30 +//// if (Objects.isNull(property)) {
  31 +//// return;
  32 +//// }
  33 +// IotDeviceDataRespVO vo = new IotDeviceDataRespVO();
  34 +// vo.setDeviceId(device.getId());
  35 +// vo.setProductKey(device.getProductKey());
  36 +// vo.setDeviceName(device.getDeviceName());
  37 +// vo.setIdentifier(identifier);
  38 +//// vo.setName(property.getName());
  39 +//// vo.setDataType(property.getDataType().getType());
  40 +// vo.setUpdateTime(device.getUpdateTime());
  41 +// vo.setValue(value.toString());
  42 +// list.add(vo);
  43 +// });
  44 +// return list;
  45 +// }
  46 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.dataobject.device;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
  4 +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.AllArgsConstructor;
  8 +import lombok.Builder;
  9 +import lombok.Data;
  10 +import lombok.NoArgsConstructor;
  11 +
  12 +import java.math.BigDecimal;
  13 +import java.time.LocalDateTime;
  14 +
  15 +/**
  16 + * IoT 设备数据 DO
  17 + *
  18 + * @author haohao
  19 + */
  20 +@Data
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class IotDeviceDataDO {
  25 +
  26 + /**
  27 + * 设备编号
  28 + */
  29 + private Long deviceId;
  30 +
  31 + /**
  32 + * 物模型编号
  33 + */
  34 + private Long thinkModelFunctionId;
  35 +
  36 + /**
  37 + * 产品标识
  38 + */
  39 + private String productKey;
  40 +
  41 + /**
  42 + * 设备名称
  43 + */
  44 + private String deviceName;
  45 +
  46 + /**
  47 + * 属性标识符
  48 + */
  49 + private String identifier;
  50 +
  51 + /**
  52 + * 属性名称
  53 + */
  54 + private String name;
  55 +
  56 + /**
  57 + * 数据类型
  58 + */
  59 + private String dataType;
  60 +
  61 + /**
  62 + * 更新时间
  63 + */
  64 + private LocalDateTime updateTime;
  65 +
  66 + /**
  67 + * 最新值
  68 + */
  69 + private String value;
  70 +
  71 +}
0 72 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.mysql.device;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.redis;
  2 +
  3 +
  4 +
  5 +/**
  6 + * Iot Redis Key 枚举类
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public interface RedisKeyConstants {
  11 +
  12 + /**
  13 + * 设备属性数据缓存
  14 + * <p>
  15 + * KEY 格式:device_property_data:{deviceId}
  16 + * VALUE 数据类型:String 设备属性数据
  17 + */
  18 + String DEVICE_PROPERTY_DATA = "device_property_data:%s_%s_%s";
  19 +
  20 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/deviceData/DeviceDataRedisDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.redis.deviceData;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
  6 +import jakarta.annotation.Resource;
  7 +import org.springframework.data.redis.core.StringRedisTemplate;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +import java.util.concurrent.TimeUnit;
  13 +
  14 +import static cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants.DEVICE_PROPERTY_DATA;
  15 +
  16 +/**
  17 + * {@link IotDeviceDataDO} 的 Redis DAO
  18 + */
  19 +@Repository
  20 +public class DeviceDataRedisDAO {
  21 +
  22 + @Resource
  23 + private StringRedisTemplate stringRedisTemplate;
  24 +
  25 + public IotDeviceDataDO get(String productKey, String deviceName, String identifier) {
  26 + String redisKey = formatKey(productKey, deviceName, identifier);
  27 + return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), IotDeviceDataDO.class);
  28 + }
  29 +
  30 + public void set(IotDeviceDataDO deviceData) {
  31 + String redisKey = formatKey(deviceData.getProductKey(), deviceData.getDeviceName(), deviceData.getIdentifier());
  32 + stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(deviceData));
  33 + }
  34 +
  35 + public void delete(String productKey, String deviceName, String identifier) {
  36 + String redisKey = formatKey(productKey, deviceName, identifier);
  37 + stringRedisTemplate.delete(redisKey);
  38 + }
  39 +
  40 + private static String formatKey(String productKey, String deviceName, String identifier) {
  41 + return String.format(DEVICE_PROPERTY_DATA, productKey, deviceName, identifier);
  42 + }
  43 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
1 1 package cn.iocoder.yudao.module.iot.service.device;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
6   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
8 5 import jakarta.validation.Valid;
9 6  
  7 +import java.util.List;
  8 +
10 9 /**
11 10 * IoT 设备数据 Service 接口
12 11 *
... ... @@ -23,4 +22,12 @@ public interface IotDeviceDataService {
23 22 * @param message 消息
24 23 */
25 24 void saveDeviceData(String productKey, String deviceName, String message);
  25 +
  26 + /**
  27 + * 获得设备属性最新数据
  28 + *
  29 + * @param deviceId 设备编号
  30 + * @return 设备属性最新数据
  31 + */
  32 + List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceId);
26 33 }
27 34 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java
1 1 package cn.iocoder.yudao.module.iot.service.device;
2 2  
3 3 import cn.hutool.json.JSONObject;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
4 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
5 7 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
  8 +import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
  9 +import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
  10 +import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
6 11 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
  12 +import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService;
7 13 import jakarta.annotation.Resource;
  14 +import jakarta.validation.Valid;
8 15 import lombok.extern.slf4j.Slf4j;
9 16 import org.springframework.stereotype.Service;
10 17  
  18 +import java.util.ArrayList;
  19 +import java.util.List;
  20 +
11 21 @Slf4j
12 22 @Service
13 23 public class IotDeviceDataServiceImpl implements IotDeviceDataService {
... ... @@ -16,6 +26,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
16 26 private IotDeviceService deviceService;
17 27 @Resource
18 28 private IotThingModelMessageService thingModelMessageService;
  29 + @Resource
  30 + private IotThinkModelFunctionService thinkModelFunctionService;
  31 +
  32 + @Resource
  33 + private DeviceDataRedisDAO deviceDataRedisDAO;
19 34  
20 35 @Override
21 36 public void saveDeviceData(String productKey, String deviceName, String message) {
... ... @@ -34,6 +49,46 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
34 49 .deviceName(deviceName)
35 50 .deviceKey(device.getDeviceKey())
36 51 .build();
37   - thingModelMessageService.saveThingModelMessage(device,thingModelMessage);
  52 + thingModelMessageService.saveThingModelMessage(device, thingModelMessage);
  53 + }
  54 +
  55 + @Override
  56 + public List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
  57 + List<IotDeviceDataDO> list = new ArrayList<>();
  58 + // 1. 获取设备信息
  59 + IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
  60 + // 2. 获取设备属性最新数据
  61 + List<IotThinkModelFunctionDO> thinkModelFunctionList = thinkModelFunctionService.getThinkModelFunctionListByProductKey(device.getProductKey());
  62 + thinkModelFunctionList = thinkModelFunctionList.stream()
  63 + .filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType()
  64 + .equals(function.getType())).toList();
  65 +
  66 + // 3. 过滤标识符和属性名称
  67 + if (deviceDataReqVO.getIdentifier() != null) {
  68 + thinkModelFunctionList = thinkModelFunctionList.stream()
  69 + .filter(function -> function.getIdentifier().toLowerCase().contains(deviceDataReqVO.getIdentifier().toLowerCase()))
  70 + .toList();
  71 + }
  72 + if (deviceDataReqVO.getName() != null) {
  73 + thinkModelFunctionList = thinkModelFunctionList.stream()
  74 + .filter(function -> function.getName().toLowerCase().contains(deviceDataReqVO.getName().toLowerCase()))
  75 + .toList();
  76 + }
  77 + // 4. 获取设备属性最新数据
  78 + thinkModelFunctionList.forEach(function -> {
  79 + IotDeviceDataDO deviceData = deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName(), function.getIdentifier());
  80 + if (deviceData == null) {
  81 + deviceData = new IotDeviceDataDO();
  82 + deviceData.setProductKey(device.getProductKey());
  83 + deviceData.setDeviceName(device.getDeviceName());
  84 + deviceData.setIdentifier(function.getIdentifier());
  85 + deviceData.setDeviceId(deviceDataReqVO.getDeviceId());
  86 + deviceData.setThinkModelFunctionId(function.getId());
  87 + deviceData.setName(function.getName());
  88 + deviceData.setDataType(function.getProperty().getDataType().getType());
  89 + }
  90 + list.add(deviceData);
  91 + });
  92 + return list;
38 93 }
39 94 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
1 1 package cn.iocoder.yudao.module.iot.service.device;
2 2  
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
3 6 import jakarta.validation.*;
4   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*;
5 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
6 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 9  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
... ... @@ -5,9 +5,9 @@ import cn.hutool.core.util.StrUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 7 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
8   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
9   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
10   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
  10 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
11 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
12 12 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
13 13 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataServiceImpl.java
1 1 package cn.iocoder.yudao.module.iot.service.tdengine;
2 2  
  3 +import cn.hutool.core.bean.BeanUtil;
3 4 import cn.hutool.core.collection.CollUtil;
4 5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
5 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
6 7 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
7 8 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
8 9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
9   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdRestApi;
10 10 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
11 11 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
12 12 import jakarta.annotation.Resource;
... ... @@ -14,10 +14,7 @@ import lombok.extern.slf4j.Slf4j;
14 14 import org.springframework.beans.factory.annotation.Value;
15 15 import org.springframework.stereotype.Service;
16 16  
17   -import java.util.ArrayList;
18   -import java.util.List;
19   -import java.util.Map;
20   -import java.util.Objects;
  17 +import java.util.*;
21 18 import java.util.stream.Collectors;
22 19  
23 20 @Service
... ... @@ -27,9 +24,6 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
27 24 @Resource
28 25 private IotTdEngineService iotTdEngineService;
29 26  
30   - @Resource
31   - private TdRestApi tdRestApi;
32   -
33 27 @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
34 28 private String url;
35 29  
... ... @@ -37,39 +31,25 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
37 31 public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
38 32 // 1. 解析物模型,获得字段列表
39 33 List<TdFieldDO> schemaFields = new ArrayList<>();
40   - schemaFields.add(TdFieldDO.builder().
41   - fieldName("time").
42   - dataType("TIMESTAMP").
43   - build());
  34 + schemaFields.add(TdFieldDO.builder()
  35 + .fieldName("time")
  36 + .dataType("TIMESTAMP")
  37 + .build());
44 38 schemaFields.addAll(FieldParser.parse(thingModel));
45 39  
46 40 // 3. 设置超级表的标签
47   - List<TdFieldDO> tagsFields = new ArrayList<>();
48   - tagsFields.add(TdFieldDO.builder().
49   - fieldName("product_key").
50   - dataType("NCHAR").
51   - dataLength(64).
52   - build());
53   - tagsFields.add(TdFieldDO.builder().
54   - fieldName("device_key").
55   - dataType("NCHAR").
56   - dataLength(64).
57   - build());
58   - tagsFields.add(TdFieldDO.builder().
59   - fieldName("device_name").
60   - dataType("NCHAR").
61   - dataLength(64).
62   - build());
63   - tagsFields.add(TdFieldDO.builder().
64   - fieldName("device_type").
65   - dataType("INT").
66   - build());
  41 + List<TdFieldDO> tagsFields = Arrays.asList(
  42 + TdFieldDO.builder().fieldName("product_key").dataType("NCHAR").dataLength(64).build(),
  43 + TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build(),
  44 + TdFieldDO.builder().fieldName("device_name").dataType("NCHAR").dataLength(64).build(),
  45 + TdFieldDO.builder().fieldName("device_type").dataType("INT").build()
  46 + );
67 47  
68 48 // 4. 获取超级表的名称
69 49 String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
70 50  
71 51 // 5. 创建超级表
72   - String dataBaseName = url.substring(url.lastIndexOf("/") + 1);
  52 + String dataBaseName = getDatabaseName();
73 53 iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
74 54 }
75 55  
... ... @@ -81,7 +61,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
81 61 List<TdFieldDO> newFields = FieldParser.parse(thingModel);
82 62  
83 63 updateTableFields(tbName, oldFields, newFields);
84   - } catch (Throwable e) {
  64 + } catch (Exception e) {
85 65 log.error("更新物模型超级表失败", e);
86 66 }
87 67 }
... ... @@ -90,14 +70,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
90 70 private List<TdFieldDO> getTableFields(String tableName) {
91 71 List<TdFieldDO> fields = new ArrayList<>();
92 72 // 获取超级表的描述信息
93   - List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), tableName);
  73 + List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(getDatabaseName(), tableName);
94 74 if (maps != null) {
95   - // 过滤掉 note 字段为 TAG 的记录
96   - maps = maps.stream().filter(map -> !"TAG".equals(map.get("note"))).toList();
97   - // 过滤掉 time 字段
98   - maps = maps.stream().filter(map -> !"time".equals(map.get("field"))).toList();
  75 + // 过滤掉 note 字段为 TAG 的记录和 time 字段
  76 + List<Map<String, Object>> filteredMaps = maps.stream()
  77 + .filter(map -> !"TAG".equals(map.get("note")))
  78 + .filter(map -> !"time".equals(map.get("field")))
  79 + .toList();
99 80 // 解析字段信息
100   - fields = FieldParser.parse(maps.stream()
  81 + fields = FieldParser.parse(filteredMaps.stream()
101 82 .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
102 83 .collect(Collectors.toList()));
103 84 }
... ... @@ -113,7 +94,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
113 94 // 获取删除字段
114 95 List<TdFieldDO> dropFields = getDropFields(oldFields, newFields);
115 96  
116   - String dataBaseName = url.substring(url.lastIndexOf("/") + 1);
  97 + String dataBaseName = getDatabaseName();
117 98 // 添加新增字段
118 99 if (CollUtil.isNotEmpty(addFields)) {
119 100 iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields);
... ... @@ -131,25 +112,37 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
131 112  
132 113 // 获取新增字段
133 114 private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  115 + Set<String> oldFieldNames = oldFields.stream()
  116 + .map(TdFieldDO::getFieldName)
  117 + .collect(Collectors.toSet());
134 118 return newFields.stream()
135   - .filter(f -> oldFields.stream().noneMatch(old -> old.getFieldName().equals(f.getFieldName())))
  119 + .filter(f -> !oldFieldNames.contains(f.getFieldName()))
136 120 .collect(Collectors.toList());
137 121 }
138 122  
139 123 // 获取修改字段
140 124 private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  125 + Map<String, TdFieldDO> oldFieldMap = oldFields.stream()
  126 + .collect(Collectors.toMap(TdFieldDO::getFieldName, f -> f));
  127 +
141 128 return newFields.stream()
142   - .filter(f -> oldFields.stream().anyMatch(old ->
143   - old.getFieldName().equals(f.getFieldName()) &&
144   - (!old.getDataType().equals(f.getDataType()) || !Objects.equals(old.getDataLength(), f.getDataLength()))))
  129 + .filter(f -> {
  130 + TdFieldDO oldField = oldFieldMap.get(f.getFieldName());
  131 + return oldField != null &&
  132 + (!oldField.getDataType().equals(f.getDataType()) ||
  133 + !Objects.equals(oldField.getDataLength(), f.getDataLength()));
  134 + })
145 135 .collect(Collectors.toList());
146 136 }
147 137  
148 138 // 获取删除字段
149 139 private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  140 + Set<String> newFieldNames = newFields.stream()
  141 + .map(TdFieldDO::getFieldName)
  142 + .collect(Collectors.toSet());
150 143 return oldFields.stream()
151   - .filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()) &&
152   - newFields.stream().noneMatch(n -> n.getFieldName().equals(f.getFieldName())))
  144 + .filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()))
  145 + .filter(f -> !newFieldNames.contains(f.getFieldName()))
153 146 .collect(Collectors.toList());
154 147 }
155 148  
... ... @@ -157,13 +150,13 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
157 150 public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
158 151 ThingModelRespVO thingModel = buildThingModel(product, functionList);
159 152  
160   - if (thingModel.getModel().getProperties().isEmpty()) {
  153 + if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
161 154 log.warn("物模型属性列表为空,不创建超级表");
162 155 return;
163 156 }
164 157  
165 158 String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey());
166   - String dataBaseName = url.substring(url.lastIndexOf("/") + 1);
  159 + String dataBaseName = getDatabaseName();
167 160 Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName);
168 161  
169 162 if (tableExists != null && tableExists > 0) {
... ... @@ -180,7 +173,8 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
180 173  
181 174 ThingModelRespVO.Model model = new ThingModelRespVO.Model();
182 175 List<ThingModelProperty> properties = functionList.stream()
183   - .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(IotProductFunctionTypeEnum.valueOf(function.getType())))
  176 + .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(
  177 + IotProductFunctionTypeEnum.valueOfType(function.getType())))
184 178 .map(this::buildThingModelProperty)
185 179 .collect(Collectors.toList());
186 180  
... ... @@ -191,14 +185,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
191 185 }
192 186  
193 187 private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) {
194   - ThingModelProperty property = new ThingModelProperty();
195   - property.setIdentifier(function.getIdentifier());
196   - property.setName(function.getName());
197   - property.setDescription(function.getDescription());
  188 + ThingModelProperty property = BeanUtil.copyProperties(function, ThingModelProperty.class);
198 189 property.setDataType(function.getProperty().getDataType());
199 190 return property;
200 191 }
201 192  
  193 + private String getDatabaseName() {
  194 + return url.substring(url.lastIndexOf("/") + 1);
  195 + }
  196 +
202 197 static String getProductPropertySTableName(Integer deviceType, String productKey) {
203 198 return switch (deviceType) {
204 199 case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
... ... @@ -207,7 +202,4 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
207 202 };
208 203 }
209 204  
210   - static String getDevicePropertyTableName(String deviceType, String productKey, String deviceKey) {
211   - return String.format("%s_%s_%s", deviceType, productKey, deviceKey).toLowerCase();
212   - }
213 205 }
214 206 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
1 1 package cn.iocoder.yudao.module.iot.service.tdengine;
2 2  
  3 +import cn.hutool.core.date.DateUtil;
3 4 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
4   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
5 6 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
6 8 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
7 9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
8 10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
9 11 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
10 12 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
  13 +import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
11 14 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
12 15 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
13 16 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
... ... @@ -17,9 +20,7 @@ import lombok.extern.slf4j.Slf4j;
17 20 import org.springframework.beans.factory.annotation.Value;
18 21 import org.springframework.stereotype.Service;
19 22  
20   -import java.util.ArrayList;
21   -import java.util.List;
22   -import java.util.Map;
  23 +import java.util.*;
23 24 import java.util.stream.Collectors;
24 25  
25 26 @Slf4j
... ... @@ -36,11 +37,14 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
36 37 @Resource
37 38 private IotTdEngineService iotTdEngineService;
38 39  
  40 + @Resource
  41 + private DeviceDataRedisDAO deviceDataRedisDAO;
  42 +
39 43 @Override
40 44 @TenantIgnore
41 45 public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) {
42 46 // 判断设备状态,如果为未激活状态,创建数据表
43   - if (device.getStatus().equals(0)) {
  47 + if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) {
44 48 // 创建设备数据表
45 49 createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
46 50 // 更新设备状态
... ... @@ -50,53 +54,99 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
50 54 iotDeviceService.updateDeviceStatus(updateReqVO);
51 55 }
52 56  
53   - // 1. 获取设备属性
  57 + // 获取设备属性
54 58 Map<String, Object> params = thingModelMessage.dataToMap();
55 59  
56   - // 2. 物模型校验,过滤非物模型属性
57   - List<IotThinkModelFunctionDO> thinkModelFunctionListByProductKey = iotThinkModelFunctionService.getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey());
  60 + // 物模型校验,过滤非物模型属性
  61 + List<IotThinkModelFunctionDO> functionList = iotThinkModelFunctionService
  62 + .getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey())
  63 + .stream()
  64 + .filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType().equals(function.getType()))
  65 + .toList();
58 66  
59   - // 2.1 筛选是属性 IotProductFunctionTypeEnum
60   - thinkModelFunctionListByProductKey.removeIf(iotThinkModelFunctionDO -> !iotThinkModelFunctionDO.getType().equals(IotProductFunctionTypeEnum.PROPERTY.getType()));
61   - if (thinkModelFunctionListByProductKey.isEmpty()) {
  67 + if (functionList.isEmpty()) {
62 68 return;
63 69 }
64   - // 2.2 获取属性名称
65   - Map<String, String> thingModelProperties = thinkModelFunctionListByProductKey.stream().collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, IotThinkModelFunctionDO::getName));
66 70  
67   - // 4. 保存属性记录
68   - List<TdFieldDO> schemaFieldValues = new ArrayList<>();
  71 + // 获取属性标识符集合
  72 + Set<String> propertyIdentifiers = functionList.stream()
  73 + .map(IotThinkModelFunctionDO::getIdentifier)
  74 + .collect(Collectors.toSet());
69 75  
70   - // 1. 设置字段名
71   - schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime()));
  76 + Map<String, IotThinkModelFunctionDO> functionMap = functionList.stream()
  77 + .collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, function -> function));
72 78  
73   - // 2. 遍历新属性
  79 + // 过滤并收集有效的属性字段
  80 + List<TdFieldDO> schemaFieldValues = new ArrayList<>();
  81 + schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime()));
74 82 params.forEach((key, val) -> {
75   - if (thingModelProperties.containsKey(key)) {
  83 + if (propertyIdentifiers.contains(key)) {
76 84 schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val));
  85 + // 缓存设备属性
  86 + setDeviceDataCache(device, functionMap.get(key), val, thingModelMessage.getTime());
77 87 }
78 88 });
  89 + if (schemaFieldValues.size() == 1) {
  90 + return;
  91 + }
79 92  
80   - // 3. 保存设备属性
  93 + // 构建并保存设备属性
81 94 TableDO tableData = new TableDO();
82   - tableData.setDataBaseName(url.substring(url.lastIndexOf("/") + 1));
  95 + tableData.setDataBaseName(getDatabaseName());
83 96 tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey()));
84   - tableData.setTableName("device_" + device.getProductKey().toLowerCase() + "_" + device.getDeviceName().toLowerCase());
  97 + tableData.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
85 98 tableData.setSchemaFieldValues(schemaFieldValues);
86 99  
87   - // 4. 保存数据
88 100 iotTdEngineService.insertData(tableData);
89 101 }
90 102  
  103 + /**
  104 + * 缓存设备属性
  105 + *
  106 + * @param device 设备信息
  107 + * @param iotThinkModelFunctionDO 物模型属性
  108 + * @param val 属性值
  109 + * @param time 时间
  110 + */
  111 + private void setDeviceDataCache(IotDeviceDO device, IotThinkModelFunctionDO iotThinkModelFunctionDO, Object val, Long time) {
  112 + IotDeviceDataDO deviceData = IotDeviceDataDO.builder()
  113 + .productKey(device.getProductKey())
  114 + .deviceName(device.getDeviceName())
  115 + .identifier(iotThinkModelFunctionDO.getIdentifier())
  116 + .value(val != null ? val.toString() : null)
  117 + .updateTime(DateUtil.toLocalDateTime(new Date(time)))
  118 + .deviceId(device.getId())
  119 + .thinkModelFunctionId(iotThinkModelFunctionDO.getId())
  120 + .name(iotThinkModelFunctionDO.getName())
  121 + .dataType(iotThinkModelFunctionDO.getProperty().getDataType().getType())
  122 + .build();
  123 + deviceDataRedisDAO.set(deviceData);
  124 + }
  125 +
  126 + /**
  127 + * 创建设备数据表
  128 + *
  129 + * @param deviceType 设备类型
  130 + * @param productKey 产品 Key
  131 + * @param deviceName 设备名称
  132 + * @param deviceKey 设备 Key
  133 + */
91 134 private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) {
  135 + String superTableName = getProductPropertySTableName(deviceType, productKey);
  136 + String dataBaseName = getDatabaseName();
  137 +
  138 + List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(dataBaseName, superTableName);
92 139 List<TdFieldDO> tagsFieldValues = new ArrayList<>();
93   - String SuperTableName = getProductPropertySTableName(deviceType, productKey);
94   - List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), SuperTableName);
  140 +
95 141 if (maps != null) {
96   - List<Map<String, Object>> taggedNotesList = maps.stream().filter(map -> "TAG".equals(map.get("note"))).toList();
  142 + List<Map<String, Object>> taggedNotesList = maps.stream()
  143 + .filter(map -> "TAG".equals(map.get("note")))
  144 + .toList();
  145 +
97 146 tagsFieldValues = FieldParser.parse(taggedNotesList.stream()
98 147 .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
99 148 .collect(Collectors.toList()));
  149 +
100 150 for (TdFieldDO tagsFieldValue : tagsFieldValues) {
101 151 switch (tagsFieldValue.getFieldName()) {
102 152 case "product_key" -> tagsFieldValue.setFieldValue(productKey);
... ... @@ -107,21 +157,49 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
107 157 }
108 158 }
109 159  
110   - // 1. 创建设备数据表
111   - String tableName = "device_" + productKey.toLowerCase() + "_" + deviceName.toLowerCase();
  160 + // 创建设备数据表
  161 + String tableName = getDeviceTableName(productKey, deviceName);
112 162 TableDO tableDto = new TableDO();
113   - tableDto.setDataBaseName(url.substring(url.lastIndexOf("/") + 1));
114   - tableDto.setSuperTableName(SuperTableName);
  163 + tableDto.setDataBaseName(dataBaseName);
  164 + tableDto.setSuperTableName(superTableName);
115 165 tableDto.setTableName(tableName);
116 166 tableDto.setTagsFieldValues(tagsFieldValues);
  167 +
117 168 iotTdEngineService.createTable(tableDto);
118 169 }
119 170  
120   - static String getProductPropertySTableName(Integer deviceType, String productKey) {
  171 + /**
  172 + * 获取数据库名称
  173 + *
  174 + * @return 数据库名称
  175 + */
  176 + private String getDatabaseName() {
  177 + return url.substring(url.lastIndexOf("/") + 1);
  178 + }
  179 +
  180 + /**
  181 + * 获取产品属性表名
  182 + *
  183 + * @param deviceType 设备类型
  184 + * @param productKey 产品 Key
  185 + * @return 产品属性表名
  186 + */
  187 + private static String getProductPropertySTableName(Integer deviceType, String productKey) {
121 188 return switch (deviceType) {
122 189 case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
123 190 case 2 -> String.format("gateway_%s", productKey).toLowerCase();
124 191 default -> String.format("device_%s", productKey).toLowerCase();
125 192 };
126 193 }
  194 +
  195 + /**
  196 + * 获取设备表名
  197 + *
  198 + * @param productKey 产品 Key
  199 + * @param deviceName 设备名称
  200 + * @return 设备表名
  201 + */
  202 + private static String getDeviceTableName(String productKey, String deviceName) {
  203 + return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase());
  204 + }
127 205 }
128 206 \ No newline at end of file
... ...