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

This commit is contained in:
安浩浩 2024-11-03 00:16:46 +08:00
parent 3dafd31da6
commit 624f5283b3
20 changed files with 523 additions and 108 deletions

View File

@ -30,7 +30,7 @@ public enum IotProductFunctionTypeEnum implements IntArrayValuable {
*/ */
private final String description; private final String description;
public static IotProductFunctionTypeEnum valueOf(Integer type) { public static IotProductFunctionTypeEnum valueOfType(Integer type) {
for (IotProductFunctionTypeEnum value : values()) { for (IotProductFunctionTypeEnum value : values()) {
if (value.getType().equals(type)) { if (value.getType().equals(type)) {
return value; return value;

View File

@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.iot.controller.admin.device;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.iot.controller.admin.device;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT 设备数据")
@RestController
@RequestMapping("/iot/device/data")
@Validated
public class IotDeviceDataController {
@Resource
private IotDeviceDataService deviceDataService;
@GetMapping("/latest-data")
@Operation(summary = "获取设备属性最新数据")
public CommonResult<List<IotDeviceDataRespVO>> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
List<IotDeviceDataDO> list = deviceDataService.getDevicePropertiesLatestData(deviceDataReqVO);
return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo; package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.InEnum;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo; package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo; package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo; package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device;
import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 设备数据 Request VO")
@Data
public class IotDeviceDataReqVO {
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
private Long deviceId;
@Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
private String identifier;
@Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
}

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 设备数据 Response VO")
@Data
public class IotDeviceDataRespVO {
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
private Long deviceId;
@Schema(description = "物模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
private Long thinkModelFunctionId;
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
private String productKey;
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
private String deviceName;
@Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
private String identifier;
@Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
@Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED)
private String dataType;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
@Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
private String value;
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.iot.convert.device;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThinkModelFunctionSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Mapper
public interface IotDeviceDataConvert {
IotDeviceDataConvert INSTANCE = Mappers.getMapper(IotDeviceDataConvert.class);
// default List<IotDeviceDataRespVO> convert(Map<String, Object> deviceData, IotDeviceDO device){
// List<IotDeviceDataRespVO> list = new ArrayList<>();
// deviceData.forEach((identifier, value) -> {
//// ThingModelProperty property = ThingModelService.INSTANCE.getProperty(device.getProductId(), identifier);
//// if (Objects.isNull(property)) {
//// return;
//// }
// IotDeviceDataRespVO vo = new IotDeviceDataRespVO();
// vo.setDeviceId(device.getId());
// vo.setProductKey(device.getProductKey());
// vo.setDeviceName(device.getDeviceName());
// vo.setIdentifier(identifier);
//// vo.setName(property.getName());
//// vo.setDataType(property.getDataType().getType());
// vo.setUpdateTime(device.getUpdateTime());
// vo.setValue(value.toString());
// list.add(vo);
// });
// return list;
// }
}

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.device;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* IoT 设备数据 DO
*
* @author haohao
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotDeviceDataDO {
/**
* 设备编号
*/
private Long deviceId;
/**
* 物模型编号
*/
private Long thinkModelFunctionId;
/**
* 产品标识
*/
private String productKey;
/**
* 设备名称
*/
private String deviceName;
/**
* 属性标识符
*/
private String identifier;
/**
* 属性名称
*/
private String name;
/**
* 数据类型
*/
private String dataType;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 最新值
*/
private String value;
}

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.mysql.device;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.iot.dal.redis;
/**
* Iot Redis Key 枚举类
*
* @author 芋道源码
*/
public interface RedisKeyConstants {
/**
* 设备属性数据缓存
* <p>
* KEY 格式device_property_data:{deviceId}
* VALUE 数据类型String 设备属性数据
*/
String DEVICE_PROPERTY_DATA = "device_property_data:%s_%s_%s";
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.iot.dal.redis.deviceData;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants.DEVICE_PROPERTY_DATA;
/**
* {@link IotDeviceDataDO} Redis DAO
*/
@Repository
public class DeviceDataRedisDAO {
@Resource
private StringRedisTemplate stringRedisTemplate;
public IotDeviceDataDO get(String productKey, String deviceName, String identifier) {
String redisKey = formatKey(productKey, deviceName, identifier);
return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), IotDeviceDataDO.class);
}
public void set(IotDeviceDataDO deviceData) {
String redisKey = formatKey(deviceData.getProductKey(), deviceData.getDeviceName(), deviceData.getIdentifier());
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(deviceData));
}
public void delete(String productKey, String deviceName, String identifier) {
String redisKey = formatKey(productKey, deviceName, identifier);
stringRedisTemplate.delete(redisKey);
}
private static String formatKey(String productKey, String deviceName, String identifier) {
return String.format(DEVICE_PROPERTY_DATA, productKey, deviceName, identifier);
}
}

View File

@ -1,12 +1,11 @@
package cn.iocoder.yudao.module.iot.service.device; package cn.iocoder.yudao.module.iot.service.device;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List;
/** /**
* IoT 设备数据 Service 接口 * IoT 设备数据 Service 接口
* *
@ -23,4 +22,12 @@ public interface IotDeviceDataService {
* @param message 消息 * @param message 消息
*/ */
void saveDeviceData(String productKey, String deviceName, String message); void saveDeviceData(String productKey, String deviceName, String message);
/**
* 获得设备属性最新数据
*
* @param deviceId 设备编号
* @return 设备属性最新数据
*/
List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceId);
} }

View File

@ -1,13 +1,23 @@
package cn.iocoder.yudao.module.iot.service.device; package cn.iocoder.yudao.module.iot.service.device;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
public class IotDeviceDataServiceImpl implements IotDeviceDataService { public class IotDeviceDataServiceImpl implements IotDeviceDataService {
@ -16,6 +26,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
private IotDeviceService deviceService; private IotDeviceService deviceService;
@Resource @Resource
private IotThingModelMessageService thingModelMessageService; private IotThingModelMessageService thingModelMessageService;
@Resource
private IotThinkModelFunctionService thinkModelFunctionService;
@Resource
private DeviceDataRedisDAO deviceDataRedisDAO;
@Override @Override
public void saveDeviceData(String productKey, String deviceName, String message) { public void saveDeviceData(String productKey, String deviceName, String message) {
@ -34,6 +49,46 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
.deviceName(deviceName) .deviceName(deviceName)
.deviceKey(device.getDeviceKey()) .deviceKey(device.getDeviceKey())
.build(); .build();
thingModelMessageService.saveThingModelMessage(device,thingModelMessage); thingModelMessageService.saveThingModelMessage(device, thingModelMessage);
}
@Override
public List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
List<IotDeviceDataDO> list = new ArrayList<>();
// 1. 获取设备信息
IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
// 2. 获取设备属性最新数据
List<IotThinkModelFunctionDO> thinkModelFunctionList = thinkModelFunctionService.getThinkModelFunctionListByProductKey(device.getProductKey());
thinkModelFunctionList = thinkModelFunctionList.stream()
.filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType()
.equals(function.getType())).toList();
// 3. 过滤标识符和属性名称
if (deviceDataReqVO.getIdentifier() != null) {
thinkModelFunctionList = thinkModelFunctionList.stream()
.filter(function -> function.getIdentifier().toLowerCase().contains(deviceDataReqVO.getIdentifier().toLowerCase()))
.toList();
}
if (deviceDataReqVO.getName() != null) {
thinkModelFunctionList = thinkModelFunctionList.stream()
.filter(function -> function.getName().toLowerCase().contains(deviceDataReqVO.getName().toLowerCase()))
.toList();
}
// 4. 获取设备属性最新数据
thinkModelFunctionList.forEach(function -> {
IotDeviceDataDO deviceData = deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName(), function.getIdentifier());
if (deviceData == null) {
deviceData = new IotDeviceDataDO();
deviceData.setProductKey(device.getProductKey());
deviceData.setDeviceName(device.getDeviceName());
deviceData.setIdentifier(function.getIdentifier());
deviceData.setDeviceId(deviceDataReqVO.getDeviceId());
deviceData.setThinkModelFunctionId(function.getId());
deviceData.setName(function.getName());
deviceData.setDataType(function.getProperty().getDataType().getType());
}
list.add(deviceData);
});
return list;
} }
} }

View File

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.iot.service.device; package cn.iocoder.yudao.module.iot.service.device;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
import jakarta.validation.*; import jakarta.validation.*;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;

View File

@ -5,9 +5,9 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;

View File

@ -1,12 +1,12 @@
package cn.iocoder.yudao.module.iot.service.tdengine; package cn.iocoder.yudao.module.iot.service.tdengine;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO; import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdRestApi;
import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -14,10 +14,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -27,9 +24,6 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
@Resource @Resource
private IotTdEngineService iotTdEngineService; private IotTdEngineService iotTdEngineService;
@Resource
private TdRestApi tdRestApi;
@Value("${spring.datasource.dynamic.datasource.tdengine.url}") @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
private String url; private String url;
@ -37,39 +31,25 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) { public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
// 1. 解析物模型获得字段列表 // 1. 解析物模型获得字段列表
List<TdFieldDO> schemaFields = new ArrayList<>(); List<TdFieldDO> schemaFields = new ArrayList<>();
schemaFields.add(TdFieldDO.builder(). schemaFields.add(TdFieldDO.builder()
fieldName("time"). .fieldName("time")
dataType("TIMESTAMP"). .dataType("TIMESTAMP")
build()); .build());
schemaFields.addAll(FieldParser.parse(thingModel)); schemaFields.addAll(FieldParser.parse(thingModel));
// 3. 设置超级表的标签 // 3. 设置超级表的标签
List<TdFieldDO> tagsFields = new ArrayList<>(); List<TdFieldDO> tagsFields = Arrays.asList(
tagsFields.add(TdFieldDO.builder(). TdFieldDO.builder().fieldName("product_key").dataType("NCHAR").dataLength(64).build(),
fieldName("product_key"). TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build(),
dataType("NCHAR"). TdFieldDO.builder().fieldName("device_name").dataType("NCHAR").dataLength(64).build(),
dataLength(64). TdFieldDO.builder().fieldName("device_type").dataType("INT").build()
build()); );
tagsFields.add(TdFieldDO.builder().
fieldName("device_key").
dataType("NCHAR").
dataLength(64).
build());
tagsFields.add(TdFieldDO.builder().
fieldName("device_name").
dataType("NCHAR").
dataLength(64).
build());
tagsFields.add(TdFieldDO.builder().
fieldName("device_type").
dataType("INT").
build());
// 4. 获取超级表的名称 // 4. 获取超级表的名称
String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey()); String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
// 5. 创建超级表 // 5. 创建超级表
String dataBaseName = url.substring(url.lastIndexOf("/") + 1); String dataBaseName = getDatabaseName();
iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName); iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
} }
@ -81,7 +61,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
List<TdFieldDO> newFields = FieldParser.parse(thingModel); List<TdFieldDO> newFields = FieldParser.parse(thingModel);
updateTableFields(tbName, oldFields, newFields); updateTableFields(tbName, oldFields, newFields);
} catch (Throwable e) { } catch (Exception e) {
log.error("更新物模型超级表失败", e); log.error("更新物模型超级表失败", e);
} }
} }
@ -90,14 +70,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
private List<TdFieldDO> getTableFields(String tableName) { private List<TdFieldDO> getTableFields(String tableName) {
List<TdFieldDO> fields = new ArrayList<>(); List<TdFieldDO> fields = new ArrayList<>();
// 获取超级表的描述信息 // 获取超级表的描述信息
List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), tableName); List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(getDatabaseName(), tableName);
if (maps != null) { if (maps != null) {
// 过滤掉 note 字段为 TAG 的记录 // 过滤掉 note 字段为 TAG 的记录和 time 字段
maps = maps.stream().filter(map -> !"TAG".equals(map.get("note"))).toList(); List<Map<String, Object>> filteredMaps = maps.stream()
// 过滤掉 time 字段 .filter(map -> !"TAG".equals(map.get("note")))
maps = maps.stream().filter(map -> !"time".equals(map.get("field"))).toList(); .filter(map -> !"time".equals(map.get("field")))
.toList();
// 解析字段信息 // 解析字段信息
fields = FieldParser.parse(maps.stream() fields = FieldParser.parse(filteredMaps.stream()
.map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
@ -113,7 +94,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
// 获取删除字段 // 获取删除字段
List<TdFieldDO> dropFields = getDropFields(oldFields, newFields); List<TdFieldDO> dropFields = getDropFields(oldFields, newFields);
String dataBaseName = url.substring(url.lastIndexOf("/") + 1); String dataBaseName = getDatabaseName();
// 添加新增字段 // 添加新增字段
if (CollUtil.isNotEmpty(addFields)) { if (CollUtil.isNotEmpty(addFields)) {
iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields); iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields);
@ -131,25 +112,37 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
// 获取新增字段 // 获取新增字段
private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
Set<String> oldFieldNames = oldFields.stream()
.map(TdFieldDO::getFieldName)
.collect(Collectors.toSet());
return newFields.stream() return newFields.stream()
.filter(f -> oldFields.stream().noneMatch(old -> old.getFieldName().equals(f.getFieldName()))) .filter(f -> !oldFieldNames.contains(f.getFieldName()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
// 获取修改字段 // 获取修改字段
private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
Map<String, TdFieldDO> oldFieldMap = oldFields.stream()
.collect(Collectors.toMap(TdFieldDO::getFieldName, f -> f));
return newFields.stream() return newFields.stream()
.filter(f -> oldFields.stream().anyMatch(old -> .filter(f -> {
old.getFieldName().equals(f.getFieldName()) && TdFieldDO oldField = oldFieldMap.get(f.getFieldName());
(!old.getDataType().equals(f.getDataType()) || !Objects.equals(old.getDataLength(), f.getDataLength())))) return oldField != null &&
(!oldField.getDataType().equals(f.getDataType()) ||
!Objects.equals(oldField.getDataLength(), f.getDataLength()));
})
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
// 获取删除字段 // 获取删除字段
private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) { private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
Set<String> newFieldNames = newFields.stream()
.map(TdFieldDO::getFieldName)
.collect(Collectors.toSet());
return oldFields.stream() return oldFields.stream()
.filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()) && .filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()))
newFields.stream().noneMatch(n -> n.getFieldName().equals(f.getFieldName()))) .filter(f -> !newFieldNames.contains(f.getFieldName()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -157,13 +150,13 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) { public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
ThingModelRespVO thingModel = buildThingModel(product, functionList); ThingModelRespVO thingModel = buildThingModel(product, functionList);
if (thingModel.getModel().getProperties().isEmpty()) { if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
log.warn("物模型属性列表为空,不创建超级表"); log.warn("物模型属性列表为空,不创建超级表");
return; return;
} }
String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey()); String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey());
String dataBaseName = url.substring(url.lastIndexOf("/") + 1); String dataBaseName = getDatabaseName();
Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName); Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName);
if (tableExists != null && tableExists > 0) { if (tableExists != null && tableExists > 0) {
@ -180,7 +173,8 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
ThingModelRespVO.Model model = new ThingModelRespVO.Model(); ThingModelRespVO.Model model = new ThingModelRespVO.Model();
List<ThingModelProperty> properties = functionList.stream() List<ThingModelProperty> properties = functionList.stream()
.filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(IotProductFunctionTypeEnum.valueOf(function.getType()))) .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(
IotProductFunctionTypeEnum.valueOfType(function.getType())))
.map(this::buildThingModelProperty) .map(this::buildThingModelProperty)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -191,14 +185,15 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
} }
private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) { private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) {
ThingModelProperty property = new ThingModelProperty(); ThingModelProperty property = BeanUtil.copyProperties(function, ThingModelProperty.class);
property.setIdentifier(function.getIdentifier());
property.setName(function.getName());
property.setDescription(function.getDescription());
property.setDataType(function.getProperty().getDataType()); property.setDataType(function.getProperty().getDataType());
return property; return property;
} }
private String getDatabaseName() {
return url.substring(url.lastIndexOf("/") + 1);
}
static String getProductPropertySTableName(Integer deviceType, String productKey) { static String getProductPropertySTableName(Integer deviceType, String productKey) {
return switch (deviceType) { return switch (deviceType) {
case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
@ -207,7 +202,4 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
}; };
} }
static String getDevicePropertyTableName(String deviceType, String productKey, String deviceKey) {
return String.format("%s_%s_%s", deviceType, productKey, deviceKey).toLowerCase();
}
} }

