Commit 862f356cb8c81def23309b3e0ddb6c022f8a9e3a

Authored by YunaiV
1 parent e476dcb2

feat:【IoT 物联网】获取设备属性时,即使没有值,也进行返回,和 aliyun 保持一致

Showing 10 changed files with 79 additions and 33 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDevicePropertyController.java
1 1 package cn.iocoder.yudao.module.iot.controller.admin.device;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.hutool.core.date.LocalDateTimeUtil;
5 4 import cn.hutool.core.lang.Assert;
6 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryListReqVO;
8   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
  9 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
9 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
10 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
11 12 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
  13 +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
12 14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
13 15 import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService;
14 16 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
... ... @@ -47,24 +49,32 @@ public class IotDevicePropertyController {
47 49 @Operation(summary = "获取设备属性最新属性")
48 50 @Parameter(name = "deviceId", description = "设备编号", required = true)
49 51 @PreAuthorize("@ss.hasPermission('iot:device:property-query')")
50   - public CommonResult<List<IotDevicePropertyRespVO>> getLatestDeviceProperties(
  52 + public CommonResult<List<IotDevicePropertyDetailRespVO>> getLatestDeviceProperties(
51 53 @RequestParam("deviceId") Long deviceId) {
52   - Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId);
53   -
54   - // 拼接数据
  54 + // 1.1 获取设备信息
55 55 IotDeviceDO device = deviceService.getDevice(deviceId);
56 56 Assert.notNull(device, "设备不存在");
57   - List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(device.getProductId());
58   - return success(convertList(properties.entrySet(), entry -> {
59   - IotThingModelDO thingModel = CollUtil.findOne(thingModels,
60   - item -> item.getIdentifier().equals(entry.getKey()));
61   - if (thingModel == null || thingModel.getProperty() == null) {
62   - return null;
  57 + // 1.2 获取设备最新属性
  58 + Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId);
  59 + // 1.3 根据 productId + type 查询属性类型的物模型
  60 + List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductIdAndType(
  61 + device.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
  62 +
  63 + // 2. 基于 thingModels 遍历,拼接 properties
  64 + return success(convertList(thingModels, thingModel -> {
  65 + ThingModelProperty thingModelProperty = thingModel.getProperty();
  66 + Assert.notNull(thingModelProperty, "属性不能为空");
  67 + IotDevicePropertyDetailRespVO result = new IotDevicePropertyDetailRespVO()
  68 + .setName(thingModel.getName()).setDataType(thingModelProperty.getDataType())
  69 + .setDataSpecs(thingModelProperty.getDataSpecs())
  70 + .setDataSpecsList(thingModelProperty.getDataSpecsList());
  71 + result.setIdentifier(thingModel.getIdentifier());
  72 + IotDevicePropertyDO property = properties.get(thingModel.getIdentifier());
  73 + if (property != null) {
  74 + result.setValue(property.getValue())
  75 + .setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
63 76 }
64   - // 构建对象
65   - IotDevicePropertyDO property = entry.getValue();
66   - return new IotDevicePropertyRespVO().setProperty(thingModel.getProperty())
67   - .setValue(property.getValue()).setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
  77 + return result;
68 78 }));
69 79 }
70 80  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
  2 +
  3 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - IoT 设备属性详细 Response VO") // 额外增加 来自 ThingModelProperty 的变量 属性
  10 +@Data
  11 +public class IotDevicePropertyDetailRespVO extends IotDevicePropertyRespVO {
  12 +
  13 + @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
  14 + private String name;
  15 +
  16 + @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int")
  17 + private String dataType;
  18 +
  19 + @Schema(description = "数据定义")
  20 + private ThingModelDataSpecs dataSpecs;
  21 +
  22 + @Schema(description = "数据定义列表")
  23 + private List<ThingModelDataSpecs> dataSpecsList;
  24 +
  25 +}
0 26 \ 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/data/IotDevicePropertyHistoryListReqVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyHistoryListReqVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import jakarta.validation.constraints.NotEmpty;
... ... @@ -28,4 +28,4 @@ public class IotDevicePropertyHistoryListReqVO {
28 28 @Size(min = 2, max = 2, message = "请选择时间范围")
29 29 private LocalDateTime[] times;
30 30  
31   -}
32 31 \ No newline at end of file
  32 +}
33 33 \ 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/data/IotDevicePropertyRespVO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyRespVO.java
1   -package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
  1 +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
2 2  
3   -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
4 3 import io.swagger.v3.oas.annotations.media.Schema;
5 4 import lombok.Data;
6 5  
... ... @@ -8,10 +7,10 @@ import lombok.Data;
8 7 @Data
9 8 public class IotDevicePropertyRespVO {
10 9  
11   - @Schema(description = "属性定义", requiredMode = Schema.RequiredMode.REQUIRED)
12   - private ThingModelProperty property;
  10 + @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
  11 + private String identifier;
13 12  
14   - @Schema(description = "最新值", requiredMode = Schema.RequiredMode.REQUIRED)
  13 + @Schema(description = "属性值", requiredMode = Schema.RequiredMode.REQUIRED)
15 14 private Object value;
16 15  
17 16 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java
... ... @@ -3,13 +3,12 @@ package cn.iocoder.yudao.module.iot.dal.tdengine;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
6   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryListReqVO;
7   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
9 9 import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
10 10 import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS;
11 11 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
12   -import com.baomidou.mybatisplus.core.metadata.IPage;
13 12 import org.apache.ibatis.annotations.Mapper;
14 13 import org.apache.ibatis.annotations.Param;
15 14  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyService.java
1 1 package cn.iocoder.yudao.module.iot.service.device.property;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryListReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
  3 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
6 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 6 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
8 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java
... ... @@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.date.LocalDateTimeUtil;
5 5 import cn.hutool.core.map.MapUtil;
6 6 import cn.hutool.core.util.StrUtil;
7   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryListReqVO;
8   -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
9 9 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
10 10 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
11 11 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
... ... @@ -55,6 +55,15 @@ public interface IotThingModelService {
55 55 List<IotThingModelDO> getThingModelListByProductId(Long productId);
56 56  
57 57 /**
  58 + * 获得产品物模型列表
  59 + *
  60 + * @param productId 产品编号
  61 + * @param type 物模型类型
  62 + * @return 产品物模型列表
  63 + */
  64 + List<IotThingModelDO> getThingModelListByProductIdAndType(Long productId, Integer type);
  65 +
  66 + /**
58 67 * 【缓存】获得产品物模型列表
59 68 *
60 69 * 注意:该方法会忽略租户信息,所以调用时,需要确认会不会有跨租户访问的风险!!!
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
... ... @@ -132,6 +132,11 @@ public class IotThingModelServiceImpl implements IotThingModelService {
132 132 }
133 133  
134 134 @Override
  135 + public List<IotThingModelDO> getThingModelListByProductIdAndType(Long productId, Integer type) {
  136 + return thingModelMapper.selectListByProductIdAndType(productId, type);
  137 + }
  138 +
  139 + @Override
135 140 @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId")
136 141 @TenantIgnore // 忽略租户信息,跨租户 productKey 是唯一的
137 142 public List<IotThingModelDO> getThingModelListByProductIdFromCache(Long productId) {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml
... ... @@ -67,7 +67,7 @@
67 67 </select>
68 68  
69 69 <select id="selectListByHistory"
70   - resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO">
  70 + resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO">
71 71 SELECT ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} AS `value`, ts AS update_time
72 72 FROM device_property_${reqVO.deviceId}
73 73 WHERE ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} IS NOT NULL
... ...