Commit 624f5283b3ec89295f3562a068bd009881b1c487
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,7 +30,7 @@ public enum IotProductFunctionTypeEnum implements IntArrayValuable { | ||
| 30 | */ | 30 | */ |
| 31 | private final String description; | 31 | private final String description; |
| 32 | 32 | ||
| 33 | - public static IotProductFunctionTypeEnum valueOf(Integer type) { | 33 | + public static IotProductFunctionTypeEnum valueOfType(Integer type) { |
| 34 | for (IotProductFunctionTypeEnum value : values()) { | 34 | for (IotProductFunctionTypeEnum value : values()) { |
| 35 | if (value.getType().equals(type)) { | 35 | if (value.getType().equals(type)) { |
| 36 | return value; | 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,10 +3,10 @@ package cn.iocoder.yudao.module.iot.controller.admin.device; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 11 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 11 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 12 | import io.swagger.v3.oas.annotations.Operation; | 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 | \ No newline at end of file | 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 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 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 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | 3 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| 4 | import com.alibaba.excel.annotation.ExcelProperty; | 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
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 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | 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 | \ No newline at end of file | 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 | \ No newline at end of file | 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 | \ No newline at end of file | 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,7 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.mysql.device; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 8 | import org.apache.ibatis.annotations.Mapper; | 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 | package cn.iocoder.yudao.module.iot.service.device; | 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 | import jakarta.validation.Valid; | 5 | import jakarta.validation.Valid; |
| 9 | 6 | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 10 | /** | 9 | /** |
| 11 | * IoT 设备数据 Service 接口 | 10 | * IoT 设备数据 Service 接口 |
| 12 | * | 11 | * |
| @@ -23,4 +22,12 @@ public interface IotDeviceDataService { | @@ -23,4 +22,12 @@ public interface IotDeviceDataService { | ||
| 23 | * @param message 消息 | 22 | * @param message 消息 |
| 24 | */ | 23 | */ |
| 25 | void saveDeviceData(String productKey, String deviceName, String message); | 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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.service.device; | 1 | package cn.iocoder.yudao.module.iot.service.device; |
| 2 | 2 | ||
| 3 | import cn.hutool.json.JSONObject; | 3 | import cn.hutool.json.JSONObject; |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO; | ||
| 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | 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 | import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; | 11 | import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; |
| 12 | +import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService; | ||
| 7 | import jakarta.annotation.Resource; | 13 | import jakarta.annotation.Resource; |
| 14 | +import jakarta.validation.Valid; | ||
| 8 | import lombok.extern.slf4j.Slf4j; | 15 | import lombok.extern.slf4j.Slf4j; |
| 9 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| 10 | 17 | ||
| 18 | +import java.util.ArrayList; | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 11 | @Slf4j | 21 | @Slf4j |
| 12 | @Service | 22 | @Service |
| 13 | public class IotDeviceDataServiceImpl implements IotDeviceDataService { | 23 | public class IotDeviceDataServiceImpl implements IotDeviceDataService { |
| @@ -16,6 +26,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { | @@ -16,6 +26,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { | ||
| 16 | private IotDeviceService deviceService; | 26 | private IotDeviceService deviceService; |
| 17 | @Resource | 27 | @Resource |
| 18 | private IotThingModelMessageService thingModelMessageService; | 28 | private IotThingModelMessageService thingModelMessageService; |
| 29 | + @Resource | ||
| 30 | + private IotThinkModelFunctionService thinkModelFunctionService; | ||
| 31 | + | ||
| 32 | + @Resource | ||
| 33 | + private DeviceDataRedisDAO deviceDataRedisDAO; | ||
| 19 | 34 | ||
| 20 | @Override | 35 | @Override |
| 21 | public void saveDeviceData(String productKey, String deviceName, String message) { | 36 | public void saveDeviceData(String productKey, String deviceName, String message) { |
| @@ -34,6 +49,46 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { | @@ -34,6 +49,46 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService { | ||
| 34 | .deviceName(deviceName) | 49 | .deviceName(deviceName) |
| 35 | .deviceKey(device.getDeviceKey()) | 50 | .deviceKey(device.getDeviceKey()) |
| 36 | .build(); | 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 | package cn.iocoder.yudao.module.iot.service.device; | 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 | import jakarta.validation.*; | 6 | import jakarta.validation.*; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 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,9 +5,9 @@ import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 13 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; | 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 | package cn.iocoder.yudao.module.iot.service.tdengine; | 1 | package cn.iocoder.yudao.module.iot.service.tdengine; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.bean.BeanUtil; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 4 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; | 5 | import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; | 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; |
| 9 | -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdRestApi; | ||
| 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; |
| 11 | import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; | 11 | import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; |
| 12 | import jakarta.annotation.Resource; | 12 | import jakarta.annotation.Resource; |
| @@ -14,10 +14,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -14,10 +14,7 @@ import lombok.extern.slf4j.Slf4j; | ||
| 14 | import org.springframework.beans.factory.annotation.Value; | 14 | import org.springframework.beans.factory.annotation.Value; |
| 15 | import org.springframework.stereotype.Service; | 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 | import java.util.stream.Collectors; | 18 | import java.util.stream.Collectors; |
| 22 | 19 | ||
| 23 | @Service | 20 | @Service |
| @@ -27,9 +24,6 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -27,9 +24,6 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 27 | @Resource | 24 | @Resource |
| 28 | private IotTdEngineService iotTdEngineService; | 25 | private IotTdEngineService iotTdEngineService; |
| 29 | 26 | ||
| 30 | - @Resource | ||
| 31 | - private TdRestApi tdRestApi; | ||
| 32 | - | ||
| 33 | @Value("${spring.datasource.dynamic.datasource.tdengine.url}") | 27 | @Value("${spring.datasource.dynamic.datasource.tdengine.url}") |
| 34 | private String url; | 28 | private String url; |
| 35 | 29 | ||
| @@ -37,39 +31,25 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -37,39 +31,25 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 37 | public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) { | 31 | public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) { |
| 38 | // 1. 解析物模型,获得字段列表 | 32 | // 1. 解析物模型,获得字段列表 |
| 39 | List<TdFieldDO> schemaFields = new ArrayList<>(); | 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 | schemaFields.addAll(FieldParser.parse(thingModel)); | 38 | schemaFields.addAll(FieldParser.parse(thingModel)); |
| 45 | 39 | ||
| 46 | // 3. 设置超级表的标签 | 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 | // 4. 获取超级表的名称 | 48 | // 4. 获取超级表的名称 |
| 69 | String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey()); | 49 | String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey()); |
| 70 | 50 | ||
| 71 | // 5. 创建超级表 | 51 | // 5. 创建超级表 |
| 72 | - String dataBaseName = url.substring(url.lastIndexOf("/") + 1); | 52 | + String dataBaseName = getDatabaseName(); |
| 73 | iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName); | 53 | iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName); |
| 74 | } | 54 | } |
| 75 | 55 | ||
| @@ -81,7 +61,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -81,7 +61,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 81 | List<TdFieldDO> newFields = FieldParser.parse(thingModel); | 61 | List<TdFieldDO> newFields = FieldParser.parse(thingModel); |
| 82 | 62 | ||
| 83 | updateTableFields(tbName, oldFields, newFields); | 63 | updateTableFields(tbName, oldFields, newFields); |
| 84 | - } catch (Throwable e) { | 64 | + } catch (Exception e) { |
| 85 | log.error("更新物模型超级表失败", e); | 65 | log.error("更新物模型超级表失败", e); |
| 86 | } | 66 | } |
| 87 | } | 67 | } |
| @@ -90,14 +70,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -90,14 +70,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 90 | private List<TdFieldDO> getTableFields(String tableName) { | 70 | private List<TdFieldDO> getTableFields(String tableName) { |
| 91 | List<TdFieldDO> fields = new ArrayList<>(); | 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 | if (maps != null) { | 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 | .map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) | 82 | .map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) |
| 102 | .collect(Collectors.toList())); | 83 | .collect(Collectors.toList())); |
| 103 | } | 84 | } |
| @@ -113,7 +94,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -113,7 +94,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 113 | // 获取删除字段 | 94 | // 获取删除字段 |
| 114 | List<TdFieldDO> dropFields = getDropFields(oldFields, newFields); | 95 | List<TdFieldDO> dropFields = getDropFields(oldFields, newFields); |
| 115 | 96 | ||
| 116 | - String dataBaseName = url.substring(url.lastIndexOf("/") + 1); | 97 | + String dataBaseName = getDatabaseName(); |
| 117 | // 添加新增字段 | 98 | // 添加新增字段 |
| 118 | if (CollUtil.isNotEmpty(addFields)) { | 99 | if (CollUtil.isNotEmpty(addFields)) { |
| 119 | iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields); | 100 | iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields); |
| @@ -131,25 +112,37 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -131,25 +112,37 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 131 | 112 | ||
| 132 | // 获取新增字段 | 113 | // 获取新增字段 |
| 133 | private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { | 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 | return newFields.stream() | 118 | return newFields.stream() |
| 135 | - .filter(f -> oldFields.stream().noneMatch(old -> old.getFieldName().equals(f.getFieldName()))) | 119 | + .filter(f -> !oldFieldNames.contains(f.getFieldName())) |
| 136 | .collect(Collectors.toList()); | 120 | .collect(Collectors.toList()); |
| 137 | } | 121 | } |
| 138 | 122 | ||
| 139 | // 获取修改字段 | 123 | // 获取修改字段 |
| 140 | private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { | 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 | return newFields.stream() | 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 | .collect(Collectors.toList()); | 135 | .collect(Collectors.toList()); |
| 146 | } | 136 | } |
| 147 | 137 | ||
| 148 | // 获取删除字段 | 138 | // 获取删除字段 |
| 149 | private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { | 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 | return oldFields.stream() | 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 | .collect(Collectors.toList()); | 146 | .collect(Collectors.toList()); |
| 154 | } | 147 | } |
| 155 | 148 | ||
| @@ -157,13 +150,13 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -157,13 +150,13 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 157 | public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) { | 150 | public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) { |
| 158 | ThingModelRespVO thingModel = buildThingModel(product, functionList); | 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 | log.warn("物模型属性列表为空,不创建超级表"); | 154 | log.warn("物模型属性列表为空,不创建超级表"); |
| 162 | return; | 155 | return; |
| 163 | } | 156 | } |
| 164 | 157 | ||
| 165 | String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey()); | 158 | String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey()); |
| 166 | - String dataBaseName = url.substring(url.lastIndexOf("/") + 1); | 159 | + String dataBaseName = getDatabaseName(); |
| 167 | Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName); | 160 | Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName); |
| 168 | 161 | ||
| 169 | if (tableExists != null && tableExists > 0) { | 162 | if (tableExists != null && tableExists > 0) { |
| @@ -180,7 +173,8 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -180,7 +173,8 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 180 | 173 | ||
| 181 | ThingModelRespVO.Model model = new ThingModelRespVO.Model(); | 174 | ThingModelRespVO.Model model = new ThingModelRespVO.Model(); |
| 182 | List<ThingModelProperty> properties = functionList.stream() | 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 | .map(this::buildThingModelProperty) | 178 | .map(this::buildThingModelProperty) |
| 185 | .collect(Collectors.toList()); | 179 | .collect(Collectors.toList()); |
| 186 | 180 | ||
| @@ -191,14 +185,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -191,14 +185,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | ||
| 191 | } | 185 | } |
| 192 | 186 | ||
| 193 | private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) { | 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 | property.setDataType(function.getProperty().getDataType()); | 189 | property.setDataType(function.getProperty().getDataType()); |
| 199 | return property; | 190 | return property; |
| 200 | } | 191 | } |
| 201 | 192 | ||
| 193 | + private String getDatabaseName() { | ||
| 194 | + return url.substring(url.lastIndexOf("/") + 1); | ||
| 195 | + } | ||
| 196 | + | ||
| 202 | static String getProductPropertySTableName(Integer deviceType, String productKey) { | 197 | static String getProductPropertySTableName(Integer deviceType, String productKey) { |
| 203 | return switch (deviceType) { | 198 | return switch (deviceType) { |
| 204 | case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); | 199 | case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); |
| @@ -207,7 +202,4 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService | @@ -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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.service.tdengine; | 1 | package cn.iocoder.yudao.module.iot.service.tdengine; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.date.DateUtil; | ||
| 3 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 7 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; | ||
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO; | 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; |
| 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; |
| 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; |
| 13 | +import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; | ||
| 11 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | 14 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; |
| 12 | import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; | 15 | import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; |
| 13 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 16 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| @@ -17,9 +20,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -17,9 +20,7 @@ import lombok.extern.slf4j.Slf4j; | ||
| 17 | import org.springframework.beans.factory.annotation.Value; | 20 | import org.springframework.beans.factory.annotation.Value; |
| 18 | import org.springframework.stereotype.Service; | 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 | import java.util.stream.Collectors; | 24 | import java.util.stream.Collectors; |
| 24 | 25 | ||
| 25 | @Slf4j | 26 | @Slf4j |
| @@ -36,11 +37,14 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ | @@ -36,11 +37,14 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ | ||
| 36 | @Resource | 37 | @Resource |
| 37 | private IotTdEngineService iotTdEngineService; | 38 | private IotTdEngineService iotTdEngineService; |
| 38 | 39 | ||
| 40 | + @Resource | ||
| 41 | + private DeviceDataRedisDAO deviceDataRedisDAO; | ||
| 42 | + | ||
| 39 | @Override | 43 | @Override |
| 40 | @TenantIgnore | 44 | @TenantIgnore |
| 41 | public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) { | 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 | createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); | 49 | createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); |
| 46 | // 更新设备状态 | 50 | // 更新设备状态 |
| @@ -50,53 +54,99 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ | @@ -50,53 +54,99 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ | ||
| 50 | iotDeviceService.updateDeviceStatus(updateReqVO); | 54 | iotDeviceService.updateDeviceStatus(updateReqVO); |
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | - // 1. 获取设备属性 | 57 | + // 获取设备属性 |
| 54 | Map<String, Object> params = thingModelMessage.dataToMap(); | 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 | return; | 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 | params.forEach((key, val) -> { | 82 | params.forEach((key, val) -> { |
| 75 | - if (thingModelProperties.containsKey(key)) { | 83 | + if (propertyIdentifiers.contains(key)) { |
| 76 | schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val)); | 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 | TableDO tableData = new TableDO(); | 94 | TableDO tableData = new TableDO(); |
| 82 | - tableData.setDataBaseName(url.substring(url.lastIndexOf("/") + 1)); | 95 | + tableData.setDataBaseName(getDatabaseName()); |
| 83 | tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey())); | 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 | tableData.setSchemaFieldValues(schemaFieldValues); | 98 | tableData.setSchemaFieldValues(schemaFieldValues); |
| 86 | 99 | ||
| 87 | - // 4. 保存数据 | ||
| 88 | iotTdEngineService.insertData(tableData); | 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 | private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) { | 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 | List<TdFieldDO> tagsFieldValues = new ArrayList<>(); | 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 | if (maps != null) { | 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 | tagsFieldValues = FieldParser.parse(taggedNotesList.stream() | 146 | tagsFieldValues = FieldParser.parse(taggedNotesList.stream() |
| 98 | .map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) | 147 | .map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) |
| 99 | .collect(Collectors.toList())); | 148 | .collect(Collectors.toList())); |
| 149 | + | ||
| 100 | for (TdFieldDO tagsFieldValue : tagsFieldValues) { | 150 | for (TdFieldDO tagsFieldValue : tagsFieldValues) { |
| 101 | switch (tagsFieldValue.getFieldName()) { | 151 | switch (tagsFieldValue.getFieldName()) { |
| 102 | case "product_key" -> tagsFieldValue.setFieldValue(productKey); | 152 | case "product_key" -> tagsFieldValue.setFieldValue(productKey); |
| @@ -107,21 +157,49 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ | @@ -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 | TableDO tableDto = new TableDO(); | 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 | tableDto.setTableName(tableName); | 165 | tableDto.setTableName(tableName); |
| 116 | tableDto.setTagsFieldValues(tagsFieldValues); | 166 | tableDto.setTagsFieldValues(tagsFieldValues); |
| 167 | + | ||
| 117 | iotTdEngineService.createTable(tableDto); | 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 | return switch (deviceType) { | 188 | return switch (deviceType) { |
| 122 | case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); | 189 | case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); |
| 123 | case 2 -> String.format("gateway_%s", productKey).toLowerCase(); | 190 | case 2 -> String.format("gateway_%s", productKey).toLowerCase(); |
| 124 | default -> String.format("device_%s", productKey).toLowerCase(); | 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 | \ No newline at end of file | 206 | \ No newline at end of file |