feat(powerenv): 实现设备指标数据定时采集与存储功能

- 新增阿里巴巴设备指标定时任务类,支持多租户执行
- 实现设备最新监控数据的实时更新与持久化
- 添加设备监控指标数据批量保存逻辑
- 重构设备监控数据结构,使用Map替代原有DeviceMetric类
- 完善设备服务接口,增加查询与更新方法
- 优化监控指标服务实现,支持按条件查询与批量操作
- 增强数据转换逻辑,支持多种指标类型解析与告警判断
This commit is contained in:
2025-12-03 11:18:44 +08:00
parent ba59c4a508
commit 4d785adf40
9 changed files with 240 additions and 443 deletions

View File

@@ -1,10 +1,27 @@
package com.jeelowcode.module.biz.convert; package com.jeelowcode.module.biz.convert;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jeelowcode.module.biz.dto.PowerEnvDeviceDataDTO;
import com.jeelowcode.module.biz.dto.PowerEnvDeviceMetricDataDTO;
import com.jeelowcode.module.biz.entity.LcPowerEnvDeviceEntity;
import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity; import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity;
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 动环监控指标实体转换接口 * 动环监控指标实体转换接口
@@ -16,20 +33,97 @@ public interface LcPowerEnvMonitorMetricEntityConvert {
LcPowerEnvMonitorMetricEntityConvert INSTANCE = Mappers.getMapper(LcPowerEnvMonitorMetricEntityConvert.class); LcPowerEnvMonitorMetricEntityConvert INSTANCE = Mappers.getMapper(LcPowerEnvMonitorMetricEntityConvert.class);
/** default List<LcPowerEnvMonitorMetricEntity> convertList(PowerEnvDeviceDataDTO deviceData) {
* 将 LcPowerEnvMonitorMetricEntity 转换为 LcPowerEnvMonitorMetricEntity String deviceUid = deviceData.getDeviceUid();
* List<PowerEnvDeviceMetricDataDTO> list = deviceData.getPropertyRunDataList();
* @param bean 实体对象 if (CollUtil.isEmpty(list)) return Collections.emptyList();
* @return 实体对象 return list.stream().map(metric -> {
*/ LcPowerEnvMonitorMetricEntity entity = new LcPowerEnvMonitorMetricEntity();
LcPowerEnvMonitorMetricEntity convert(LcPowerEnvMonitorMetricEntity bean); entity.setDeviceUid(deviceUid);
entity.setMetadataUid(metric.getMetadataUid());
entity.setMetadataCode(metric.getMetadataCode());
entity.setMetadataName(metric.getMetadataName());
entity.setPropertyCode(metric.getPropertyCode());
entity.setPropertyName(metric.getPropertyName());
entity.setUnitCode(metric.getUnitCode());
entity.setValueType(metric.getValueType());
entity.setValueTypeName(getValueTypeName(metric.getValueType()));
entity.setPointType(metric.getType());
entity.setMetricValue(metric.getValue());
entity.setUpdateTime(LocalDateTimeUtil.of(metric.getUpdateTime()));
return entity;
}).collect(Collectors.toList());
}
default String getValueTypeName(Integer valueType) {
StringBuilder valueTypeName = new StringBuilder();
switch (valueType) {
case 20100:
valueTypeName.append("文本型");
break;
case 20200:
valueTypeName.append("数字型");
break;
case 20300:
valueTypeName.append("布尔型");
break;
case 20400:
valueTypeName.append("枚举型");
break;
default:
valueTypeName.append("未知");
break;
}
return valueTypeName.toString();
}
default String getPointTypeName(Integer pointType) {
StringBuilder pointTypeName = new StringBuilder();
switch (pointType) {
case 10200:
pointTypeName.append("配置类点位");
break;
case 10300:
pointTypeName.append("采集类点位");
break;
case 10400:
pointTypeName.append("执行类点位");
break;
case 10500:
pointTypeName.append("报警类点位");
break;
default:
pointTypeName.append("未知");
break;
}
return pointTypeName.toString();
}
/** /**
* 将 LcPowerEnvMonitorMetricEntity 列表转换为 LcPowerEnvMonitorMetricEntity 列表 * 将设备度量数据列表转换为最新度量映射
* *
* @param list 实体对象列表 * @param list 设备度量数据列表
* @return 实体对象列表 * @return 包含度量数据的映射,其中键为属性编码,值为对应的度量值和视图值
*/ */
List<LcPowerEnvMonitorMetricEntity> convertList(List<LcPowerEnvMonitorMetricEntity> list); default Map<String, Object> convertLatestMetric(List<PowerEnvDeviceMetricDataDTO> list) {
Map<String, Object> deviceMetric = new LinkedHashMap<>();
deviceMetric.put("alarm", Boolean.FALSE);
list.forEach(metric -> {
if (NumberUtil.equals(metric.getValueType(), Integer.valueOf(20200))) {
// 处理数字类型度量值
deviceMetric.put(metric.getPropertyCode(), Convert.toBigDecimal(metric.getValue()));
String fieldView = StrUtil.isEmpty(metric.getUnitCode()) ? metric.getValue() : metric.getValue() + metric.getUnitCode();
deviceMetric.put(metric.getPropertyCode() + "View", fieldView);
} else if (NumberUtil.equals(metric.getValueType(), Integer.valueOf(20300))) {
// 处理布尔类型度量值
deviceMetric.put(metric.getPropertyCode(), Convert.toBool(metric.getValue()));
Map<String, String> controlEnumValue = JSONUtil.toBean(metric.getControlEnumValue(), new TypeReference<Map<String, String>>() {
}, true);
deviceMetric.put(metric.getPropertyCode() + "View", controlEnumValue.get(metric.getValue()));
if (StrUtil.equals(metric.getValue(), "true")) deviceMetric.put("alarm", Boolean.TRUE);
}
});
return deviceMetric;
}
} }

View File

@@ -5,14 +5,13 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.jeelowcode.framework.utils.model.global.BaseTenantEntity; import com.jeelowcode.framework.utils.model.global.BaseTenantEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal; import java.util.Map;
/** /**
* 动环设备信息表 * 动环设备信息表
@@ -75,431 +74,6 @@ public class LcPowerEnvDeviceEntity extends BaseTenantEntity {
* 最新监控数据 映射成DeviceMetric数据库是Json * 最新监控数据 映射成DeviceMetric数据库是Json
*/ */
@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = JacksonTypeHandler.class)
private DeviceMetric monitorData; private Map<String, Object> monitorData;
/**
* 动环设备监控指标信息
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class DeviceMetric {
/**
* 是否告警
*/
private Boolean alarm;
/**
* 电池组电流
*/
private BigDecimal BatI;
/**
* 电池组电流视图
*/
private String BatIView;
// UPS相关指标
/**
* 电池备用时间
*/
private BigDecimal BatteryPowerTime;
/**
* 电池备用时间视图
*/
private String BatteryPowerTimeView;
/**
* 电池组电压
*/
private BigDecimal BatU;
/**
* 电池组电压视图
*/
private String BatUView;
/**
* 频率
*/
private BigDecimal electricFr;
/**
* 频率视图
*/
private String electricFrView;
/**
* A相有功功率
*/
private BigDecimal electricPa;
/**
* A相有功功率视图
*/
private String electricPaView;
/**
* B相有功功率
*/
private BigDecimal electricPb;
/**
* B相有功功率视图
*/
private String electricPbView;
/**
* C相有功功率
*/
private BigDecimal electricPc;
/**
* C相有功功率视图
*/
private String electricPcView;
/**
* 紧急停止状态
*/
private Boolean EmerOutage;
/**
* 紧急停止状态视图
*/
private String EmerOutageView;
/**
* UPS保险丝故障状态
*/
private Boolean FuFaultAlarm;
/**
* UPS保险丝故障状态视图
*/
private String FuFaultAlarmView;
/**
* 逆变器主要故障状态
*/
private Boolean InverterFaultAlarm;
/**
* 逆变器主要故障状态视图
*/
private String InverterFaultAlarmView;
/**
* 负载百分比
*/
private BigDecimal LoadPercentage;
/**
* 负载百分比视图
*/
private String LoadPercentageView;
/**
* 电池电量低警告状态
*/
private Boolean LowBatteryAlarm;
/**
* 电池电量低警告状态视图
*/
private String LowBatteryAlarmView;
/**
* A相电压
*/
private BigDecimal nUa;
/**
* A相电压视图
*/
private String nUaView;
/**
* B相电压
*/
private BigDecimal nUb;
/**
* B相电压视图
*/
private String nUbView;
/**
* C相电压
*/
private BigDecimal nUc;
/**
* C相电压视图
*/
private String nUcView;
/**
* UPS过载状态
*/
private Boolean OverLoadAlarm;
/**
* UPS过载状态视图
*/
private String OverLoadAlarmView;
/**
* 开关状态
*/
private Boolean switchStatus;
/**
* 开关状态视图
*/
private String switchStatusView;
/**
* AB线电压
*/
private BigDecimal Uab1;
/**
* AB线电压视图
*/
private String Uab1View;
/**
* BC线电压
*/
private BigDecimal Ubc1;
/**
* BC线电压视图
*/
private String Ubc1View;
/**
* CA线电压
*/
private BigDecimal Uca1;
/**
* CA线电压视图
*/
private String Uca1View;
// 精密空调相关指标
/**
* 风机或气流丢失故障
*/
private Boolean FlowLose;
/**
* 风机或气流丢失故障视图
*/
private String FlowLoseView;
/**
* 回风高湿报警
*/
private Boolean HumidityHighAlarm;
/**
* 回风高湿报警视图
*/
private String HumidityHighAlarmView;
/**
* 回风低湿报警
*/
private Boolean HumidityLowAlarm;
/**
* 回风低湿报警视图
*/
private String HumidityLowAlarmView;
/**
* 水浸报警
*/
private Boolean LeakAlarm;
/**
* 水浸报警视图
*/
private String LeakAlarmView;
/**
* 回风湿度
*/
private BigDecimal nRetAirHum;
/**
* 回风湿度视图
*/
private String nRetAirHumView;
/**
* 回风温度
*/
private BigDecimal nRetAirTemp;
/**
* 回风温度视图
*/
private String nRetAirTempView;
/**
* 相序错误(逆相)
*/
private Boolean PhaseSequenceError;
/**
* 相序错误(逆相)视图
*/
private String PhaseSequenceErrorView;
/**
* 回风高温报警
*/
private Boolean TemperatureHighAlarm;
/**
* 回风高温报警视图
*/
private String TemperatureHighAlarmView;
/**
* 回风低温报警
*/
private Boolean TemperatureLowAlarm;
/**
* 回风低温报警视图
*/
private String TemperatureLowAlarmView;
// 温湿度检测相关指标
/**
* 环境湿度
*/
private BigDecimal humidity;
/**
* 环境湿度视图
*/
private String humidityView;
/**
* 环境温度
*/
private BigDecimal temperature;
/**
* 环境温度视图
*/
private String temperatureView;
// 氢气检测相关指标
/**
* 氢气浓度
*/
private BigDecimal Concentrate;
/**
* 氢气浓度视图
*/
private String ConcentrateView;
// 粉尘检测相关指标
/**
* 粉尘检测
*/
private BigDecimal DustDetection;
/**
* 粉尘检测视图
*/
private String DustDetectionView;
// 加湿器相关指标
/**
* 盘管故障
*/
private Boolean CoilFault;
/**
* 盘管故障视图
*/
private String CoilFaultView;
/**
* 水满告警
*/
private Boolean FullWaterAlarm;
/**
* 水满告警视图
*/
private String FullWaterAlarmView;
/**
* 缺水告警
*/
private Boolean LockWaterAlarm;
/**
* 缺水告警视图
*/
private String LockWaterAlarmView;
/**
* 温湿度传感器故障
*/
private Boolean SensorFault;
/**
* 温湿度传感器故障视图
*/
private String SensorFaultView;
// 加湿除湿一体相关指标
// humidity 和 temperature 字段已在上面定义
// 电量仪相关指标
/**
* A相电流
*/
private BigDecimal nIa;
/**
* A相电流视图
*/
private String nIaView;
/**
* B相电流
*/
private BigDecimal nIb;
/**
* B相电流视图
*/
private String nIbView;
/**
* C相电流
*/
private BigDecimal nIc;
/**
* C相电流视图
*/
private String nIcView;
// nUa, nUb, nUc 字段已在上面定义
}
} }

