【功能优化】IoT:部分实现 IotDevicePropertyMessageConsumer,支持缓存的记录(差设备属性的日志记录)
This commit is contained in:
parent
b319485ca6
commit
8e80a53a8b
|
@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.*;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
|
||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService;
|
||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
|
||||
|
@ -28,18 +28,14 @@ public class IotDeviceDataController {
|
|||
|
||||
@Resource
|
||||
private IotDevicePropertyService deviceDataService;
|
||||
|
||||
@Resource
|
||||
private IotDeviceLogService iotDeviceLogDataService;
|
||||
|
||||
@Resource // TODO @super:service 之间,不用空行;原因是,这样更简洁;空行,主要是为了“间隔”,提升可读性
|
||||
private IotDeviceLogService deviceLogDataService;
|
||||
|
||||
// TODO @浩浩:这里的 /latest-list,包括方法名。
|
||||
@GetMapping("/latest")
|
||||
@Operation(summary = "获取设备属性最新数据")
|
||||
public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
|
||||
List<IotDeviceDataDO> list = deviceDataService.getLatestDeviceProperties(deviceDataReqVO);
|
||||
List<IotDevicePropertyDO> list = deviceDataService.getLatestDeviceProperties(deviceDataReqVO);
|
||||
return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
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.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* IoT 设备数据 DO
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDeviceDataDO {
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
* <p>
|
||||
* 关联 {@link IotDeviceDO#getId()}
|
||||
*/
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 物模型编号
|
||||
* <p>
|
||||
* 关联 {@link IotThingModelDO#getId()}
|
||||
*/
|
||||
private Long thingModelId;
|
||||
|
||||
/**
|
||||
* 产品标识
|
||||
* <p>
|
||||
* 关联 {@link IotProductDO#getProductKey()}
|
||||
*/
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
* <p>
|
||||
* 冗余 {@link IotDeviceDO#getDeviceName()}
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 属性标识符
|
||||
* <p>
|
||||
* 关联 {@link IotThingModelDO#getIdentifier()}
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* 属性名称
|
||||
* <p>
|
||||
* 关联 {@link IotThingModelDO#getName()}
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 数据类型
|
||||
* <p>
|
||||
* 关联 {@link IotThingModelDO#getProperty()#getDataType()}
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 最新值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.dataobject.device;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* IoT 设备属性项 Redis DO
|
||||
*
|
||||
* @see cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants#DEVICE_PROPERTY
|
||||
* @see DevicePropertyRedisDAO
|
||||
*
|
||||
* @author haohao
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class IotDevicePropertyDO {
|
||||
|
||||
/**
|
||||
* 属性值(最新)
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.redis;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
|
||||
/**
|
||||
* Iot Redis Key 枚举类
|
||||
|
@ -10,11 +10,20 @@ package cn.iocoder.yudao.module.iot.dal.redis;
|
|||
public interface RedisKeyConstants {
|
||||
|
||||
/**
|
||||
* 设备属性数据缓存
|
||||
* 设备属性数据缓存,采用 HASH 结构
|
||||
* <p>
|
||||
* KEY 格式:device_property_data:{deviceId}
|
||||
* VALUE 数据类型:String 设备属性数据
|
||||
* KEY 格式:device_property:{deviceKey}
|
||||
* HASH KEY:identifier 属性标识
|
||||
* VALUE 数据类型:String(JSON) {@link IotDevicePropertyDO}
|
||||
*/
|
||||
String DEVICE_PROPERTY_DATA = "device_property_data:%s_%s_%s";
|
||||
String DEVICE_PROPERTY = "device_property:%s";
|
||||
|
||||
/**
|
||||
* 设备的最后上报时间,采用 ZSET 结构
|
||||
*
|
||||
* KEY 格式:{deviceKey}
|
||||
* SCORE:上报时间
|
||||
*/
|
||||
String DEVICE_REPORT_TIME = "device_report_time";
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.redis.device;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants.DEVICE_PROPERTY;
|
||||
|
||||
/**
|
||||
* {@link IotDevicePropertyDO} 的 Redis DAO
|
||||
*/
|
||||
@Repository
|
||||
public class DevicePropertyRedisDAO {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
public Map<String, IotDevicePropertyDO> get(String deviceKey) {
|
||||
String redisKey = formatKey(deviceKey);
|
||||
Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(redisKey);
|
||||
if (CollUtil.isEmpty(entries)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return convertMap(entries.values(), key -> (String) key,
|
||||
value -> JsonUtils.parseObject((String) value, IotDevicePropertyDO.class));
|
||||
}
|
||||
|
||||
public void set(String deviceKey, Map<String, IotDevicePropertyDO> properties) {
|
||||
if (CollUtil.isEmpty(properties)) {
|
||||
return;
|
||||
}
|
||||
String redisKey = formatKey(deviceKey);
|
||||
stringRedisTemplate.opsForHash().putAll(redisKey, convertMap(properties.entrySet(),
|
||||
Map.Entry::getKey,
|
||||
entry -> JsonUtils.toJsonString(entry.getValue())));
|
||||
}
|
||||
|
||||
public void delete(String deviceKey) {
|
||||
String redisKey = formatKey(deviceKey);
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
|
||||
private static String formatKey(String deviceKey) {
|
||||
return String.format(DEVICE_PROPERTY, deviceKey);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.iot.dal.redis.device;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 设备的最后上报时间的 Redis DAO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Repository
|
||||
public class DeviceReportTimeRedisDAO {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
public void update(String deviceKey, LocalDateTime reportTime) {
|
||||
stringRedisTemplate.opsForZSet().add(RedisKeyConstants.DEVICE_REPORT_TIME, deviceKey,
|
||||
LocalDateTimeUtil.toEpochMilli(reportTime));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ public interface IotDevicePropertyDataMapper {
|
|||
void alterProductPropertySTableDropField(@Param("productKey") String productKey,
|
||||
@Param("field") TDengineTableField field);
|
||||
|
||||
// TODO @芋艿:待实现
|
||||
/**
|
||||
* 获取历史数据列表
|
||||
*
|
||||
|
|
|
@ -39,7 +39,7 @@ public class EmqxServiceImpl implements EmqxService {
|
|||
// .deviceName(deviceName)
|
||||
// .properties(message) // TODO 芋艿:临时去掉,看看
|
||||
.build();
|
||||
iotDeviceDataService.saveDeviceData(createDTO);
|
||||
// iotDeviceDataService.saveDeviceProperty(createDTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package cn.iocoder.yudao.module.iot.mq.consumer.device;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
|
||||
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
|
||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -24,11 +27,14 @@ public class IotDevicePropertyMessageConsumer {
|
|||
@EventListener
|
||||
@Async
|
||||
public void onMessage(IotDeviceMessage message) {
|
||||
if (ObjectUtil.notEqual(message.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())
|
||||
|| ObjectUtil.notEqual(message.getIdentifier(), IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier())) {
|
||||
return;
|
||||
}
|
||||
log.info("[onMessage][消息内容({})]", message);
|
||||
|
||||
// 设备日志记录
|
||||
// TODO @芋艿:重新写下
|
||||
// deviceLogDataService.createDeviceLog(message);
|
||||
// 保存设备属性
|
||||
deviceDataService.saveDeviceProperty(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ public interface IotDeviceService {
|
|||
*/
|
||||
Long getDeviceCountByGroupId(Long groupId);
|
||||
|
||||
// TODO @芋艿:增加缓存
|
||||
/**
|
||||
* 根据产品 key 和设备名称,获得设备信息
|
||||
*
|
||||
|
|
|
@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
|||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
|
||||
|
@ -247,7 +246,6 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
public IotDeviceDO getDeviceByProductKeyAndDeviceName(String productKey, String deviceName) {
|
||||
return deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package cn.iocoder.yudao.module.iot.service.device.data;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
|
||||
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -27,9 +27,9 @@ public interface IotDevicePropertyService {
|
|||
/**
|
||||
* 保存设备数据
|
||||
*
|
||||
* @param createDTO 设备数据
|
||||
* @param message 设备消息
|
||||
*/
|
||||
void saveDeviceData(IotDevicePropertyReportReqDTO createDTO);
|
||||
void saveDeviceProperty(IotDeviceMessage message);
|
||||
|
||||
/**
|
||||
* 模拟设备
|
||||
|
@ -44,7 +44,7 @@ public interface IotDevicePropertyService {
|
|||
* @param deviceId 设备编号
|
||||
* @return 设备属性最新数据
|
||||
*/
|
||||
List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
|
||||
List<IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
|
||||
|
||||
/**
|
||||
* 获得设备属性历史数据
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
package cn.iocoder.yudao.module.iot.service.device.data;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.iot.api.device.dto.IotDevicePropertyReportReqDTO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO;
|
||||
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
|
||||
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.device.IotDevicePropertyDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
|
||||
import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
|
||||
import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO;
|
||||
import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyDataMapper;
|
||||
import cn.iocoder.yudao.module.iot.enums.IotConstants;
|
||||
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum;
|
||||
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
|
||||
import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
|
||||
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
|
||||
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
|
||||
import cn.iocoder.yudao.module.iot.service.product.IotProductService;
|
||||
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
|
||||
|
@ -31,15 +30,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DATA_CONTENT_JSON_PARSE_ERROR;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +74,7 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
|
|||
private IotProductService productService;
|
||||
|
||||
@Resource
|
||||
private DeviceDataRedisDAO deviceDataRedisDAO;
|
||||
private DevicePropertyRedisDAO deviceDataRedisDAO;
|
||||
|
||||
@Resource
|
||||
private IotDevicePropertyDataMapper devicePropertyDataMapper;
|
||||
|
@ -126,13 +123,41 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void saveDeviceData(IotDevicePropertyReportReqDTO createDTO) {
|
||||
// TODO 芋艿:这块需要实现
|
||||
// 1. 根据产品 key 和设备名称,获得设备信息
|
||||
IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceName(createDTO.getProductKey(), createDTO.getDeviceName());
|
||||
// 2. 解析消息,保存数据
|
||||
JSONObject jsonObject = new JSONObject(createDTO.getProperties());
|
||||
log.info("[saveDeviceData][productKey({}) deviceName({}) data({})]", createDTO.getProductKey(), createDTO.getDeviceName(), jsonObject);
|
||||
public void saveDeviceProperty(IotDeviceMessage message) {
|
||||
if (!(message.getData() instanceof Map)) {
|
||||
log.error("[saveDeviceProperty][消息内容({}) 的 data 类型不正确]", message);
|
||||
return;
|
||||
}
|
||||
// 1. 获得设备信息
|
||||
IotDeviceDO device = TenantUtils.executeIgnore(() ->
|
||||
deviceService.getDeviceByProductKeyAndDeviceName(message.getProductKey(), message.getDeviceName()));
|
||||
if (device == null) {
|
||||
log.error("[saveDeviceProperty][消息({}) 对应的设备不存在]", message);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 根据物模型,拼接合法的属性
|
||||
List<IotThingModelDO> thingModels = TenantUtils.executeIgnore(() ->
|
||||
thingModelService.getThingModelListByProductId(device.getProductId()));
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
((Map<?, ?>) message.getData()).forEach((key, value) -> {
|
||||
if (CollUtil.findOne(thingModels, thingModel -> thingModel.getIdentifier().equals(key)) == null) {
|
||||
log.error("[saveDeviceProperty][消息({}) 的属性({}) 不存在]", message, key);
|
||||
return;
|
||||
}
|
||||
properties.put((String) key, value);
|
||||
});
|
||||
if (CollUtil.isEmpty(properties)) {
|
||||
log.error("[saveDeviceProperty][消息({}) 没有合法的属性]", message);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3.1 保存属性【数据】
|
||||
// TODO 芋艿,未实现
|
||||
|
||||
// 3.2 保存属性【日志】
|
||||
deviceDataRedisDAO.set(message.getDeviceKey(), convertMap(properties.entrySet(), Map.Entry::getKey,
|
||||
entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build()));
|
||||
}
|
||||
|
||||
//TODO @芋艿:copy 了 saveDeviceData 的逻辑,后续看看这块怎么优化
|
||||
|
@ -163,62 +188,64 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
|
||||
List<IotDeviceDataDO> list = new ArrayList<>();
|
||||
// 1. 获取设备信息
|
||||
IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
|
||||
// 2. 获取设备属性最新数据
|
||||
List<IotThingModelDO> thingModelList = thingModelService.getProductThingModelListByProductKey(device.getProductKey());
|
||||
thingModelList = filterList(thingModelList, thingModel -> IotThingModelTypeEnum.PROPERTY.getType()
|
||||
.equals(thingModel.getType()));
|
||||
|
||||
// 3. 过滤标识符和属性名称
|
||||
if (deviceDataReqVO.getIdentifier() != null) {
|
||||
thingModelList = filterList(thingModelList, thingModel -> thingModel.getIdentifier()
|
||||
.toLowerCase().contains(deviceDataReqVO.getIdentifier().toLowerCase()));
|
||||
}
|
||||
if (deviceDataReqVO.getName() != null) {
|
||||
thingModelList = filterList(thingModelList, thingModel -> thingModel.getName()
|
||||
.toLowerCase().contains(deviceDataReqVO.getName().toLowerCase()));
|
||||
}
|
||||
// 4. 获取设备属性最新数据
|
||||
thingModelList.forEach(thingModel -> {
|
||||
IotDeviceDataDO deviceData = deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName(), thingModel.getIdentifier());
|
||||
if (deviceData == null) {
|
||||
deviceData = new IotDeviceDataDO();
|
||||
deviceData.setProductKey(device.getProductKey());
|
||||
deviceData.setDeviceName(device.getDeviceName());
|
||||
deviceData.setIdentifier(thingModel.getIdentifier());
|
||||
deviceData.setDeviceId(deviceDataReqVO.getDeviceId());
|
||||
deviceData.setThingModelId(thingModel.getId());
|
||||
deviceData.setName(thingModel.getName());
|
||||
deviceData.setDataType(thingModel.getProperty().getDataType());
|
||||
}
|
||||
list.add(deviceData);
|
||||
});
|
||||
return list;
|
||||
public List<IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
|
||||
// List<IotDevicePropertyDO> list = new ArrayList<>();
|
||||
// // 1. 获取设备信息
|
||||
// IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
|
||||
// // 2. 获取设备属性最新数据
|
||||
// List<IotThingModelDO> thingModelList = thingModelService.getProductThingModelListByProductKey(device.getProductKey());
|
||||
// thingModelList = filterList(thingModelList, thingModel -> IotThingModelTypeEnum.PROPERTY.getType()
|
||||
// .equals(thingModel.getType()));
|
||||
//
|
||||
// // 3. 过滤标识符和属性名称
|
||||
// if (deviceDataReqVO.getIdentifier() != null) {
|
||||
// thingModelList = filterList(thingModelList, thingModel -> thingModel.getIdentifier()
|
||||
// .toLowerCase().contains(deviceDataReqVO.getIdentifier().toLowerCase()));
|
||||
// }
|
||||
// if (deviceDataReqVO.getName() != null) {
|
||||
// thingModelList = filterList(thingModelList, thingModel -> thingModel.getName()
|
||||
// .toLowerCase().contains(deviceDataReqVO.getName().toLowerCase()));
|
||||
// }
|
||||
// // 4. 获取设备属性最新数据
|
||||
// thingModelList.forEach(thingModel -> {
|
||||
// IotDevicePropertyDO deviceData = deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName(), thingModel.getIdentifier());
|
||||
// if (deviceData == null) {
|
||||
// deviceData = new IotDevicePropertyDO();
|
||||
// deviceData.setProductKey(device.getProductKey());
|
||||
// deviceData.setDeviceName(device.getDeviceName());
|
||||
// deviceData.setIdentifier(thingModel.getIdentifier());
|
||||
// deviceData.setDeviceId(deviceDataReqVO.getDeviceId());
|
||||
// deviceData.setThingModelId(thingModel.getId());
|
||||
// deviceData.setName(thingModel.getName());
|
||||
// deviceData.setDataType(thingModel.getProperty().getDataType());
|
||||
// }
|
||||
// list.add(deviceData);
|
||||
// });
|
||||
// return list;
|
||||
return null; // TODO 芋艿:晚点实现
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<Map<String, Object>> getHistoryDeviceProperties(IotDeviceDataPageReqVO deviceDataReqVO) {
|
||||
PageResult<Map<String, Object>> pageResult = new PageResult<>();
|
||||
// 1. 获取设备信息
|
||||
IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
|
||||
// 2. 获取设备属性历史数据
|
||||
SelectVisualDO selectVisualDO = new SelectVisualDO();
|
||||
selectVisualDO.setDataBaseName(getDatabaseName());
|
||||
selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
|
||||
selectVisualDO.setDeviceKey(device.getDeviceKey());
|
||||
selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier());
|
||||
selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
|
||||
selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("rows", deviceDataReqVO.getPageSize());
|
||||
params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
|
||||
selectVisualDO.setParams(params);
|
||||
pageResult.setList(devicePropertyDataMapper.selectHistoryDataList(selectVisualDO));
|
||||
pageResult.setTotal(devicePropertyDataMapper.selectHistoryCount(selectVisualDO));
|
||||
return pageResult;
|
||||
// PageResult<Map<String, Object>> pageResult = new PageResult<>();
|
||||
// // 1. 获取设备信息
|
||||
// IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
|
||||
// // 2. 获取设备属性历史数据
|
||||
// SelectVisualDO selectVisualDO = new SelectVisualDO();
|
||||
// selectVisualDO.setDataBaseName(getDatabaseName());
|
||||
// selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
|
||||
// selectVisualDO.setDeviceKey(device.getDeviceKey());
|
||||
// selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier());
|
||||
// selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
|
||||
// selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
|
||||
// Map<String, Object> params = new HashMap<>();
|
||||
// params.put("rows", deviceDataReqVO.getPageSize());
|
||||
// params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
|
||||
// selectVisualDO.setParams(params);
|
||||
// pageResult.setList(devicePropertyDataMapper.selectHistoryDataList(selectVisualDO));
|
||||
// pageResult.setTotal(devicePropertyDataMapper.selectHistoryCount(selectVisualDO));
|
||||
// return pageResult;
|
||||
return null; // TODO 芋艿:晚点实现
|
||||
}
|
||||
|
||||
private String getDatabaseName() {
|
||||
|
|
|
@ -46,6 +46,7 @@ public interface IotThingModelService {
|
|||
*/
|
||||
IotThingModelDO getThingModel(Long id);
|
||||
|
||||
// TODO @芋艿:增加缓存
|
||||
/**
|
||||
* 获得产品物模型列表
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue