|
|
|
@ -8,7 +8,9 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
|
|
|
|
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.JavaToTdengineTypeEnum;
|
|
|
|
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.JavaToTdengineTypeEnum;
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper;
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper;
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
|
|
|
|
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
|
|
|
|
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
|
|
|
|
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
|
|
|
|
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
@ -16,6 +18,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import javax.validation.ConstraintViolationException;
|
|
|
|
import javax.validation.ConstraintViolationException;
|
|
|
|
@ -58,6 +61,10 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
|
|
|
|
@Resource
|
|
|
|
@Resource
|
|
|
|
private DeviceAttributeTypeMapper deviceAttributeTypeMapper;
|
|
|
|
private DeviceAttributeTypeMapper deviceAttributeTypeMapper;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
|
|
|
@Lazy
|
|
|
|
|
|
|
|
private DeviceContactModelMapper deviceContactModelMapper;
|
|
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
@Resource
|
|
|
|
private ErpProductUnitService productUnitService;
|
|
|
|
private ErpProductUnitService productUnitService;
|
|
|
|
|
|
|
|
|
|
|
|
@ -164,6 +171,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public List<Map<String, Object>> operationAnalysisDetails(Long deviceId, Long modelId,
|
|
|
|
public List<Map<String, Object>> operationAnalysisDetails(Long deviceId, Long modelId,
|
|
|
|
String collectionStartTime, String collectionEndTime) {
|
|
|
|
String collectionStartTime, String collectionEndTime) {
|
|
|
|
|
|
|
|
|
|
|
|
if (deviceId == null) {
|
|
|
|
if (deviceId == null) {
|
|
|
|
throw exception(DEVICE_ID_DOES_NOT_EXIST);
|
|
|
|
throw exception(DEVICE_ID_DOES_NOT_EXIST);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -174,47 +182,37 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
|
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 1. 获取最新10条设备数据列表(直接从TDengine获取原始字段)
|
|
|
|
// 获取最新10条设备数据
|
|
|
|
List<Map<String, Object>> deviceDataList =
|
|
|
|
List<Map<String, Object>> deviceDataList =
|
|
|
|
tdengineService.newSelectLatestData(deviceId, collectionStartTime, collectionEndTime, 10);
|
|
|
|
tdengineService.newSelectLatestData(deviceId, collectionStartTime, collectionEndTime, 10);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 获取属性类型映射
|
|
|
|
// 查找 modelId 对应的 attributeCode
|
|
|
|
Map<Long, String> idToNameMap = deviceAttributeTypeMapper.selectList()
|
|
|
|
DeviceContactModelDO modelDO = deviceContactModelMapper.selectById(modelId);
|
|
|
|
.stream()
|
|
|
|
if (modelDO == null) {
|
|
|
|
.collect(Collectors.toMap(
|
|
|
|
throw exception(POINT_ID_MODEL_NOT_EXISTS);
|
|
|
|
DeviceAttributeTypeDO::getId,
|
|
|
|
}
|
|
|
|
DeviceAttributeTypeDO::getName
|
|
|
|
|
|
|
|
));
|
|
|
|
String attributeCode = modelDO.getAttributeCode();
|
|
|
|
|
|
|
|
if (StringUtils.isBlank(attributeCode)) {
|
|
|
|
|
|
|
|
return resultList;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 遍历每个时间点的数据
|
|
|
|
// 遍历时间点数据
|
|
|
|
for (Map<String, Object> deviceData : deviceDataList) {
|
|
|
|
for (Map<String, Object> deviceData : deviceDataList) {
|
|
|
|
Timestamp timestamp = (Timestamp) deviceData.get("ts"); // TDengine 时间列
|
|
|
|
|
|
|
|
|
|
|
|
Timestamp timestamp = (Timestamp) deviceData.get("ts");
|
|
|
|
if (timestamp == null) continue;
|
|
|
|
if (timestamp == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
|
|
|
|
String formattedTime = sdf.format(timestamp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, Object> timePointData = new LinkedHashMap<>();
|
|
|
|
Map<String, Object> timePointData = new LinkedHashMap<>();
|
|
|
|
timePointData.put("collectTime", formattedTime);
|
|
|
|
timePointData.put("collectTime", sdf.format(timestamp));
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历所有字段(除 ts 之外)
|
|
|
|
|
|
|
|
Map<String, List<Map<String, Object>>> groupedData = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
for (Map.Entry<String, Object> entry : deviceData.entrySet()) {
|
|
|
|
|
|
|
|
String key = entry.getKey();
|
|
|
|
|
|
|
|
if ("ts".equalsIgnoreCase(key)) continue; // 跳过时间字段
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, Object> simplifiedData = new HashMap<>();
|
|
|
|
|
|
|
|
simplifiedData.put("attributeName", key);
|
|
|
|
|
|
|
|
simplifiedData.put("addressValue", entry.getValue());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据 modelId 或 attributeType 分类,这里暂时按 "其他" 分组
|
|
|
|
// modelId 对应的字段
|
|
|
|
groupedData.computeIfAbsent("其他", k -> new ArrayList<>()).add(simplifiedData);
|
|
|
|
Object value = deviceData.get(attributeCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加属性分组
|
|
|
|
timePointData.put("attributeName", attributeCode);
|
|
|
|
for (Map.Entry<String, List<Map<String, Object>>> entry : groupedData.entrySet()) {
|
|
|
|
timePointData.put("addressValue", value);
|
|
|
|
timePointData.put(entry.getKey(), entry.getValue());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resultList.add(timePointData);
|
|
|
|
resultList.add(timePointData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -226,7 +224,6 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
|
|
|
|
|
|
|
|
|
|
|
|
return resultList;
|
|
|
|
return resultList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public List<DeviceModelAttributeDO> getDeviceModelAttributeList(Long id) {
|
|
|
|
public List<DeviceModelAttributeDO> getDeviceModelAttributeList(Long id) {
|
|
|
|
|
|
|
|
|
|
|
|
|