View File

@@ -85,5 +85,5 @@ public class LcPowerEnvMonitorMetricEntity extends BaseTenantEntity {
* 指标值 * 指标值
*/ */
private String metricValue; private String metricValue;
} }

View File

@@ -1,10 +1,23 @@
package com.jeelowcode.module.biz.job; package com.jeelowcode.module.biz.job;
import com.jeelowcode.module.biz.convert.LcPowerEnvMonitorMetricEntityConvert;
import com.jeelowcode.module.biz.dto.PowerEnvDeviceDataDTO;
import com.jeelowcode.module.biz.dto.PowerEnvDeviceMetricDataDTO;
import com.jeelowcode.module.biz.entity.LcPowerEnvDeviceEntity;
import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity;
import com.jeelowcode.module.biz.service.IBizHttpClientService;
import com.jeelowcode.module.biz.service.ILcPowerEnvDeviceService;
import com.jeelowcode.module.biz.service.ILcPowerEnvMonitorMetricService;
import com.jeelowcode.tool.framework.quartz.core.handler.JobHandler; import com.jeelowcode.tool.framework.quartz.core.handler.JobHandler;
import com.jeelowcode.tool.framework.tenant.core.job.TenantJob;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/** /**
* 设备指标数据定时任务 * 设备指标数据定时任务
* *
@@ -15,10 +28,31 @@ import org.springframework.stereotype.Component;
@ConditionalOnProperty(name = "jeelowcode.powerenv.baseurl") @ConditionalOnProperty(name = "jeelowcode.powerenv.baseurl")
public class AlibabaDeviceMetricJob implements JobHandler { public class AlibabaDeviceMetricJob implements JobHandler {
@Resource
private ILcPowerEnvDeviceService deviceService;
@Resource
private IBizHttpClientService httpClientService;
@Resource
private ILcPowerEnvMonitorMetricService monitorMetricService;
@Override @Override
@TenantJob
public String execute(String param) throws Exception { public String execute(String param) throws Exception {
return ""; List<LcPowerEnvDeviceEntity> deviceList = deviceService.selectList();
deviceList.parallelStream().forEach(device -> {
PowerEnvDeviceDataDTO deviceData = httpClientService.listDeviceMetrics(device.getDeviceUid());
List<PowerEnvDeviceMetricDataDTO> metricList = deviceData.getPropertyRunDataList();
// 更新这个设备的最新数据
Map<String, Object> deviceMetric = LcPowerEnvMonitorMetricEntityConvert.INSTANCE.convertLatestMetric(metricList);
device.setMonitorData(deviceMetric);
deviceService.updateById(device);
// 将这些数据保存到数据库中
List<LcPowerEnvMonitorMetricEntity> metricEntityList = LcPowerEnvMonitorMetricEntityConvert.INSTANCE.convertList(deviceData);
monitorMetricService.saveBatch(metricEntityList);
});
return "设备指标数据定时任务执行完毕";
} }
} }

View File

@@ -2,8 +2,12 @@ package com.jeelowcode.module.biz.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity; import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity;
import com.jeelowcode.tool.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.List;
/** /**
* 动环设备监控指标信息 Mapper * 动环设备监控指标信息 Mapper
* *
@@ -12,4 +16,19 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface LcPowerEnvMonitorMetricMapper extends BaseMapper<LcPowerEnvMonitorMetricEntity> { public interface LcPowerEnvMonitorMetricMapper extends BaseMapper<LcPowerEnvMonitorMetricEntity> {
/**
* 根据设备UID、属性编码和更新时间查询动环设备监控指标信息列表
*
* @param deviceUid 设备唯一标识
* @param propertyCode 属性编码
* @param updateTime 更新时间
* @return 符合条件的动环设备监控指标信息列表
*/
default List<LcPowerEnvMonitorMetricEntity> selectListByCondition(String deviceUid, String propertyCode, LocalDateTime updateTime) {
return selectList(new LambdaQueryWrapperX<LcPowerEnvMonitorMetricEntity>()
.eq(LcPowerEnvMonitorMetricEntity::getDeviceUid, deviceUid)
.eq(LcPowerEnvMonitorMetricEntity::getPropertyCode, propertyCode)
.eq(LcPowerEnvMonitorMetricEntity::getUpdateTime, updateTime));
}
} }