View File

@ -1,13 +1,16 @@
package cn.iocoder.yudao.module.iot.service.tdengine; package cn.iocoder.yudao.module.iot.service.tdengine;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum; import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
@ -17,9 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@ -36,11 +37,14 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
@Resource @Resource
private IotTdEngineService iotTdEngineService; private IotTdEngineService iotTdEngineService;
@Resource
private DeviceDataRedisDAO deviceDataRedisDAO;
@Override @Override
@TenantIgnore @TenantIgnore
public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) { public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) {
// 判断设备状态如果为未激活状态创建数据表 // 判断设备状态如果为未激活状态创建数据表
if (device.getStatus().equals(0)) { if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) {
// 创建设备数据表 // 创建设备数据表
createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
// 更新设备状态 // 更新设备状态
@ -50,53 +54,99 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
iotDeviceService.updateDeviceStatus(updateReqVO); iotDeviceService.updateDeviceStatus(updateReqVO);
} }
// 1. 获取设备属性 // 获取设备属性
Map<String, Object> params = thingModelMessage.dataToMap(); Map<String, Object> params = thingModelMessage.dataToMap();
// 2. 物模型校验过滤非物模型属性 // 物模型校验过滤非物模型属性
List<IotThinkModelFunctionDO> thinkModelFunctionListByProductKey = iotThinkModelFunctionService.getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey()); List<IotThinkModelFunctionDO> functionList = iotThinkModelFunctionService
.getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey())
.stream()
.filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType().equals(function.getType()))
.toList();
// 2.1 筛选是属性 IotProductFunctionTypeEnum if (functionList.isEmpty()) {
thinkModelFunctionListByProductKey.removeIf(iotThinkModelFunctionDO -> !iotThinkModelFunctionDO.getType().equals(IotProductFunctionTypeEnum.PROPERTY.getType()));
if (thinkModelFunctionListByProductKey.isEmpty()) {
return; return;
} }
// 2.2 获取属性名称
Map<String, String> thingModelProperties = thinkModelFunctionListByProductKey.stream().collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, IotThinkModelFunctionDO::getName));
// 4. 保存属性记录 // 获取属性标识符集合
Set<String> propertyIdentifiers = functionList.stream()
.map(IotThinkModelFunctionDO::getIdentifier)
.collect(Collectors.toSet());
Map<String, IotThinkModelFunctionDO> functionMap = functionList.stream()
.collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, function -> function));
// 过滤并收集有效的属性字段
List<TdFieldDO> schemaFieldValues = new ArrayList<>(); List<TdFieldDO> schemaFieldValues = new ArrayList<>();
// 1. 设置字段名
schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime())); schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime()));
// 2. 遍历新属性
params.forEach((key, val) -> { params.forEach((key, val) -> {
if (thingModelProperties.containsKey(key)) { if (propertyIdentifiers.contains(key)) {
schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val)); schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val));
// 缓存设备属性
setDeviceDataCache(device, functionMap.get(key), val, thingModelMessage.getTime());
} }
}); });
if (schemaFieldValues.size() == 1) {
return;
}
// 3. 保存设备属性 // 构建并保存设备属性
TableDO tableData = new TableDO(); TableDO tableData = new TableDO();
tableData.setDataBaseName(url.substring(url.lastIndexOf("/") + 1)); tableData.setDataBaseName(getDatabaseName());
tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey())); tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey()));
tableData.setTableName("device_" + device.getProductKey().toLowerCase() + "_" + device.getDeviceName().toLowerCase()); tableData.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
tableData.setSchemaFieldValues(schemaFieldValues); tableData.setSchemaFieldValues(schemaFieldValues);
// 4. 保存数据
iotTdEngineService.insertData(tableData); iotTdEngineService.insertData(tableData);
} }
/**
* 缓存设备属性
*
* @param device 设备信息
* @param iotThinkModelFunctionDO 物模型属性
* @param val 属性值
* @param time 时间
*/
private void setDeviceDataCache(IotDeviceDO device, IotThinkModelFunctionDO iotThinkModelFunctionDO, Object val, Long time) {
IotDeviceDataDO deviceData = IotDeviceDataDO.builder()
.productKey(device.getProductKey())
.deviceName(device.getDeviceName())
.identifier(iotThinkModelFunctionDO.getIdentifier())
.value(val != null ? val.toString() : null)
.updateTime(DateUtil.toLocalDateTime(new Date(time)))
.deviceId(device.getId())
.thinkModelFunctionId(iotThinkModelFunctionDO.getId())
.name(iotThinkModelFunctionDO.getName())
.dataType(iotThinkModelFunctionDO.getProperty().getDataType().getType())
.build();
deviceDataRedisDAO.set(deviceData);
}
/**
* 创建设备数据表
*
* @param deviceType 设备类型
* @param productKey 产品 Key
* @param deviceName 设备名称
* @param deviceKey 设备 Key
*/
private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) { private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) {
String superTableName = getProductPropertySTableName(deviceType, productKey);
String dataBaseName = getDatabaseName();
List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(dataBaseName, superTableName);
List<TdFieldDO> tagsFieldValues = new ArrayList<>(); List<TdFieldDO> tagsFieldValues = new ArrayList<>();
String SuperTableName = getProductPropertySTableName(deviceType, productKey);
List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), SuperTableName);
if (maps != null) { if (maps != null) {
List<Map<String, Object>> taggedNotesList = maps.stream().filter(map -> "TAG".equals(map.get("note"))).toList(); List<Map<String, Object>> taggedNotesList = maps.stream()
.filter(map -> "TAG".equals(map.get("note")))
.toList();
tagsFieldValues = FieldParser.parse(taggedNotesList.stream() tagsFieldValues = FieldParser.parse(taggedNotesList.stream()
.map(map -> List.of(map.get("field"), map.get("type"), map.get("length"))) .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
.collect(Collectors.toList())); .collect(Collectors.toList()));
for (TdFieldDO tagsFieldValue : tagsFieldValues) { for (TdFieldDO tagsFieldValue : tagsFieldValues) {
switch (tagsFieldValue.getFieldName()) { switch (tagsFieldValue.getFieldName()) {
case "product_key" -> tagsFieldValue.setFieldValue(productKey); case "product_key" -> tagsFieldValue.setFieldValue(productKey);
@ -107,21 +157,49 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
} }
} }
// 1. 创建设备数据表 // 创建设备数据表
String tableName = "device_" + productKey.toLowerCase() + "_" + deviceName.toLowerCase(); String tableName = getDeviceTableName(productKey, deviceName);
TableDO tableDto = new TableDO(); TableDO tableDto = new TableDO();
tableDto.setDataBaseName(url.substring(url.lastIndexOf("/") + 1)); tableDto.setDataBaseName(dataBaseName);
tableDto.setSuperTableName(SuperTableName); tableDto.setSuperTableName(superTableName);
tableDto.setTableName(tableName); tableDto.setTableName(tableName);
tableDto.setTagsFieldValues(tagsFieldValues); tableDto.setTagsFieldValues(tagsFieldValues);
iotTdEngineService.createTable(tableDto); iotTdEngineService.createTable(tableDto);
} }
static String getProductPropertySTableName(Integer deviceType, String productKey) { /**
* 获取数据库名称
*
* @return 数据库名称
*/
private String getDatabaseName() {
return url.substring(url.lastIndexOf("/") + 1);
}
/**
* 获取产品属性表名
*
* @param deviceType 设备类型
* @param productKey 产品 Key
* @return 产品属性表名
*/
private static String getProductPropertySTableName(Integer deviceType, String productKey) {
return switch (deviceType) { return switch (deviceType) {
case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase(); case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
case 2 -> String.format("gateway_%s", productKey).toLowerCase(); case 2 -> String.format("gateway_%s", productKey).toLowerCase();
default -> String.format("device_%s", productKey).toLowerCase(); default -> String.format("device_%s", productKey).toLowerCase();
}; };
} }
/**
* 获取设备表名
*
* @param productKey 产品 Key
* @param deviceName 设备名称
* @return 设备表名
*/
private static String getDeviceTableName(String productKey, String deviceName) {
return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase());
}
} }