dev #4
@ -208,9 +208,7 @@ public class EmsSiteMonitorController extends BaseController{
|
|||||||
{
|
{
|
||||||
startPage();
|
startPage();
|
||||||
SiteBatteryDataList siteBatteryDataList = new SiteBatteryDataList();
|
SiteBatteryDataList siteBatteryDataList = new SiteBatteryDataList();
|
||||||
// 簇最大最小单体id数据
|
|
||||||
List<BMSBatteryDataList> clusterBatteryDataList = iSingleSiteService.getClusterBatteryList(siteId,stackDeviceId,clusterDeviceId);
|
|
||||||
siteBatteryDataList.setClusterList(clusterBatteryDataList);
|
|
||||||
// 单体电池数据
|
// 单体电池数据
|
||||||
List<BatteryDataStatsListVo> List = iSingleSiteService.getClusterDataInfoList(clusterDeviceId,siteId,stackDeviceId,batteryId);
|
List<BatteryDataStatsListVo> List = iSingleSiteService.getClusterDataInfoList(clusterDeviceId,siteId,stackDeviceId,batteryId);
|
||||||
// 对batteryList进行分页处理
|
// 对batteryList进行分页处理
|
||||||
|
|||||||
@ -14,7 +14,9 @@ import com.xzzn.common.utils.StringUtils;
|
|||||||
import com.xzzn.ems.domain.EmsAlarmRecords;
|
import com.xzzn.ems.domain.EmsAlarmRecords;
|
||||||
import com.xzzn.ems.domain.EmsFaultProtectionPlan;
|
import com.xzzn.ems.domain.EmsFaultProtectionPlan;
|
||||||
import com.xzzn.ems.domain.vo.ProtectionConstraintVo;
|
import com.xzzn.ems.domain.vo.ProtectionConstraintVo;
|
||||||
|
import com.xzzn.ems.domain.vo.ProtectionPlanVo;
|
||||||
import com.xzzn.ems.domain.vo.ProtectionSettingVo;
|
import com.xzzn.ems.domain.vo.ProtectionSettingVo;
|
||||||
|
import com.xzzn.ems.domain.vo.ProtectionSettingsGroupVo;
|
||||||
import com.xzzn.ems.mapper.EmsAlarmRecordsMapper;
|
import com.xzzn.ems.mapper.EmsAlarmRecordsMapper;
|
||||||
import com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper;
|
import com.xzzn.ems.mapper.EmsFaultProtectionPlanMapper;
|
||||||
import com.xzzn.ems.service.IEmsFaultProtectionPlanService;
|
import com.xzzn.ems.service.IEmsFaultProtectionPlanService;
|
||||||
@ -75,11 +77,12 @@ public class ProtectionPlanTask {
|
|||||||
if (StringUtils.isEmpty(siteId)) {
|
if (StringUtils.isEmpty(siteId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<ProtectionSettingVo> protSettings = parseProtectionSettings(plan.getProtectionSettings());
|
ProtectionSettingsGroupVo settingGroup = parseProtectionSettings(plan.getProtectionSettings());
|
||||||
if (CollectionUtils.isEmpty(protSettings)) {
|
if (CollectionUtils.isEmpty(settingGroup.getFaultSettings())
|
||||||
|
&& CollectionUtils.isEmpty(settingGroup.getReleaseSettings())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dealWithProtectionPlan(plan, protSettings);
|
dealWithProtectionPlan(plan, settingGroup);
|
||||||
}
|
}
|
||||||
refreshProtectionConstraintCache(planList);
|
refreshProtectionConstraintCache(planList);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -88,20 +91,22 @@ public class ProtectionPlanTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SyncAfterInsert
|
@SyncAfterInsert
|
||||||
private void dealWithProtectionPlan(EmsFaultProtectionPlan plan, List<ProtectionSettingVo> protSettings) {
|
private void dealWithProtectionPlan(EmsFaultProtectionPlan plan, ProtectionSettingsGroupVo settingGroup) {
|
||||||
logger.info("<轮询保护方案> 站点:{},方案ID:{}", plan.getSiteId(), plan.getId());
|
logger.info("<轮询保护方案> 站点:{},方案ID:{}", plan.getSiteId(), plan.getId());
|
||||||
String siteId = plan.getSiteId();
|
String siteId = plan.getSiteId();
|
||||||
Integer isAlertAlarm = plan.getIsAlert();
|
Integer isAlertAlarm = plan.getIsAlert();
|
||||||
|
List<ProtectionSettingVo> faultSettings = settingGroup.getFaultSettings();
|
||||||
|
List<ProtectionSettingVo> releaseSettings = settingGroup.getReleaseSettings();
|
||||||
Long status = plan.getStatus();
|
Long status = plan.getStatus();
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
status = ProtPlanStatus.STOP.getCode();
|
status = ProtPlanStatus.STOP.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Objects.equals(status, ProtPlanStatus.STOP.getCode())) {
|
if (Objects.equals(status, ProtPlanStatus.STOP.getCode())) {
|
||||||
if (checkIsNeedIssuedPlan(protSettings, siteId)) {
|
if (checkIsNeedIssuedPlan(faultSettings, siteId)) {
|
||||||
int faultDelay = safeDelaySeconds(plan.getFaultDelaySeconds(), 0);
|
int faultDelay = safeDelaySeconds(plan.getFaultDelaySeconds(), 0);
|
||||||
scheduledExecutorService.schedule(() -> {
|
scheduledExecutorService.schedule(() -> {
|
||||||
if (!checkIsNeedIssuedPlan(protSettings, siteId)) {
|
if (!checkIsNeedIssuedPlan(faultSettings, siteId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Integer.valueOf(1).equals(isAlertAlarm)) {
|
if (Integer.valueOf(1).equals(isAlertAlarm)) {
|
||||||
@ -117,7 +122,7 @@ public class ProtectionPlanTask {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkIsNeedCancelPlan(protSettings, siteId)) {
|
if (checkIsNeedCancelPlan(releaseSettings, siteId)) {
|
||||||
int releaseDelay = safeDelaySeconds(plan.getReleaseDelaySeconds(), 0);
|
int releaseDelay = safeDelaySeconds(plan.getReleaseDelaySeconds(), 0);
|
||||||
scheduledExecutorService.schedule(() -> {
|
scheduledExecutorService.schedule(() -> {
|
||||||
if (Integer.valueOf(1).equals(isAlertAlarm)) {
|
if (Integer.valueOf(1).equals(isAlertAlarm)) {
|
||||||
@ -146,14 +151,58 @@ public class ProtectionPlanTask {
|
|||||||
return delay.intValue();
|
return delay.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ProtectionSettingVo> parseProtectionSettings(String settingsJson) {
|
private ProtectionSettingsGroupVo parseProtectionSettings(String settingsJson) {
|
||||||
if (StringUtils.isEmpty(settingsJson)) {
|
if (StringUtils.isEmpty(settingsJson)) {
|
||||||
|
return ProtectionSettingsGroupVo.empty();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (settingsJson.trim().startsWith("[")) {
|
||||||
|
List<ProtectionSettingVo> legacy = objectMapper.readValue(
|
||||||
|
settingsJson,
|
||||||
|
new TypeReference<List<ProtectionSettingVo>>() {}
|
||||||
|
);
|
||||||
|
ProtectionSettingsGroupVo groupVo = ProtectionSettingsGroupVo.empty();
|
||||||
|
groupVo.setFaultSettings(legacy);
|
||||||
|
groupVo.setReleaseSettings(legacy);
|
||||||
|
return groupVo;
|
||||||
|
}
|
||||||
|
ProtectionSettingsGroupVo groupVo = objectMapper.readValue(settingsJson, ProtectionSettingsGroupVo.class);
|
||||||
|
if (groupVo == null) {
|
||||||
|
return ProtectionSettingsGroupVo.empty();
|
||||||
|
}
|
||||||
|
if (groupVo.getFaultSettings() == null) {
|
||||||
|
groupVo.setFaultSettings(new ArrayList<>());
|
||||||
|
}
|
||||||
|
if (groupVo.getReleaseSettings() == null) {
|
||||||
|
groupVo.setReleaseSettings(new ArrayList<>());
|
||||||
|
}
|
||||||
|
return groupVo;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析保护前提失败,json:{}", settingsJson, e);
|
||||||
|
return ProtectionSettingsGroupVo.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProtectionPlanVo> parseProtectionPlan(String planJson) {
|
||||||
|
if (StringUtils.isEmpty(planJson)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(settingsJson, new TypeReference<List<ProtectionSettingVo>>() {});
|
if (planJson.trim().startsWith("[")) {
|
||||||
|
List<ProtectionPlanVo> plans = objectMapper.readValue(
|
||||||
|
planJson,
|
||||||
|
new TypeReference<List<ProtectionPlanVo>>() {}
|
||||||
|
);
|
||||||
|
return plans == null ? new ArrayList<>() : plans;
|
||||||
|
}
|
||||||
|
ProtectionPlanVo plan = objectMapper.readValue(planJson, ProtectionPlanVo.class);
|
||||||
|
List<ProtectionPlanVo> plans = new ArrayList<>();
|
||||||
|
if (plan != null) {
|
||||||
|
plans.add(plan);
|
||||||
|
}
|
||||||
|
return plans;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("解析保护前提失败,json:{}", settingsJson, e);
|
logger.error("解析执行保护失败,json:{}", planJson, e);
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,9 +305,98 @@ public class ProtectionPlanTask {
|
|||||||
vo.setPowerLimitRatio(BigDecimal.ZERO);
|
vo.setPowerLimitRatio(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 执行保护配置优先于描述文本配置
|
||||||
|
List<ProtectionPlanVo> protectionPlans = parseProtectionPlan(plan.getProtectionPlan());
|
||||||
|
applyCapabilityByProtectionPlan(vo, protectionPlans);
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyCapabilityByProtectionPlan(ProtectionConstraintVo vo, List<ProtectionPlanVo> protectionPlans) {
|
||||||
|
if (CollectionUtils.isEmpty(protectionPlans)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ProtectionPlanVo item : protectionPlans) {
|
||||||
|
if (item == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String marker = ((item.getPointName() == null ? "" : item.getPointName()) + " "
|
||||||
|
+ (item.getPoint() == null ? "" : item.getPoint())).toLowerCase();
|
||||||
|
if (StringUtils.isEmpty(marker)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsAny(marker, "降功率", "derate", "power_limit", "powerlimit")) {
|
||||||
|
BigDecimal ratio = parseDerateRatioByPlan(item);
|
||||||
|
if (ratio != null) {
|
||||||
|
vo.setPowerLimitRatio(minRatio(vo.getPowerLimitRatio(), ratio));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCapabilityEnabled(item.getValue())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsAny(marker, "禁止充放电", "forbid_charge_discharge", "disable_charge_discharge")) {
|
||||||
|
vo.setAllowCharge(false);
|
||||||
|
vo.setAllowDischarge(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "禁止充电", "forbid_charge", "disable_charge")) {
|
||||||
|
vo.setAllowCharge(false);
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "禁止放电", "forbid_discharge", "disable_discharge")) {
|
||||||
|
vo.setAllowDischarge(false);
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "允许充电", "allow_charge")) {
|
||||||
|
vo.setAllowCharge(true);
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "允许放电", "allow_discharge")) {
|
||||||
|
vo.setAllowDischarge(true);
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "待机", "standby")) {
|
||||||
|
vo.setForceStandby(true);
|
||||||
|
}
|
||||||
|
if (containsAny(marker, "关机", "停机", "切断", "shutdown", "stop")) {
|
||||||
|
vo.setForceStop(true);
|
||||||
|
vo.setForceStandby(true);
|
||||||
|
vo.setAllowCharge(false);
|
||||||
|
vo.setAllowDischarge(false);
|
||||||
|
vo.setPowerLimitRatio(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal parseDerateRatioByPlan(ProtectionPlanVo planVo) {
|
||||||
|
BigDecimal value = planVo.getValue();
|
||||||
|
if (value == null || value.compareTo(BigDecimal.ZERO) < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value.compareTo(BigDecimal.ONE) <= 0) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.compareTo(new BigDecimal("100")) <= 0) {
|
||||||
|
return value.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCapabilityEnabled(BigDecimal value) {
|
||||||
|
return value == null || value.compareTo(BigDecimal.ZERO) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsAny(String text, String... markers) {
|
||||||
|
if (StringUtils.isEmpty(text) || markers == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String marker : markers) {
|
||||||
|
if (!StringUtils.isEmpty(marker) && text.contains(marker)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private BigDecimal parseDerateRatio(String text) {
|
private BigDecimal parseDerateRatio(String text) {
|
||||||
if (StringUtils.isEmpty(text)) {
|
if (StringUtils.isEmpty(text)) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -575,9 +575,6 @@ public class StrategyPoller {
|
|||||||
ChargeStatus targetStatus,
|
ChargeStatus targetStatus,
|
||||||
EmsStrategyRuntimeConfig runtimeConfig,
|
EmsStrategyRuntimeConfig runtimeConfig,
|
||||||
ProtectionConstraintVo constraint) {
|
ProtectionConstraintVo constraint) {
|
||||||
if (!Integer.valueOf(1).equals(runtimeConfig.getProtectInterveneEnable())) {
|
|
||||||
return new StrategyCommandDecision(targetStatus, safePower(targetPower));
|
|
||||||
}
|
|
||||||
if (constraint == null || nullSafeInt(constraint.getLevel()) <= 0) {
|
if (constraint == null || nullSafeInt(constraint.getLevel()) <= 0) {
|
||||||
return new StrategyCommandDecision(targetStatus, safePower(targetPower));
|
return new StrategyCommandDecision(targetStatus, safePower(targetPower));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,18 @@ public class BatteryDataStatsListVo {
|
|||||||
|
|
||||||
/** SOH (%) */
|
/** SOH (%) */
|
||||||
private BigDecimal 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")
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
private Date dataTimestamp;
|
private Date dataTimestamp;
|
||||||
@ -71,6 +83,38 @@ public class BatteryDataStatsListVo {
|
|||||||
this.soh = soh;
|
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() {
|
public Date getDataTimestamp() {
|
||||||
return dataTimestamp;
|
return dataTimestamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,5 +13,7 @@ public interface EmsSiteMonitorPointMatchMapper {
|
|||||||
|
|
||||||
int deleteBySiteId(@Param("siteId") String siteId);
|
int deleteBySiteId(@Param("siteId") String siteId);
|
||||||
|
|
||||||
|
int deleteBySiteIdAndDeviceId(@Param("siteId") String siteId, @Param("deviceId") String deviceId);
|
||||||
|
|
||||||
int insertBatch(@Param("list") List<EmsSiteMonitorPointMatch> list);
|
int insertBatch(@Param("list") List<EmsSiteMonitorPointMatch> list);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,9 +216,127 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
|
|||||||
pcsSetting.setDeviceSettingId(devicesSetting.getId());
|
pcsSetting.setDeviceSettingId(devicesSetting.getId());
|
||||||
emsPcsSettingMapper.insertEmsPcsSetting(pcsSetting);
|
emsPcsSettingMapper.insertEmsPcsSetting(pcsSetting);
|
||||||
}
|
}
|
||||||
|
initSiteMonitorPointMappingsForNewDevice(devicesSetting);
|
||||||
return result;
|
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
|
* @param devicesSetting
|
||||||
@ -277,9 +396,26 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public int deleteEmsDevicesSettingById(Long id){
|
public int deleteEmsDevicesSettingById(Long id){
|
||||||
|
if (id == null) {
|
||||||
return emsDevicesMapper.deleteEmsDevicesSettingById(id);
|
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
|
@Override
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import com.xzzn.ems.domain.EmsBatteryData;
|
|||||||
import com.xzzn.ems.domain.EmsBatteryStack;
|
import com.xzzn.ems.domain.EmsBatteryStack;
|
||||||
import com.xzzn.ems.domain.EmsCoolingData;
|
import com.xzzn.ems.domain.EmsCoolingData;
|
||||||
import com.xzzn.ems.domain.EmsDhData;
|
import com.xzzn.ems.domain.EmsDhData;
|
||||||
|
import com.xzzn.ems.domain.EmsDevicesSetting;
|
||||||
import com.xzzn.ems.domain.EmsEmsData;
|
import com.xzzn.ems.domain.EmsEmsData;
|
||||||
import com.xzzn.ems.domain.EmsPcsBranchData;
|
import com.xzzn.ems.domain.EmsPcsBranchData;
|
||||||
import com.xzzn.ems.domain.EmsSiteMonitorPointMatch;
|
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.EmsStrategyRunningMapper;
|
||||||
import com.xzzn.ems.mapper.EmsStrategyTempMapper;
|
import com.xzzn.ems.mapper.EmsStrategyTempMapper;
|
||||||
import com.xzzn.ems.service.IEmsEnergyPriceConfigService;
|
import com.xzzn.ems.service.IEmsEnergyPriceConfigService;
|
||||||
|
import com.xzzn.ems.service.IEmsDeviceSettingService;
|
||||||
import com.xzzn.ems.service.ISingleSiteService;
|
import com.xzzn.ems.service.ISingleSiteService;
|
||||||
import com.xzzn.ems.service.InfluxPointDataWriter;
|
import com.xzzn.ems.service.InfluxPointDataWriter;
|
||||||
import com.xzzn.ems.utils.DevicePointMatchDataProcessor;
|
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(
|
private static final Set<String> PCS_DETAIL_META_FIELDS = new HashSet<>(Arrays.asList(
|
||||||
"siteId", "deviceId", "deviceName", "alarmNum", "pcsBranchInfoList", "dataUpdateTime"
|
"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 = "温度";
|
private static final String CLUSTER_DATA_TEP = "温度";
|
||||||
|
|
||||||
@ -135,6 +141,8 @@ public class SingleSiteServiceImpl implements ISingleSiteService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IEmsEnergyPriceConfigService iEmsEnergyPriceConfigService;
|
private IEmsEnergyPriceConfigService iEmsEnergyPriceConfigService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private IEmsDeviceSettingService iEmsDeviceSettingService;
|
||||||
|
@Autowired
|
||||||
private DevicePointMatchDataProcessor devicePointMatchDataProcessor;
|
private DevicePointMatchDataProcessor devicePointMatchDataProcessor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1007,45 +1015,292 @@ public class SingleSiteServiceImpl implements ISingleSiteService {
|
|||||||
public List<BatteryDataStatsListVo> getClusterDataInfoList(String clusterDeviceId,String siteId,
|
public List<BatteryDataStatsListVo> getClusterDataInfoList(String clusterDeviceId,String siteId,
|
||||||
String stackDeviceId, String batteryId) {
|
String stackDeviceId, String batteryId) {
|
||||||
List<BatteryDataStatsListVo> batteryDataStatsListVo = new ArrayList<>();
|
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<>();
|
List<Map<String, Object>> clusterIds = new ArrayList<>();
|
||||||
if (StringUtils.isEmpty(clusterDeviceId)) {
|
if (StringUtils.isNotBlank(targetClusterDeviceId)) {
|
||||||
clusterIds = emsDevicesSettingMapper.getClusterIdsByFuzzyQuery(siteId, DeviceCategory.CLUSTER.getCode(),stackDeviceId);
|
|
||||||
} else {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("id", clusterDeviceId);
|
map.put("id", targetClusterDeviceId);
|
||||||
clusterIds.add(map);
|
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) {
|
for (Map<String, Object> clusterDevice : clusterIds) {
|
||||||
// 从redis取单个簇详细数据
|
if (clusterDevice == null || clusterDevice.get("id") == null) {
|
||||||
String clusterId = clusterDevice.get("id").toString();
|
continue;
|
||||||
|
}
|
||||||
|
String clusterId = StringUtils.trimToEmpty(String.valueOf(clusterDevice.get("id")));
|
||||||
|
if (StringUtils.isBlank(clusterId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
List<EmsBatteryData> batteryDataList = redisCache.getCacheList(RedisKeyConstants.BATTERY + siteId + "_" + clusterId);
|
List<EmsBatteryData> batteryDataList = redisCache.getCacheList(RedisKeyConstants.BATTERY + siteId + "_" + clusterId);
|
||||||
if (batteryDataList != null) {
|
if (CollectionUtils.isEmpty(batteryDataList)) {
|
||||||
for (EmsBatteryData batteryData : batteryDataList) {
|
continue;
|
||||||
// 判断是否需要筛选:batteryId不为空时才进行匹配
|
}
|
||||||
if (batteryId == null || batteryId.trim().isEmpty()) {
|
for (EmsBatteryData batteryData : batteryDataList) {
|
||||||
// 空值情况:直接添加所有数据
|
if (batteryData == null) {
|
||||||
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
|
continue;
|
||||||
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
|
}
|
||||||
batteryDataStatsListVo.add(batteryDataStatsVo);
|
String currentBatteryId = StringUtils.trimToEmpty(batteryData.getDeviceId());
|
||||||
} else {
|
if (StringUtils.isNotEmpty(targetBatteryId) && !targetBatteryId.equals(currentBatteryId)) {
|
||||||
// 有值情况:只添加匹配的数据
|
continue;
|
||||||
if (batteryId.equals(batteryData.getDeviceId())) {
|
}
|
||||||
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
|
BatteryDataStatsListVo batteryDataStatsVo = new BatteryDataStatsListVo();
|
||||||
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
|
BeanUtils.copyProperties(batteryData, batteryDataStatsVo);
|
||||||
batteryDataStatsListVo.add(batteryDataStatsVo);
|
if (StringUtils.isBlank(batteryDataStatsVo.getClusterDeviceId())) {
|
||||||
// 找到匹配项后可提前退出当前簇的循环
|
batteryDataStatsVo.setClusterDeviceId(clusterId);
|
||||||
break;
|
}
|
||||||
}
|
fillBatteryPointIdFromProjectDisplay(batteryDataStatsVo, batteryDisplayMap == null ? null : batteryDisplayMap.get(currentBatteryId));
|
||||||
}
|
targetList.add(batteryDataStatsVo);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO 临时删除排序
|
}
|
||||||
// 排序
|
|
||||||
// List<BatteryDataStatsListVo> sortedList = batteryDataStatsListVo.stream()
|
private void fillBatteryDetailByLatestPointMapping(String siteId,
|
||||||
// .sorted((u1, u2) -> Integer.parseInt(u1.getClusterDeviceId()) - Integer.parseInt(u2.getClusterDeviceId()))
|
String deviceId,
|
||||||
// .collect(Collectors.toList());
|
BatteryDataStatsListVo target,
|
||||||
return batteryDataStatsListVo;
|
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
|
// 获取单站的最大最小温度和电压单体数据id
|
||||||
|
|||||||
@ -175,6 +175,7 @@
|
|||||||
from ems_devices_setting t
|
from ems_devices_setting t
|
||||||
where t.site_id = #{siteId}
|
where t.site_id = #{siteId}
|
||||||
and t.parent_id = #{parentId}
|
and t.parent_id = #{parentId}
|
||||||
|
order by t.device_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getAllBatteryDeviceBySiteId" parameterType="String" resultType="com.xzzn.ems.domain.EmsDevicesSetting">
|
<select id="getAllBatteryDeviceBySiteId" parameterType="String" resultType="com.xzzn.ems.domain.EmsDevicesSetting">
|
||||||
@ -206,9 +207,10 @@
|
|||||||
|
|
||||||
<select id="getDeviceBySiteAndDeviceId" parameterType="String" resultMap="EmsDevicesSettingResult">
|
<select id="getDeviceBySiteAndDeviceId" parameterType="String" resultMap="EmsDevicesSettingResult">
|
||||||
<include refid="selectEmsDevicesSettingVo"/>
|
<include refid="selectEmsDevicesSettingVo"/>
|
||||||
where device_id = #{deviceId}
|
where site_id = #{siteId}
|
||||||
AND site_id = #{siteId}
|
<if test="deviceId != null and deviceId != ''">
|
||||||
limit 1
|
AND device_id = #{deviceId}
|
||||||
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getAmmeterNameList" parameterType="String" resultType="java.util.Map">
|
<select id="getAmmeterNameList" parameterType="String" resultType="java.util.Map">
|
||||||
@ -235,4 +237,4 @@
|
|||||||
and site_id = #{siteId}
|
and site_id = #{siteId}
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -31,6 +31,12 @@
|
|||||||
where site_id = #{siteId}
|
where site_id = #{siteId}
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteBySiteIdAndDeviceId">
|
||||||
|
delete from ems_site_monitor_point_match
|
||||||
|
where site_id = #{siteId}
|
||||||
|
and device_id = #{deviceId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
<insert id="insertBatch">
|
<insert id="insertBatch">
|
||||||
insert into ems_site_monitor_point_match
|
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)
|
(site_id, field_code, device_id, data_point, fixed_data_point, use_fixed_display, create_by, create_time, update_by, update_time)
|
||||||
|
|||||||
Reference in New Issue
Block a user