View File

@@ -1,5 +1,9 @@
package com.jeelowcode.module.biz.service; package com.jeelowcode.module.biz.service;
import com.jeelowcode.module.biz.entity.LcPowerEnvDeviceEntity;
import java.util.List;
/** /**
* 动环设备信息服务接口 * 动环设备信息服务接口
* *
@@ -7,4 +11,19 @@ package com.jeelowcode.module.biz.service;
*/ */
public interface ILcPowerEnvDeviceService { public interface ILcPowerEnvDeviceService {
/**
* 查询所有设备信息
*
* @return 设备信息列表
*/
List<LcPowerEnvDeviceEntity> selectList();
/**
* 根据ID更新设备信息
*
* @param entity 设备信息
* @return 更新结果
*/
int updateById(LcPowerEnvDeviceEntity entity);
} }

View File

@@ -1,5 +1,9 @@
package com.jeelowcode.module.biz.service; package com.jeelowcode.module.biz.service;
import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity;
import java.util.List;
/** /**
* 动环设备监控指标信息服务接口 * 动环设备监控指标信息服务接口
* *
@@ -7,4 +11,12 @@ package com.jeelowcode.module.biz.service;
*/ */
public interface ILcPowerEnvMonitorMetricService { public interface ILcPowerEnvMonitorMetricService {
/**
* 批量保存
*
* @param list 批量保存数据
* @return 批量保存结果
*/
int saveBatch(List<LcPowerEnvMonitorMetricEntity> list);
} }

