|
|
|
|
@ -986,68 +986,218 @@ public class DeviceServiceImpl implements DeviceService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Map<String, Object>> getMultiDeviceAttributes(String deviceIds) {
|
|
|
|
|
public List<Map<String, Object>> getMultiDeviceAttributes(Long goviewId) {
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 解析设备ID列表
|
|
|
|
|
if (StringUtils.isBlank(deviceIds)) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Long> idList = Arrays.stream(deviceIds.split(","))
|
|
|
|
|
.map(String::trim)
|
|
|
|
|
.map(Long::valueOf)
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
try {
|
|
|
|
|
// 直接从数据库查询deviceIds JSON字符串
|
|
|
|
|
String deviceIdsJson = deviceMapper.selectDeviceIdsByGoviewId(goviewId);
|
|
|
|
|
if (StringUtils.isBlank(deviceIdsJson)) {
|
|
|
|
|
log.info("No deviceIds found for goviewId: {}", goviewId);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历每个设备ID,获取设备属性数据
|
|
|
|
|
for (Long deviceId : idList) {
|
|
|
|
|
// 获取设备信息
|
|
|
|
|
DeviceDO device = deviceMapper.selectById(deviceId);
|
|
|
|
|
if (device == null) {
|
|
|
|
|
continue;
|
|
|
|
|
// 解析JSON格式的deviceIds
|
|
|
|
|
Map<Long, Set<Long>> deviceAttributeMap = parseDeviceIdsJson(deviceIdsJson);
|
|
|
|
|
if (deviceAttributeMap.isEmpty()) {
|
|
|
|
|
log.warn("No valid device-attribute mapping found for goviewId: {}", goviewId);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建设备层级的Map
|
|
|
|
|
Map<String, Object> deviceMap = new HashMap<>();
|
|
|
|
|
deviceMap.put("deviceId", deviceId);
|
|
|
|
|
deviceMap.put("deviceName", device.getDeviceName());
|
|
|
|
|
// 批量获取所有设备的最新运行记录,减少数据库查询次数
|
|
|
|
|
Map<Long, DeviceOperationRecordDO> latestRecordMap = getLatestDeviceOperationRecords(deviceAttributeMap.keySet());
|
|
|
|
|
|
|
|
|
|
// 获取设备属性列表
|
|
|
|
|
List<DeviceContactModelDO> attributes = deviceContactModelMapper.selectList(
|
|
|
|
|
Wrappers.<DeviceContactModelDO>lambdaQuery()
|
|
|
|
|
.eq(DeviceContactModelDO::getDeviceId, deviceId));
|
|
|
|
|
|
|
|
|
|
// 获取设备最新数据
|
|
|
|
|
Map<Long, Map<String, Object>> deviceDataMap = createDeviceDataMap(deviceId);
|
|
|
|
|
|
|
|
|
|
// 创建点位集合
|
|
|
|
|
List<Map<String, Object>> attributeList = new ArrayList<>();
|
|
|
|
|
for (DeviceContactModelDO attribute : attributes) {
|
|
|
|
|
Map<String, Object> attributeData = new HashMap<>();
|
|
|
|
|
attributeData.put("attributeId", attribute.getId());
|
|
|
|
|
attributeData.put("attributeName", attribute.getAttributeName());
|
|
|
|
|
attributeData.put("attributeCode", attribute.getAttributeCode());
|
|
|
|
|
attributeData.put("dataType", attribute.getDataType());
|
|
|
|
|
attributeData.put("dataUnit", attribute.getDataUnit());
|
|
|
|
|
|
|
|
|
|
// 获取最新数据
|
|
|
|
|
Map<String, Object> latestData = deviceDataMap.get(attribute.getId());
|
|
|
|
|
if (latestData != null) {
|
|
|
|
|
attributeData.put("addressValue", adjustByRatio(latestData.get("addressValue"), attribute.getRatio()));
|
|
|
|
|
attributeData.put("latestCollectionTime", latestData.get("timestamp"));
|
|
|
|
|
log.info("Found {} devices with attribute mappings for goviewId {}: {}",
|
|
|
|
|
deviceAttributeMap.size(), goviewId, deviceAttributeMap);
|
|
|
|
|
|
|
|
|
|
// 遍历每个设备ID,获取设备属性数据
|
|
|
|
|
for (Map.Entry<Long, Set<Long>> entry : deviceAttributeMap.entrySet()) {
|
|
|
|
|
Long deviceId = entry.getKey();
|
|
|
|
|
Set<Long> attributeIds = entry.getValue();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 获取设备信息
|
|
|
|
|
DeviceDO device = deviceMapper.selectById(deviceId);
|
|
|
|
|
if (device == null) {
|
|
|
|
|
log.warn("Device not found for ID: {}", deviceId);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建设备层级的Map
|
|
|
|
|
Map<String, Object> deviceMap = new HashMap<>();
|
|
|
|
|
deviceMap.put("deviceId", deviceId);
|
|
|
|
|
deviceMap.put("deviceName", device.getDeviceName());
|
|
|
|
|
deviceMap.put("deviceCode", device.getDeviceCode());
|
|
|
|
|
|
|
|
|
|
// 添加设备运行状态
|
|
|
|
|
String operatingStatus = getDeviceOperatingStatus(deviceId, latestRecordMap);
|
|
|
|
|
deviceMap.put("operatingStatus", operatingStatus);
|
|
|
|
|
|
|
|
|
|
// 获取设备属性列表,只查询指定的属性ID
|
|
|
|
|
List<DeviceContactModelDO> attributes = deviceContactModelMapper.selectList(
|
|
|
|
|
Wrappers.<DeviceContactModelDO>lambdaQuery()
|
|
|
|
|
.eq(DeviceContactModelDO::getDeviceId, deviceId)
|
|
|
|
|
.in(DeviceContactModelDO::getId, attributeIds));
|
|
|
|
|
|
|
|
|
|
// 获取设备最新数据
|
|
|
|
|
Map<Long, Map<String, Object>> deviceDataMap = createDeviceDataMap(deviceId);
|
|
|
|
|
|
|
|
|
|
// 创建属性集合
|
|
|
|
|
List<Map<String, Object>> attributeList = new ArrayList<>();
|
|
|
|
|
for (DeviceContactModelDO attribute : attributes) {
|
|
|
|
|
Map<String, Object> attributeData = new HashMap<>();
|
|
|
|
|
attributeData.put("attributeId", attribute.getId());
|
|
|
|
|
attributeData.put("attributeName", attribute.getAttributeName());
|
|
|
|
|
attributeData.put("attributeCode", attribute.getAttributeCode());
|
|
|
|
|
attributeData.put("dataType", attribute.getDataType());
|
|
|
|
|
attributeData.put("dataUnit", attribute.getDataUnit());
|
|
|
|
|
|
|
|
|
|
// 获取最新数据
|
|
|
|
|
Map<String, Object> latestData = deviceDataMap.get(attribute.getId());
|
|
|
|
|
if (latestData != null) {
|
|
|
|
|
attributeData.put("addressValue", adjustByRatio(latestData.get("addressValue"), attribute.getRatio()));
|
|
|
|
|
attributeData.put("latestCollectionTime", latestData.get("timestamp"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attributeList.add(attributeData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将属性集合添加到设备层级
|
|
|
|
|
deviceMap.put("attributes", attributeList);
|
|
|
|
|
|
|
|
|
|
// 添加到结果列表
|
|
|
|
|
result.add(deviceMap);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("Error processing device ID: {} with attributes: {}", deviceId, attributeIds, e);
|
|
|
|
|
// 继续处理其他设备,不中断整体流程
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("Failed to get multi-device attributes by goviewId: {}", goviewId, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取设备运行状态
|
|
|
|
|
* @param deviceId 设备ID
|
|
|
|
|
* @param latestRecordMap 设备ID到最新运行记录的映射
|
|
|
|
|
* @return 设备运行状态名称
|
|
|
|
|
*/
|
|
|
|
|
private String getDeviceOperatingStatus(Long deviceId, Map<Long, DeviceOperationRecordDO> latestRecordMap) {
|
|
|
|
|
DeviceOperationRecordDO record = latestRecordMap.get(deviceId);
|
|
|
|
|
if (record != null) {
|
|
|
|
|
// 根据运行记录的rule字段获取设备状态
|
|
|
|
|
DeviceStatusEnum statusEnum = DeviceStatusEnum.getByCode(record.getRule());
|
|
|
|
|
return statusEnum != null ? statusEnum.getName() : DeviceStatusEnum.OFFLINE.getName();
|
|
|
|
|
} else {
|
|
|
|
|
// 如果没有运行记录,默认为离线状态
|
|
|
|
|
return DeviceStatusEnum.OFFLINE.getName();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 批量获取设备的最新运行记录
|
|
|
|
|
* @param deviceIds 设备ID集合
|
|
|
|
|
* @return 设备ID到最新运行记录的映射
|
|
|
|
|
*/
|
|
|
|
|
private Map<Long, DeviceOperationRecordDO> getLatestDeviceOperationRecords(Set<Long> deviceIds) {
|
|
|
|
|
if (deviceIds.isEmpty()) {
|
|
|
|
|
return Collections.emptyMap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attributeList.add(attributeData);
|
|
|
|
|
// 查询所有设备的最新运行记录
|
|
|
|
|
List<DeviceOperationRecordDO> records = deviceOperationRecordMapper.selectList(
|
|
|
|
|
Wrappers.<DeviceOperationRecordDO>lambdaQuery()
|
|
|
|
|
.in(DeviceOperationRecordDO::getDeviceId, deviceIds)
|
|
|
|
|
.orderByDesc(DeviceOperationRecordDO::getCreateTime));
|
|
|
|
|
|
|
|
|
|
// 构建设备ID到最新记录的映射
|
|
|
|
|
Map<Long, DeviceOperationRecordDO> latestRecordMap = new HashMap<>();
|
|
|
|
|
for (DeviceOperationRecordDO record : records) {
|
|
|
|
|
// 只保留每个设备的第一条记录(因为已经按创建时间倒序排序)
|
|
|
|
|
if (!latestRecordMap.containsKey(record.getDeviceId())) {
|
|
|
|
|
latestRecordMap.put(record.getDeviceId(), record);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将点位集合添加到设备层级
|
|
|
|
|
deviceMap.put("attributes", attributeList);
|
|
|
|
|
return latestRecordMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解析JSON格式的deviceIds字符串
|
|
|
|
|
* @param deviceIdsJson JSON格式的设备和属性映射字符串
|
|
|
|
|
* @return 设备ID到属性ID集合的映射(已去重)
|
|
|
|
|
*/
|
|
|
|
|
private Map<Long, Set<Long>> parseDeviceIdsJson(String deviceIdsJson) {
|
|
|
|
|
Map<Long, Set<Long>> deviceAttributeMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 添加到结果列表
|
|
|
|
|
result.add(deviceMap);
|
|
|
|
|
if (StringUtils.isBlank(deviceIdsJson)) {
|
|
|
|
|
return deviceAttributeMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
try {
|
|
|
|
|
// 使用Jackson解析JSON字符串
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
List<Map<String, Object>> deviceAttributeList = objectMapper.readValue(
|
|
|
|
|
deviceIdsJson, new TypeReference<List<Map<String, Object>>>() {});
|
|
|
|
|
|
|
|
|
|
// 遍历解析结果,构建设备-属性映射并去重
|
|
|
|
|
for (Map<String, Object> item : deviceAttributeList) {
|
|
|
|
|
try {
|
|
|
|
|
// 提取设备ID
|
|
|
|
|
Object deviceIdObj = item.get("deviceId");
|
|
|
|
|
if (deviceIdObj == null) {
|
|
|
|
|
log.warn("Device ID is null in item: {}", item);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
Long deviceId = null;
|
|
|
|
|
if (deviceIdObj instanceof Number) {
|
|
|
|
|
deviceId = ((Number) deviceIdObj).longValue();
|
|
|
|
|
} else {
|
|
|
|
|
deviceId = Long.parseLong(deviceIdObj.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取属性ID数组
|
|
|
|
|
List<Long> attributeIds = new ArrayList<>();
|
|
|
|
|
Object attributesIdsObj = item.get("attributesIds");
|
|
|
|
|
if (attributesIdsObj instanceof List) {
|
|
|
|
|
List<?> attributesList = (List<?>) attributesIdsObj;
|
|
|
|
|
for (Object attrIdObj : attributesList) {
|
|
|
|
|
if (attrIdObj instanceof Number) {
|
|
|
|
|
attributeIds.add(((Number) attrIdObj).longValue());
|
|
|
|
|
} else if (attrIdObj != null) {
|
|
|
|
|
try {
|
|
|
|
|
attributeIds.add(Long.parseLong(attrIdObj.toString()));
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
log.warn("Invalid attribute ID: {}", attrIdObj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 合并属性ID到现有设备映射中(避免Lambda变量捕获问题)
|
|
|
|
|
Set<Long> existingAttributes = deviceAttributeMap.get(deviceId);
|
|
|
|
|
if (existingAttributes == null) {
|
|
|
|
|
// 如果设备不存在,创建新的属性集合
|
|
|
|
|
Set<Long> newAttributesSet = new HashSet<>(attributeIds);
|
|
|
|
|
deviceAttributeMap.put(deviceId, newAttributesSet);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果设备已存在,将新的属性ID添加到现有集合中
|
|
|
|
|
for (Long attrId : attributeIds) {
|
|
|
|
|
existingAttributes.add(attrId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.warn("Error parsing device-attribute item: {}", item, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("Error parsing deviceIds JSON: {}", deviceIdsJson, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return deviceAttributeMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|