运行策略测试修改
This commit is contained in:
@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* 轮询设备-通过modbus协议读取数据
|
||||
@ -145,8 +146,9 @@ public class ModbusPoller {
|
||||
addDeviceOfflineRecord(siteId, config.getDeviceNumber());
|
||||
return;
|
||||
}
|
||||
List<String> rawValuEmptyList = new ArrayList<>();
|
||||
Map<String, Object> data = modbusProcessor.readDataFromDevice(config, master);
|
||||
// 在这里处理采集到的数据
|
||||
// 在这里处理采集到的数据空
|
||||
config.getTags().forEach(tag -> {
|
||||
Object rawValue = data.get(tag.getKey());
|
||||
if (rawValue != null) {
|
||||
@ -167,10 +169,14 @@ public class ModbusPoller {
|
||||
data.put(tag.getKey(), value);
|
||||
}
|
||||
} else {
|
||||
data.put(tag.getKey(), rawValue);
|
||||
log.warn("tag:{},数据为空: {}", tag.getKey(), rawValue);
|
||||
// data.put(tag.getKey(), rawValue);
|
||||
// log.warn("tag:{},数据为空: {}", tag.getKey(), rawValue);
|
||||
rawValuEmptyList.add("tag: " + tag.getKey() + ",数据为空: " + rawValue);
|
||||
}
|
||||
});
|
||||
if (!rawValuEmptyList.isEmpty()) {
|
||||
log.warn("设备 {} 数据为空: {}", config.getDeviceName(), JSON.toJSONString(rawValuEmptyList));
|
||||
}
|
||||
log.info("Data from {}: {}", config.getDeviceName(), data);
|
||||
String deviceNumber = config.getDeviceNumber();
|
||||
//处理数据并发送MQTT消息、保存Redis数据和数据入库
|
||||
@ -179,7 +185,7 @@ public class ModbusPoller {
|
||||
}
|
||||
|
||||
private void processingData(Map<String, Object> data, String deviceNumber) {
|
||||
if (data == null || data.size() == 0) {
|
||||
if (CollectionUtils.isEmpty(data)) {
|
||||
// 增加失败计数
|
||||
int failureCount = deviceFailureCounts.getOrDefault(deviceNumber, 0) + 1;
|
||||
deviceFailureCounts.put(deviceNumber, failureCount);
|
||||
@ -213,7 +219,7 @@ public class ModbusPoller {
|
||||
try {
|
||||
mqttPublisher.publish(topic, Collections.singletonList(json).toString(), 0);
|
||||
} catch (MqttException e) {
|
||||
log.error("MQTT消息发布失败: {}", json.toJSONString(), e);
|
||||
log.error("MQTT消息发布失败: {}, reason code: {}", json.toJSONString(), e.getReasonCode() ,e);
|
||||
}
|
||||
log.info("已发送数据: {}", json.toJSONString());
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -51,6 +52,8 @@ import org.springframework.stereotype.Component;
|
||||
public class StrategyPoller {
|
||||
private static final Logger logger = LoggerFactory.getLogger(StrategyPoller.class);
|
||||
|
||||
private static final ConcurrentHashMap<Long, Boolean> strategyLocks = new ConcurrentHashMap<>();
|
||||
|
||||
// SOC 上下限值,默认为0%-100%
|
||||
private static final BigDecimal SOC_DOWN = new BigDecimal(0);
|
||||
private static final BigDecimal SOC_UP = new BigDecimal(100);
|
||||
@ -86,16 +89,23 @@ public class StrategyPoller {
|
||||
logger.info("开始执行运行策略数据轮询...");
|
||||
List<StrategyRunningVo> strategyRunningVoList = emsStrategyRunningMapper.getPendingPollerStrategy(null);
|
||||
strategyRunningVoList.forEach(strategyVo -> {
|
||||
try {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
processData(strategyVo);
|
||||
})
|
||||
.exceptionally(e -> {
|
||||
logger.error("运行策略{}轮询异常", strategyVo.getId(), e);
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
logger.error("运行策略{}任务失败", strategyVo.getId(), e);
|
||||
Long strategyId = strategyVo.getId();
|
||||
if (strategyLocks.putIfAbsent(strategyId, true) == null) {
|
||||
try {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
processData(strategyVo);
|
||||
})
|
||||
.exceptionally(e -> {
|
||||
logger.error("运行策略{}轮询异常", strategyVo.getId(), e);
|
||||
return null;
|
||||
})
|
||||
.thenRun(() -> strategyLocks.remove(strategyId));
|
||||
} catch (Exception e) {
|
||||
logger.error("运行策略{}任务失败", strategyVo.getId(), e);
|
||||
strategyLocks.remove(strategyId);
|
||||
}
|
||||
} else {
|
||||
logger.info("策略{}已在处理中,跳过重复执行", strategyId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -159,7 +169,7 @@ public class StrategyPoller {
|
||||
logger.info("当前站点: {} 未配置PCS设备", siteId);
|
||||
continue;
|
||||
}
|
||||
// 判断SOC上限和下限是否在范围内
|
||||
// 判断SOC上下限
|
||||
if (isSocInRange(emsStrategyTemp)) {
|
||||
BigDecimal avgChargeDischargePower = emsStrategyTemp.getChargeDischargePower().divide(new BigDecimal(pcsDeviceList.size()));
|
||||
for (EmsDevicesSetting pcsDevice : pcsDeviceList) {
|
||||
@ -168,8 +178,8 @@ public class StrategyPoller {
|
||||
logger.info("当前站点: {}, PCS设备: {} 未获取电池簇数量", siteId, pcsDevice.getDeviceId());
|
||||
continue;
|
||||
}
|
||||
// 平均功率值,根据电池簇数量进行平均分配
|
||||
avgChargeDischargePower = avgChargeDischargePower.divide(new BigDecimal(pcsSetting.getClusterNum()));
|
||||
// 功率默认放大10倍,平均功率值,根据电池簇数量进行平均分配
|
||||
avgChargeDischargePower = avgChargeDischargePower.multiply(new BigDecimal(10)).divide(new BigDecimal(pcsSetting.getClusterNum()));
|
||||
// 根据充电状态,处理数据
|
||||
if (ChargeStatus.CHARGING.getCode().equals(emsStrategyTemp.getChargeStatus())) {
|
||||
// 发送Modbus命令控制设备-充电
|
||||
@ -189,7 +199,7 @@ public class StrategyPoller {
|
||||
powerDownType = lastStrategyLog.getPowerDownType();
|
||||
}
|
||||
|
||||
// 查询电网电表的正向有功功率
|
||||
// 查询电网电表的正向有功功率,36kW-50kW范围内,稳定运行,低于36kW,降功率,高于50kW,增加功率
|
||||
EmsAmmeterData emsAmmeterData = emsAmmeterDataMapper.getLastData(emsStrategyTemp.getSiteId(), SiteDevice.LOAD.name());
|
||||
if (emsAmmeterData == null || emsAmmeterData.getTotalActivePower() == null) {
|
||||
logger.info("当前站点: {}, 未获取到最新电表数据", emsStrategyTemp.getSiteId());
|
||||
@ -202,8 +212,8 @@ public class StrategyPoller {
|
||||
chargeDischargePower = chargeDischargePower.subtract(power);
|
||||
powerDownType = 0;
|
||||
} else {
|
||||
// 判断是否需要增加功率
|
||||
if (powerDownType != null && emsAmmeterData.getTotalActivePower().compareTo(ANTI_REVERSE_UP) < 0) {
|
||||
// 判断是否需要增加功率,
|
||||
if (powerDownType != null && emsAmmeterData.getTotalActivePower().compareTo(ANTI_REVERSE_UP) > 0) {
|
||||
if (chargeDischargePower.compareTo(avgChargeDischargePower) == 0) {
|
||||
// 功率增加到平均值则停止
|
||||
continue;
|
||||
@ -364,13 +374,19 @@ public class StrategyPoller {
|
||||
String siteId = pcsDevice.getSiteId();
|
||||
String deviceId = pcsDevice.getDeviceId();
|
||||
List<EmsStrategyLog> strategyLogList = getStrategyLog(deviceId, chargeStatus.getCode(), emsStrategyTemp, needAntiReverseFlow);
|
||||
if (CollectionUtils.isNotEmpty(strategyLogList) && (!ChargeStatus.DISCHARGING.equals(chargeStatus) || !needAntiReverseFlow)) {
|
||||
logger.info("当前站点: {}, PCS设备: {} 当前时间段已存在策略执行记录,不再重复执行", siteId, deviceId);
|
||||
continue;
|
||||
if (CollectionUtils.isNotEmpty(strategyLogList)) {
|
||||
boolean isExist = true;
|
||||
if (ChargeStatus.DISCHARGING.equals(chargeStatus) && needAntiReverseFlow) {
|
||||
isExist = false;
|
||||
}
|
||||
if (isExist) {
|
||||
logger.info("当前站点: {}, PCS设备: {} 当前时间段已存在策略执行记录,不再重复执行", siteId, deviceId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 每次操作先判断设备工作状态
|
||||
if (WorkStatus.ABNORMAL.getCode().equals(pcsDevice.getWorkStatus())) {
|
||||
if (StringUtils.isEmpty(pcsDevice.getWorkStatus()) || WorkStatus.ABNORMAL.getCode().equals(pcsDevice.getWorkStatus())) {
|
||||
// 设备故障,不发送指令
|
||||
continue;
|
||||
} else if (WorkStatus.STOP.getCode().equals(pcsDevice.getWorkStatus())) {
|
||||
@ -381,6 +397,7 @@ public class StrategyPoller {
|
||||
} else {
|
||||
// 充、放电,则先开机设备
|
||||
switchDevice(pcsDevice, pcsSetting, WorkStatus.NORMAL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,10 +408,11 @@ public class StrategyPoller {
|
||||
boolean result = modbusProcessor.writeDataToDevice(deviceConfig);
|
||||
if (!result) {
|
||||
logger.info("当前站点: {}, PCS设备: {} modbus控制设备{}指令发送失败", siteId, deviceId, chargeStatus.getInfo());
|
||||
}
|
||||
if (ChargeStatus.STANDBY.equals(chargeStatus)) {
|
||||
// 待机,先写功率值,再关机
|
||||
switchDevice(pcsDevice, pcsSetting, WorkStatus.STOP);
|
||||
} else {
|
||||
if (ChargeStatus.STANDBY.equals(chargeStatus)) {
|
||||
// 待机,先写功率值,再关机
|
||||
switchDevice(pcsDevice, pcsSetting, WorkStatus.STOP);
|
||||
}
|
||||
}
|
||||
// 记录策略执行日志
|
||||
saveStrategyLog(deviceId, chargeDischargePower, chargeStatus.getCode(), emsStrategyTemp, needAntiReverseFlow, powerDownType);
|
||||
@ -406,7 +424,7 @@ public class StrategyPoller {
|
||||
String siteId = pcsDevice.getSiteId();
|
||||
String deviceId = pcsDevice.getDeviceId();
|
||||
pcsDevice.setWorkStatus(workStatus.getCode());
|
||||
DeviceConfig deviceConfig = getDeviceConfig(siteId, deviceId, pcsDevice, pcsSetting , null, 0);
|
||||
DeviceConfig deviceConfig = getDeviceConfig(siteId, deviceId, pcsDevice, pcsSetting , null, 1);
|
||||
if (deviceConfig == null) {
|
||||
return;
|
||||
}
|
||||
@ -428,7 +446,7 @@ public class StrategyPoller {
|
||||
return now.equals(startLocalTime) || (now.isAfter(startLocalTime) && now.isBefore(endLocalTime));
|
||||
}
|
||||
|
||||
// 判断SOC上限和下限是否在范围内
|
||||
// 判断SOC上限和下限
|
||||
private boolean isSocInRange(EmsStrategyTemp emsStrategyTemp) {
|
||||
BigDecimal socDown = SOC_DOWN;
|
||||
BigDecimal socUp = SOC_UP;
|
||||
@ -438,9 +456,20 @@ public class StrategyPoller {
|
||||
}
|
||||
// 查询电池堆(BMSD) SOC
|
||||
EmsBatteryStack emsBatteryStack = emsBatteryStackMapper.getSiteSumStackInfo(emsStrategyTemp.getSiteId());
|
||||
if (emsBatteryStack != null && emsBatteryStack.getStackSoc() != null) {
|
||||
return emsBatteryStack.getStackSoc().compareTo(socDown) > 0 && emsBatteryStack.getStackSoc().compareTo(socUp) < 0;
|
||||
if (emsBatteryStack == null || emsBatteryStack.getStackSoc() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 充电阶段判断SOC上限值
|
||||
if (ChargeStatus.CHARGING.getCode().equals(emsStrategyTemp.getChargeStatus()) && emsBatteryStack.getStackSoc().compareTo(socUp) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 放电阶段判断SOC下限值
|
||||
if (ChargeStatus.DISCHARGING.getCode().equals(emsStrategyTemp.getChargeStatus()) && emsBatteryStack.getStackSoc().compareTo(socDown) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user