View File

@@ -1,9 +1,15 @@
package com.jeelowcode.module.biz.service.impl; package com.jeelowcode.module.biz.service.impl;
import com.jeelowcode.module.biz.entity.LcPowerEnvDeviceEntity;
import com.jeelowcode.module.biz.mapper.LcPowerEnvDeviceMapper;
import com.jeelowcode.module.biz.service.ILcPowerEnvDeviceService; import com.jeelowcode.module.biz.service.ILcPowerEnvDeviceService;
import com.jeelowcode.tool.framework.mybatis.core.query.LambdaQueryWrapperX;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/** /**
* 动环设备信息服务实现类 * 动环设备信息服务实现类
* *
@@ -13,4 +19,12 @@ import org.springframework.stereotype.Service;
@Service @Service
public class LcPowerEnvDeviceServiceImpl implements ILcPowerEnvDeviceService { public class LcPowerEnvDeviceServiceImpl implements ILcPowerEnvDeviceService {
} @Resource
private LcPowerEnvDeviceMapper baseMapper;
@Override
public List<LcPowerEnvDeviceEntity> selectList() {
return baseMapper.selectList(new LambdaQueryWrapperX<>());
}
}

View File

@@ -1,9 +1,15 @@
package com.jeelowcode.module.biz.service.impl; package com.jeelowcode.module.biz.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.jeelowcode.module.biz.entity.LcPowerEnvMonitorMetricEntity;
import com.jeelowcode.module.biz.mapper.LcPowerEnvMonitorMetricMapper;
import com.jeelowcode.module.biz.service.ILcPowerEnvMonitorMetricService; import com.jeelowcode.module.biz.service.ILcPowerEnvMonitorMetricService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/** /**
* 动环设备监控指标信息服务实现类 * 动环设备监控指标信息服务实现类
* *
@@ -13,4 +19,29 @@ import org.springframework.stereotype.Service;
@Service @Service
public class LcPowerEnvMonitorMetricServiceImpl implements ILcPowerEnvMonitorMetricService { public class LcPowerEnvMonitorMetricServiceImpl implements ILcPowerEnvMonitorMetricService {
} @Resource
private LcPowerEnvMonitorMetricMapper baseMapper;
/**
* 批量保存动环设备监控指标信息
* 对于每个指标实体根据设备UID、属性编码和更新时间判断是否存在相同记录
* 若不存在则插入新记录,若存在则更新原记录
*
* @param list 动环设备监控指标实体列表
* @return 成功保存的记录数
*/
@Override
public int saveBatch(List<LcPowerEnvMonitorMetricEntity> list) {
return list.parallelStream().mapToInt(metric -> {
List<LcPowerEnvMonitorMetricEntity> metricList = baseMapper.selectListByCondition(metric.getDeviceUid(), metric.getPropertyCode(), metric.getUpdateTime());
if (CollUtil.isEmpty(metricList)) {
return baseMapper.insert(metric);
} else {
metric.setId(CollUtil.getFirst(metricList).getId());
return baseMapper.updateById(metric);
}
}
).sum();
}
}