This commit is contained in:
2026-02-16 13:41:35 +08:00
parent 71d0b0f609
commit 8806473080
11 changed files with 783 additions and 53 deletions

View File

@ -24,6 +24,18 @@ public class BatteryDataStatsListVo {
/** SOH (%) */
private BigDecimal soh;
/** 电压映射点位ID */
private String voltagePointId;
/** 温度映射点位ID */
private String temperaturePointId;
/** SOC映射点位ID */
private String socPointId;
/** SOH映射点位ID */
private String sohPointId;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dataTimestamp;
@ -71,6 +83,38 @@ public class BatteryDataStatsListVo {
this.soh = soh;
}
public String getVoltagePointId() {
return voltagePointId;
}
public void setVoltagePointId(String voltagePointId) {
this.voltagePointId = voltagePointId;
}
public String getTemperaturePointId() {
return temperaturePointId;
}
public void setTemperaturePointId(String temperaturePointId) {
this.temperaturePointId = temperaturePointId;
}
public String getSocPointId() {
return socPointId;
}
public void setSocPointId(String socPointId) {
this.socPointId = socPointId;
}
public String getSohPointId() {
return sohPointId;
}
public void setSohPointId(String sohPointId) {
this.sohPointId = sohPointId;
}
public Date getDataTimestamp() {
return dataTimestamp;
}

View File

@ -0,0 +1,114 @@
package com.xzzn.ems.domain.vo;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 站点保护约束(供策略轮询仲裁)
*/
public class ProtectionConstraintVo implements Serializable {
private static final long serialVersionUID = 1L;
/** 最高保护等级0-无保护1/2/3 对应故障等级 */
private Integer level;
/** 是否允许充电 */
private Boolean allowCharge;
/** 是否允许放电 */
private Boolean allowDischarge;
/** 功率上限比例0~1 */
private BigDecimal powerLimitRatio;
/** 是否强制待机 */
private Boolean forceStandby;
/** 是否强制停机 */
private Boolean forceStop;
/** 生效的方案ID列表 */
private List<Long> sourcePlanIds;
/** 更新时间戳(毫秒) */
private Long updateAt;
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public Boolean getAllowCharge() {
return allowCharge;
}
public void setAllowCharge(Boolean allowCharge) {
this.allowCharge = allowCharge;
}
public Boolean getAllowDischarge() {
return allowDischarge;
}
public void setAllowDischarge(Boolean allowDischarge) {
this.allowDischarge = allowDischarge;
}
public BigDecimal getPowerLimitRatio() {
return powerLimitRatio;
}
public void setPowerLimitRatio(BigDecimal powerLimitRatio) {
this.powerLimitRatio = powerLimitRatio;
}
public Boolean getForceStandby() {
return forceStandby;
}
public void setForceStandby(Boolean forceStandby) {
this.forceStandby = forceStandby;
}
public Boolean getForceStop() {
return forceStop;
}
public void setForceStop(Boolean forceStop) {
this.forceStop = forceStop;
}
public List<Long> getSourcePlanIds() {
return sourcePlanIds;
}
public void setSourcePlanIds(List<Long> sourcePlanIds) {
this.sourcePlanIds = sourcePlanIds;
}
public Long getUpdateAt() {
return updateAt;
}
public void setUpdateAt(Long updateAt) {
this.updateAt = updateAt;
}
public static ProtectionConstraintVo empty() {
ProtectionConstraintVo vo = new ProtectionConstraintVo();
vo.setLevel(0);
vo.setAllowCharge(true);
vo.setAllowDischarge(true);
vo.setPowerLimitRatio(BigDecimal.ONE);
vo.setForceStandby(false);
vo.setForceStop(false);
vo.setSourcePlanIds(new ArrayList<>());
vo.setUpdateAt(System.currentTimeMillis());
return vo;
}
}

View File

@ -0,0 +1,38 @@
package com.xzzn.ems.domain.vo;
import java.util.ArrayList;
import java.util.List;
/**
* 告警保护方案-保护前提分组
*/
public class ProtectionSettingsGroupVo {
/** 故障保护前提 */
private List<ProtectionSettingVo> faultSettings;
/** 释放保护前提 */
private List<ProtectionSettingVo> releaseSettings;
public static ProtectionSettingsGroupVo empty() {
ProtectionSettingsGroupVo vo = new ProtectionSettingsGroupVo();
vo.setFaultSettings(new ArrayList<>());
vo.setReleaseSettings(new ArrayList<>());
return vo;
}
public List<ProtectionSettingVo> getFaultSettings() {
return faultSettings;
}
public void setFaultSettings(List<ProtectionSettingVo> faultSettings) {
this.faultSettings = faultSettings;
}
public List<ProtectionSettingVo> getReleaseSettings() {
return releaseSettings;
}
public void setReleaseSettings(List<ProtectionSettingVo> releaseSettings) {
this.releaseSettings = releaseSettings;
}
}

View File

@ -13,5 +13,7 @@ public interface EmsSiteMonitorPointMatchMapper {
int deleteBySiteId(@Param("siteId") String siteId);
int deleteBySiteIdAndDeviceId(@Param("siteId") String siteId, @Param("deviceId") String deviceId);
int insertBatch(@Param("list") List<EmsSiteMonitorPointMatch> list);
}

View File

@ -69,6 +69,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
/**
@ -215,9 +216,127 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
pcsSetting.setDeviceSettingId(devicesSetting.getId());
emsPcsSettingMapper.insertEmsPcsSetting(pcsSetting);
}
initSiteMonitorPointMappingsForNewDevice(devicesSetting);
return result;
}
private void initSiteMonitorPointMappingsForNewDevice(DevicesSettingVo devicesSetting) {
if (devicesSetting == null) {
return;
}
String siteId = StringUtils.trim(devicesSetting.getSiteId());
String deviceId = StringUtils.trim(devicesSetting.getDeviceId());
String deviceCategory = StringUtils.trim(devicesSetting.getDeviceCategory());
if (StringUtils.isAnyBlank(siteId, deviceId, deviceCategory)) {
return;
}
List<EmsSiteMonitorItem> itemList = getEnabledMonitorItems();
if (CollectionUtils.isEmpty(itemList)) {
return;
}
Set<String> targetFieldCodes = itemList.stream()
.filter(Objects::nonNull)
.filter(item -> isDeviceDimensionItem(item))
.filter(item -> StringUtils.equals(deviceCategory, resolveDeviceCategoryByItem(item)))
.map(EmsSiteMonitorItem::getFieldCode)
.filter(StringUtils::isNotBlank)
.map(String::trim)
.collect(Collectors.toSet());
if (targetFieldCodes.isEmpty()) {
return;
}
List<EmsSiteMonitorPointMatch> existMappings = emsSiteMonitorPointMatchMapper.selectBySiteId(siteId);
if (existMappings == null) {
existMappings = Collections.emptyList();
}
Set<String> deletedFieldCodes = existMappings.stream()
.filter(Objects::nonNull)
.filter(item -> DELETED_FIELD_MARK.equals(item.getDataPoint()))
.map(EmsSiteMonitorPointMatch::getFieldCode)
.filter(StringUtils::isNotBlank)
.map(String::trim)
.collect(Collectors.toSet());
targetFieldCodes.removeAll(deletedFieldCodes);
if (targetFieldCodes.isEmpty()) {
return;
}
Set<String> existsFieldAndDevice = existMappings.stream()
.filter(Objects::nonNull)
.map(item -> buildMatchKey(StringUtils.trim(item.getFieldCode()), StringUtils.trim(item.getDeviceId())))
.collect(Collectors.toSet());
String operName = StringUtils.defaultIfBlank(StringUtils.trim(devicesSetting.getCreateBy()), "system");
List<EmsSiteMonitorPointMatch> insertList = new ArrayList<>();
for (String fieldCode : targetFieldCodes) {
String key = buildMatchKey(fieldCode, deviceId);
if (existsFieldAndDevice.contains(key)) {
continue;
}
EmsSiteMonitorPointMatch template = findTemplateMappingForNewDevice(existMappings, fieldCode);
EmsSiteMonitorPointMatch insertItem = new EmsSiteMonitorPointMatch();
insertItem.setSiteId(siteId);
insertItem.setFieldCode(fieldCode);
insertItem.setDeviceId(deviceId);
insertItem.setDataPoint(template == null ? "" : StringUtils.defaultString(template.getDataPoint()));
insertItem.setFixedDataPoint(template == null ? null : StringUtils.trimToNull(template.getFixedDataPoint()));
insertItem.setUseFixedDisplay(template == null ? 0 : (template.getUseFixedDisplay() == null ? 0 : template.getUseFixedDisplay()));
insertItem.setCreateBy(operName);
insertItem.setUpdateBy(operName);
insertList.add(insertItem);
}
if (insertList.isEmpty()) {
return;
}
emsSiteMonitorPointMatchMapper.insertBatch(insertList);
redisCache.deleteObject(buildSiteMonitorPointMatchRedisKey(siteId));
clearSiteMonitorLatestCache(siteId);
projectDisplayCache.remove(siteId);
}
private EmsSiteMonitorPointMatch findTemplateMappingForNewDevice(List<EmsSiteMonitorPointMatch> mappings, String fieldCode) {
if (CollectionUtils.isEmpty(mappings) || StringUtils.isBlank(fieldCode)) {
return null;
}
String normalizedFieldCode = fieldCode.trim();
EmsSiteMonitorPointMatch fallback = null;
for (EmsSiteMonitorPointMatch item : mappings) {
if (item == null || !normalizedFieldCode.equals(StringUtils.trim(item.getFieldCode()))) {
continue;
}
if (DELETED_FIELD_MARK.equals(item.getDataPoint())) {
continue;
}
if (StringUtils.isNotBlank(item.getDeviceId())) {
return item;
}
if (fallback == null) {
fallback = item;
}
}
return fallback;
}
private String resolveDeviceCategoryByItem(EmsSiteMonitorItem item) {
if (item == null) {
return null;
}
String byMenu = StringUtils.trim(MENU_DEVICE_CATEGORY_MAP.get(StringUtils.trim(item.getMenuCode())));
if (StringUtils.isNotBlank(byMenu)) {
return byMenu;
}
String fieldCode = StringUtils.trim(item.getFieldCode());
if (StringUtils.isBlank(fieldCode) || !fieldCode.contains("__")) {
return null;
}
String menuCode = fieldCode.substring(0, fieldCode.indexOf("__"));
return StringUtils.trim(MENU_DEVICE_CATEGORY_MAP.get(StringUtils.trim(menuCode)));
}
/**
* 更新设备
* @param devicesSetting
@ -277,9 +396,26 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteEmsDevicesSettingById(Long id){
return emsDevicesMapper.deleteEmsDevicesSettingById(id);
if (id == null) {
return 0;
}
EmsDevicesSetting existDevice = emsDevicesMapper.selectEmsDevicesSettingById(id);
int rows = emsDevicesMapper.deleteEmsDevicesSettingById(id);
if (rows <= 0 || existDevice == null) {
return rows;
}
String siteId = StringUtils.trim(existDevice.getSiteId());
String deviceId = StringUtils.trim(existDevice.getDeviceId());
if (StringUtils.isAnyBlank(siteId, deviceId)) {
return rows;
}
emsSiteMonitorPointMatchMapper.deleteBySiteIdAndDeviceId(siteId, deviceId);
redisCache.deleteObject(buildSiteMonitorPointMatchRedisKey(siteId));
clearSiteMonitorLatestCache(siteId);
projectDisplayCache.remove(siteId);
return rows;
}
@Override

View File

@ -12,6 +12,7 @@ import com.xzzn.ems.domain.EmsBatteryData;
import com.xzzn.ems.domain.EmsBatteryStack;
import com.xzzn.ems.domain.EmsCoolingData;
import com.xzzn.ems.domain.EmsDhData;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.domain.EmsEmsData;
import com.xzzn.ems.domain.EmsPcsBranchData;
import com.xzzn.ems.domain.EmsSiteMonitorPointMatch;
@ -32,6 +33,7 @@ import com.xzzn.ems.mapper.EmsSiteMonitorPointMatchMapper;
import com.xzzn.ems.mapper.EmsStrategyRunningMapper;
import com.xzzn.ems.mapper.EmsStrategyTempMapper;
import com.xzzn.ems.service.IEmsEnergyPriceConfigService;
import com.xzzn.ems.service.IEmsDeviceSettingService;
import com.xzzn.ems.service.ISingleSiteService;
import com.xzzn.ems.service.InfluxPointDataWriter;
import com.xzzn.ems.utils.DevicePointMatchDataProcessor;
@ -90,6 +92,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService {
private static final Set<String> PCS_DETAIL_META_FIELDS = new HashSet<>(Arrays.asList(
"siteId", "deviceId", "deviceName", "alarmNum", "pcsBranchInfoList", "dataUpdateTime"
));
private static final Set<String> BATTERY_DETAIL_META_FIELDS = new HashSet<>(Arrays.asList(
"deviceId", "clusterDeviceId", "dataTimestamp"
));
private static final String MENU_SBJK_DTDC = "SBJK_DTDC";
private static final String CLUSTER_DATA_TEP = "温度";
@ -135,6 +141,8 @@ public class SingleSiteServiceImpl implements ISingleSiteService {
@Autowired
private IEmsEnergyPriceConfigService iEmsEnergyPriceConfigService;
@Autowired
private IEmsDeviceSettingService iEmsDeviceSettingService;
@Autowired
private DevicePointMatchDataProcessor devicePointMatchDataProcessor;
@Override
@ -1007,45 +1015,292 @@ public class SingleSiteServiceImpl implements ISingleSiteService {
public List<BatteryDataStatsListVo> getClusterDataInfoList(String clusterDeviceId,String siteId,
String stackDeviceId, String batteryId) {
List<BatteryDataStatsListVo> batteryDataStatsListVo = new ArrayList<>();
log.info("getClusterDataInfoList start, siteId={}, stackDeviceId={}, clusterDeviceId={}, batteryId={}",
siteId, stackDeviceId, clusterDeviceId, batteryId);
String targetStackDeviceId = StringUtils.trimToEmpty(stackDeviceId);
String targetClusterDeviceId = StringUtils.trimToEmpty(clusterDeviceId);
String targetBatteryId = StringUtils.trimToEmpty(batteryId);
if ("undefined".equalsIgnoreCase(targetStackDeviceId) || "null".equalsIgnoreCase(targetStackDeviceId)) {
targetStackDeviceId = "";
}
if ("undefined".equalsIgnoreCase(targetClusterDeviceId) || "null".equalsIgnoreCase(targetClusterDeviceId)) {
targetClusterDeviceId = "";
}
if ("undefined".equalsIgnoreCase(targetBatteryId) || "null".equalsIgnoreCase(targetBatteryId)) {
targetBatteryId = "";
}
log.info("getClusterDataInfoList normalized params, siteId={}, stackDeviceId={}, clusterDeviceId={}, batteryId={}",
siteId, targetStackDeviceId, targetClusterDeviceId, targetBatteryId);
if (StringUtils.isEmpty(siteId)) {
log.warn("getClusterDataInfoList early return, siteId is empty");
return batteryDataStatsListVo;
}
Map<String, Map<String, SiteMonitorProjectDisplayVo>> batteryDisplayMap =
buildBatteryDisplayMap(iEmsDeviceSettingService.getSiteMonitorProjectDisplay(siteId));
if (batteryDisplayMap.isEmpty()) {
log.warn("getClusterDataInfoList no battery display data from projectDisplay, siteId={}", siteId);
}
log.info("getClusterDataInfoList battery list source projectDisplay, siteId={}, batteryCount={}",
siteId, batteryDisplayMap.size());
Map<String, EmsDevicesSetting> batteryDeviceCache = new HashMap<>();
Map<String, EmsDevicesSetting> clusterDeviceCache = new HashMap<>();
List<String> sortedBatteryIds = new ArrayList<>(batteryDisplayMap.keySet());
Collections.sort(sortedBatteryIds);
for (String batteryDeviceId : sortedBatteryIds) {
if (StringUtils.isEmpty(batteryDeviceId)) {
continue;
}
if (StringUtils.isNotEmpty(targetBatteryId) && !batteryDeviceId.equals(targetBatteryId)) {
continue;
}
EmsDevicesSetting batterySetting = batteryDeviceCache.computeIfAbsent(
batteryDeviceId, key -> emsDevicesSettingMapper.getDeviceBySiteAndDeviceId(key, siteId));
String currentClusterDeviceId = batterySetting == null ? "" : StringUtils.trimToEmpty(batterySetting.getParentId());
if (StringUtils.isNotEmpty(targetClusterDeviceId) && !targetClusterDeviceId.equals(currentClusterDeviceId)) {
continue;
}
if (StringUtils.isNotEmpty(targetStackDeviceId)) {
if (StringUtils.isEmpty(currentClusterDeviceId)) {
continue;
}
EmsDevicesSetting clusterSetting = clusterDeviceCache.computeIfAbsent(
currentClusterDeviceId, key -> emsDevicesSettingMapper.getDeviceBySiteAndDeviceId(key, siteId));
String parentStackDeviceId = clusterSetting == null ? "" : StringUtils.trimToEmpty(clusterSetting.getParentId());
if (!targetStackDeviceId.equals(parentStackDeviceId)) {
continue;
}
}
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
fillBatteryValueFromProjectDisplay(batteryDataStatsVo, batteryDisplayMap.get(batteryDeviceId));
batteryDataStatsVo.setDeviceId(batteryDeviceId);
batteryDataStatsVo.setClusterDeviceId(currentClusterDeviceId);
batteryDataStatsListVo.add(batteryDataStatsVo);
log.info("getClusterDataInfoList battery from projectDisplay list, siteId={}, batteryDeviceId={}, clusterDeviceId={}, voltage={}, temperature={}, soc={}, soh={}, voltagePointId={}, temperaturePointId={}, socPointId={}, sohPointId={}, dataTimestamp={}",
siteId, batteryDeviceId, currentClusterDeviceId, batteryDataStatsVo.getVoltage(),
batteryDataStatsVo.getTemperature(), batteryDataStatsVo.getSoc(),
batteryDataStatsVo.getSoh(), batteryDataStatsVo.getVoltagePointId(),
batteryDataStatsVo.getTemperaturePointId(), batteryDataStatsVo.getSocPointId(),
batteryDataStatsVo.getSohPointId(), batteryDataStatsVo.getDataTimestamp());
}
if (batteryDataStatsListVo.isEmpty()) {
log.info("getClusterDataInfoList fallback to realtime cache, siteId={}, stackDeviceId={}, clusterDeviceId={}, batteryId={}",
siteId, targetStackDeviceId, targetClusterDeviceId, targetBatteryId);
appendBatteryFromRealtimeCache(siteId, targetStackDeviceId, targetClusterDeviceId, targetBatteryId,
batteryDisplayMap, batteryDataStatsListVo);
}
log.info("getClusterDataInfoList end, siteId={}, stackDeviceId={}, clusterDeviceId={}, batteryId={}, total={}",
siteId, targetStackDeviceId, targetClusterDeviceId, targetBatteryId, batteryDataStatsListVo.size());
return batteryDataStatsListVo;
}
private void appendBatteryFromRealtimeCache(String siteId,
String targetStackDeviceId,
String targetClusterDeviceId,
String targetBatteryId,
Map<String, Map<String, SiteMonitorProjectDisplayVo>> batteryDisplayMap,
List<BatteryDataStatsListVo> targetList) {
if (StringUtils.isBlank(siteId) || targetList == null) {
return;
}
List<Map<String, Object>> clusterIds = new ArrayList<>();
if (StringUtils.isEmpty(clusterDeviceId)) {
clusterIds = emsDevicesSettingMapper.getClusterIdsByFuzzyQuery(siteId, DeviceCategory.CLUSTER.getCode(),stackDeviceId);
} else {
if (StringUtils.isNotBlank(targetClusterDeviceId)) {
Map<String, Object> map = new HashMap<>();
map.put("id", clusterDeviceId);
map.put("id", targetClusterDeviceId);
clusterIds.add(map);
} else {
clusterIds = emsDevicesSettingMapper.getClusterIdsByFuzzyQuery(siteId,
DeviceCategory.CLUSTER.getCode(), StringUtils.trimToEmpty(targetStackDeviceId));
}
if (CollectionUtils.isEmpty(clusterIds)) {
return;
}
for (Map<String, Object> clusterDevice : clusterIds) {
// 从redis取单个簇详细数据
String clusterId = clusterDevice.get("id").toString();
if (clusterDevice == null || clusterDevice.get("id") == null) {
continue;
}
String clusterId = StringUtils.trimToEmpty(String.valueOf(clusterDevice.get("id")));
if (StringUtils.isBlank(clusterId)) {
continue;
}
List<EmsBatteryData> batteryDataList = redisCache.getCacheList(RedisKeyConstants.BATTERY + siteId + "_" + clusterId);
if (batteryDataList != null) {
for (EmsBatteryData batteryData : batteryDataList) {
// 判断是否需要筛选batteryId不为空时才进行匹配
if (batteryId == null || batteryId.trim().isEmpty()) {
// 空值情况:直接添加所有数据
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
batteryDataStatsListVo.add(batteryDataStatsVo);
} else {
// 有值情况:只添加匹配的数据
if (batteryId.equals(batteryData.getDeviceId())) {
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
batteryDataStatsListVo.add(batteryDataStatsVo);
// 找到匹配项后可提前退出当前簇的循环
break;
}
}
}
if (CollectionUtils.isEmpty(batteryDataList)) {
continue;
}
for (EmsBatteryData batteryData : batteryDataList) {
if (batteryData == null) {
continue;
}
String currentBatteryId = StringUtils.trimToEmpty(batteryData.getDeviceId());
if (StringUtils.isNotEmpty(targetBatteryId) && !targetBatteryId.equals(currentBatteryId)) {
continue;
}
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
if (StringUtils.isBlank(batteryDataStatsVo.getClusterDeviceId())) {
batteryDataStatsVo.setClusterDeviceId(clusterId);
}
fillBatteryPointIdFromProjectDisplay(batteryDataStatsVo, batteryDisplayMap == null ? null : batteryDisplayMap.get(currentBatteryId));
targetList.add(batteryDataStatsVo);
}
}
//TODO 临时删除排序
// 排序
// List<BatteryDataStatsListVo> sortedList = batteryDataStatsListVo.stream()
// .sorted((u1, u2) -> Integer.parseInt(u1.getClusterDeviceId()) - Integer.parseInt(u2.getClusterDeviceId()))
// .collect(Collectors.toList());
return batteryDataStatsListVo;
}
private void fillBatteryDetailByLatestPointMapping(String siteId,
String deviceId,
BatteryDataStatsListVo target,
Map<String, EmsSiteMonitorPointMatch> mappingByFieldAndDevice,
Map<String, InfluxPointDataWriter.PointValue> latestPointCache) {
if (StringUtils.isAnyBlank(siteId, deviceId) || target == null || mappingByFieldAndDevice == null) {
return;
}
BeanWrapper beanWrapper = new BeanWrapperImpl(target);
Date latestDataTime = null;
for (PropertyDescriptor pd : beanWrapper.getPropertyDescriptors()) {
if (pd == null || StringUtils.isBlank(pd.getName()) || pd.getWriteMethod() == null) {
continue;
}
String fieldCode = pd.getName();
if (BATTERY_DETAIL_META_FIELDS.contains(fieldCode)) {
continue;
}
EmsSiteMonitorPointMatch pointMatch = resolvePointMatchByFieldAndDevice(mappingByFieldAndDevice, fieldCode, deviceId);
if (pointMatch == null) {
continue;
}
Object fieldValue;
Date valueTime = null;
if (USE_FIXED_DISPLAY_YES == (pointMatch.getUseFixedDisplay() == null ? 0 : pointMatch.getUseFixedDisplay())
&& StringUtils.isNotBlank(pointMatch.getFixedDataPoint())) {
fieldValue = pointMatch.getFixedDataPoint().trim();
} else {
InfluxPointDataWriter.PointValue latestValue = getLatestPointValueByPointId(siteId, pointMatch.getDataPoint(), latestPointCache);
if (latestValue == null || latestValue.getPointValue() == null) {
continue;
}
fieldValue = latestValue.getPointValue();
valueTime = latestValue.getDataTime();
}
Object convertedValue = convertFieldValueByType(fieldValue, pd.getPropertyType());
if (convertedValue == null) {
continue;
}
beanWrapper.setPropertyValue(fieldCode, convertedValue);
if (valueTime != null && (latestDataTime == null || valueTime.after(latestDataTime))) {
latestDataTime = valueTime;
}
}
if (latestDataTime != null) {
target.setDataTimestamp(latestDataTime);
}
}
private Map<String, Map<String, SiteMonitorProjectDisplayVo>> buildBatteryDisplayMap(List<SiteMonitorProjectDisplayVo> displayList) {
Map<String, Map<String, SiteMonitorProjectDisplayVo>> result = new HashMap<>();
if (CollectionUtils.isEmpty(displayList)) {
return result;
}
for (SiteMonitorProjectDisplayVo item : displayList) {
if (item == null) {
continue;
}
String menuCode = StringUtils.trimToEmpty(item.getMenuCode());
String deviceId = StringUtils.trimToEmpty(item.getDeviceId());
String fieldCode = StringUtils.trimToEmpty(item.getFieldCode());
if (!MENU_SBJK_DTDC.equals(menuCode) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(fieldCode)) {
continue;
}
Map<String, SiteMonitorProjectDisplayVo> fieldMap = result.computeIfAbsent(deviceId, key -> new HashMap<>());
fieldMap.put(fieldCode, item);
String normalizedFieldCode = normalizeBatteryFieldCode(fieldCode);
if (StringUtils.isNotBlank(normalizedFieldCode)) {
fieldMap.put(normalizedFieldCode, item);
}
}
return result;
}
private String normalizeBatteryFieldCode(String fieldCode) {
String normalized = StringUtils.trimToEmpty(fieldCode);
if (StringUtils.isBlank(normalized)) {
return normalized;
}
int splitIndex = normalized.lastIndexOf("__");
if (splitIndex >= 0 && splitIndex + 2 < normalized.length()) {
normalized = normalized.substring(splitIndex + 2);
}
return normalized.toLowerCase();
}
private void fillBatteryValueFromProjectDisplay(BatteryDataStatsListVo target,
Map<String, SiteMonitorProjectDisplayVo> fieldMap) {
if (target == null || fieldMap == null || fieldMap.isEmpty()) {
return;
}
SiteMonitorProjectDisplayVo voltageVo = fieldMap.get("voltage");
SiteMonitorProjectDisplayVo temperatureVo = fieldMap.get("temperature");
SiteMonitorProjectDisplayVo socVo = fieldMap.get("soc");
SiteMonitorProjectDisplayVo sohVo = fieldMap.get("soh");
target.setVoltagePointId(voltageVo == null ? null : StringUtils.trimToNull(voltageVo.getDataPoint()));
target.setTemperaturePointId(temperatureVo == null ? null : StringUtils.trimToNull(temperatureVo.getDataPoint()));
target.setSocPointId(socVo == null ? null : StringUtils.trimToNull(socVo.getDataPoint()));
target.setSohPointId(sohVo == null ? null : StringUtils.trimToNull(sohVo.getDataPoint()));
if (voltageVo != null && StringUtils.isNotBlank(voltageVo.getFieldValue())) {
target.setVoltage(StringUtils.getBigDecimal(voltageVo.getFieldValue()));
}
if (temperatureVo != null && StringUtils.isNotBlank(temperatureVo.getFieldValue())) {
target.setTemperature(StringUtils.getBigDecimal(temperatureVo.getFieldValue()));
}
if (socVo != null && StringUtils.isNotBlank(socVo.getFieldValue())) {
target.setSoc(StringUtils.getBigDecimal(socVo.getFieldValue()));
}
if (sohVo != null && StringUtils.isNotBlank(sohVo.getFieldValue())) {
target.setSoh(StringUtils.getBigDecimal(sohVo.getFieldValue()));
}
Date latest = null;
latest = pickLaterTime(latest, voltageVo == null ? null : voltageVo.getValueTime());
latest = pickLaterTime(latest, temperatureVo == null ? null : temperatureVo.getValueTime());
latest = pickLaterTime(latest, socVo == null ? null : socVo.getValueTime());
latest = pickLaterTime(latest, sohVo == null ? null : sohVo.getValueTime());
if (latest != null) {
target.setDataTimestamp(latest);
}
}
private void fillBatteryPointIdFromProjectDisplay(BatteryDataStatsListVo target,
Map<String, SiteMonitorProjectDisplayVo> fieldMap) {
if (target == null || fieldMap == null || fieldMap.isEmpty()) {
return;
}
SiteMonitorProjectDisplayVo voltageVo = fieldMap.get("voltage");
SiteMonitorProjectDisplayVo temperatureVo = fieldMap.get("temperature");
SiteMonitorProjectDisplayVo socVo = fieldMap.get("soc");
SiteMonitorProjectDisplayVo sohVo = fieldMap.get("soh");
target.setVoltagePointId(voltageVo == null ? null : StringUtils.trimToNull(voltageVo.getDataPoint()));
target.setTemperaturePointId(temperatureVo == null ? null : StringUtils.trimToNull(temperatureVo.getDataPoint()));
target.setSocPointId(socVo == null ? null : StringUtils.trimToNull(socVo.getDataPoint()));
target.setSohPointId(sohVo == null ? null : StringUtils.trimToNull(sohVo.getDataPoint()));
}
private Date pickLaterTime(Date left, Date right) {
if (left == null) {
return right;
}
if (right == null) {
return left;
}
return right.after(left) ? right : left;
}
// 获取单站的最大最小温度和电压单体数据id

View File

@ -175,6 +175,7 @@
from ems_devices_setting t
where t.site_id = #{siteId}
and t.parent_id = #{parentId}
order by t.device_id
</select>
<select id="getAllBatteryDeviceBySiteId" parameterType="String" resultType="com.xzzn.ems.domain.EmsDevicesSetting">
@ -206,9 +207,10 @@
<select id="getDeviceBySiteAndDeviceId" parameterType="String" resultMap="EmsDevicesSettingResult">
<include refid="selectEmsDevicesSettingVo"/>
where device_id = #{deviceId}
AND site_id = #{siteId}
limit 1
where site_id = #{siteId}
<if test="deviceId != null and deviceId != ''">
AND device_id = #{deviceId}
</if>
</select>
<select id="getAmmeterNameList" parameterType="String" resultType="java.util.Map">
@ -235,4 +237,4 @@
and site_id = #{siteId}
</if>
</select>
</mapper>
</mapper>

View File

@ -31,6 +31,12 @@
where site_id = #{siteId}
</delete>
<delete id="deleteBySiteIdAndDeviceId">
delete from ems_site_monitor_point_match
where site_id = #{siteId}
and device_id = #{deviceId}
</delete>
<insert id="insertBatch">
insert into ems_site_monitor_point_match
(site_id, field_code, device_id, data_point, fixed_data_point, use_fixed_display, create_by, create_time, update_by, update_time)