Commit 862f356cb8c81def23309b3e0ddb6c022f8a9e3a
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 | package cn.iocoder.yudao.module.iot.controller.admin.device; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.device; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.date.LocalDateTimeUtil; | 3 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 5 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 13 | +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | ||
| 12 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 14 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 13 | import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService; | 15 | import cn.iocoder.yudao.module.iot.service.device.property.IotDevicePropertyService; |
| 14 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; | 16 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; |
| @@ -47,24 +49,32 @@ public class IotDevicePropertyController { | @@ -47,24 +49,32 @@ public class IotDevicePropertyController { | ||
| 47 | @Operation(summary = "获取设备属性最新属性") | 49 | @Operation(summary = "获取设备属性最新属性") |
| 48 | @Parameter(name = "deviceId", description = "设备编号", required = true) | 50 | @Parameter(name = "deviceId", description = "设备编号", required = true) |
| 49 | @PreAuthorize("@ss.hasPermission('iot:device:property-query')") | 51 | @PreAuthorize("@ss.hasPermission('iot:device:property-query')") |
| 50 | - public CommonResult<List<IotDevicePropertyRespVO>> getLatestDeviceProperties( | 52 | + public CommonResult<List<IotDevicePropertyDetailRespVO>> getLatestDeviceProperties( |
| 51 | @RequestParam("deviceId") Long deviceId) { | 53 | @RequestParam("deviceId") Long deviceId) { |
| 52 | - Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(deviceId); | ||
| 53 | - | ||
| 54 | - // 拼接数据 | 54 | + // 1.1 获取设备信息 |
| 55 | IotDeviceDO device = deviceService.getDevice(deviceId); | 55 | IotDeviceDO device = deviceService.getDevice(deviceId); |
| 56 | Assert.notNull(device, "设备不存在"); | 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 | \ No newline at end of file | 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 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import jakarta.validation.constraints.NotEmpty; | 4 | import jakarta.validation.constraints.NotEmpty; |
| @@ -28,4 +28,4 @@ public class IotDevicePropertyHistoryListReqVO { | @@ -28,4 +28,4 @@ public class IotDevicePropertyHistoryListReqVO { | ||
| 28 | @Size(min = 2, max = 2, message = "请选择时间范围") | 28 | @Size(min = 2, max = 2, message = "请选择时间范围") |
| 29 | private LocalDateTime[] times; | 29 | private LocalDateTime[] times; |
| 30 | 30 | ||
| 31 | -} | ||
| 32 | \ No newline at end of file | 31 | \ No newline at end of file |
| 32 | +} | ||
| 33 | \ No newline at end of file | 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 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | 5 | ||
| @@ -8,10 +7,10 @@ import lombok.Data; | @@ -8,10 +7,10 @@ import lombok.Data; | ||
| 8 | @Data | 7 | @Data |
| 9 | public class IotDevicePropertyRespVO { | 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 | private Object value; | 14 | private Object value; |
| 16 | 15 | ||
| 17 | @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) | 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,13 +3,12 @@ package cn.iocoder.yudao.module.iot.dal.tdengine; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 9 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; | 9 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; |
| 10 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; | 10 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; |
| 11 | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | 11 | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| 12 | -import com.baomidou.mybatisplus.core.metadata.IPage; | ||
| 13 | import org.apache.ibatis.annotations.Mapper; | 12 | import org.apache.ibatis.annotations.Mapper; |
| 14 | import org.apache.ibatis.annotations.Param; | 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 | package cn.iocoder.yudao.module.iot.service.device.property; | 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 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 5 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 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,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.date.LocalDateTimeUtil; | 4 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 5 | import cn.hutool.core.map.MapUtil; | 5 | import cn.hutool.core.map.MapUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 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 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; | 9 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; |
| 10 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 10 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 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,6 +55,15 @@ public interface IotThingModelService { | ||
| 55 | List<IotThingModelDO> getThingModelListByProductId(Long productId); | 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,6 +132,11 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | @Override | 134 | @Override |
| 135 | + public List<IotThingModelDO> getThingModelListByProductIdAndType(Long productId, Integer type) { | ||
| 136 | + return thingModelMapper.selectListByProductIdAndType(productId, type); | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + @Override | ||
| 135 | @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") | 140 | @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") |
| 136 | @TenantIgnore // 忽略租户信息,跨租户 productKey 是唯一的 | 141 | @TenantIgnore // 忽略租户信息,跨租户 productKey 是唯一的 |
| 137 | public List<IotThingModelDO> getThingModelListByProductIdFromCache(Long productId) { | 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,7 +67,7 @@ | ||
| 67 | </select> | 67 | </select> |
| 68 | 68 | ||
| 69 | <select id="selectListByHistory" | 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 | SELECT ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} AS `value`, ts AS update_time | 71 | SELECT ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} AS `value`, ts AS update_time |
| 72 | FROM device_property_${reqVO.deviceId} | 72 | FROM device_property_${reqVO.deviceId} |
| 73 | WHERE ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} IS NOT NULL | 73 | WHERE ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} IS NOT NULL |