| | |
| | | private TSystemConfigurationMapper systemConfigurationMapper; |
| | | |
| | | // 储能相关参数 |
| | | private final BigDecimal storageMaxMorning = new BigDecimal("115"); // 凌晨到8点储能最大值 |
| | | private final BigDecimal storageMaxAfternoon = new BigDecimal("115"); // 12点后储能最大值 |
| | | private final BigDecimal dischargeMaxMorning = new BigDecimal("90"); // 上午放电最大值 |
| | | private final BigDecimal dischargeMaxAfternoon = new BigDecimal("90"); // 下午放电最大值 |
| | | private final BigDecimal storageMax = new BigDecimal("115"); // 储能最大值 |
| | | private final BigDecimal targetDischargeTotal = new BigDecimal("97.75"); // 目标总放电量 |
| | | private final double minChargeIncrement = 0.5; // 充电最小增量 |
| | | private final double maxChargeIncrement = 1.0; // 充电最大增量 |
| | | private final int minDischargeTimes = 3; // 最小放电次数 |
| | | private final int maxDischargeTimes = 4; // 最大放电次数 |
| | | private final BigDecimal minDischargeAmount = new BigDecimal("25"); // 单次最小放电量 |
| | | private final BigDecimal maxDischargeAmount = new BigDecimal("35"); // 单次最大放电量 |
| | | |
| | | private final double minIncrement = 0.5; // 最小增量(储能/放电共用) |
| | | private final double maxIncrement = 1.0; // 最大增量(储能/放电共用) |
| | | |
| | | // 充电阶段标记 |
| | | private boolean isFirstChargeCompleted = false; |
| | | private boolean isSecondChargeCompleted = false; |
| | | // 放电次数计数器 |
| | | private int dischargeCount = 0; |
| | | // 当前阶段总放电量 |
| | | private BigDecimal currentPhaseDischarge = BigDecimal.ZERO; |
| | | |
| | | // 定时任务方法 - 能量刷新 |
| | | @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次(原15分钟改为1分钟) |
| | | @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 |
| | | public synchronized void refreshValue() { |
| | | LocalTime now = LocalTime.now(); |
| | | // 根据时间段执行不同逻辑 |
| | | if (isInStorageMorning(now)) { // 00:00-7:59 储能阶段 |
| | | handleStoragePhase(storageMaxMorning, BigDecimal.ZERO); |
| | | } else if (isInDischargeMorning(now)) { // 10:00-11:59 上午放电阶段 |
| | | handleDischargePhase(dischargeMaxMorning); |
| | | } else if (isInStorageAfternoon(now)) { // 12:00-16:59 下午储能阶段 |
| | | handleStoragePhase(storageMaxAfternoon, getTodayDischarge()); |
| | | } else if (isInDischargeAfternoon(now)) { // 17:00-21:59 下午放电阶段 |
| | | handleDischargePhase(dischargeMaxAfternoon); |
| | | |
| | | // 第一轮充电阶段 (0:00-3:00) |
| | | if (now.isAfter(LocalTime.of(0, 0)) && now.isBefore(LocalTime.of(3, 0))) { |
| | | handleChargePhase(); |
| | | } |
| | | // 第一轮放电阶段 (3:10开始,每10分钟一次) |
| | | else if (now.isAfter(LocalTime.of(3, 0)) && now.isBefore(LocalTime.of(15, 0)) |
| | | && now.getMinute() % 10 == 0 && now.getSecond() == 0) { |
| | | handleDischargePhase(false); |
| | | } |
| | | // 第二轮充电阶段 (15:00-17:00) |
| | | else if (now.isAfter(LocalTime.of(15, 0)) && now.isBefore(LocalTime.of(17, 0))) { |
| | | handleChargePhase(); |
| | | } |
| | | // 第二轮放电阶段 (17:10开始,每10分钟一次) |
| | | else if (now.isAfter(LocalTime.of(17, 0)) && now.isBefore(LocalTime.of(23, 59)) |
| | | && now.getMinute() % 10 == 0 && now.getSecond() == 0) { |
| | | handleDischargePhase(true); |
| | | } |
| | | } |
| | | |
| | | // 储能阶段处理逻辑 |
| | | public void handleStoragePhase(BigDecimal maxValue, BigDecimal dischargeValue) { |
| | | BigDecimal todayStorage=getTodayStorage();//当前储能值 |
| | | BigDecimal availableSpace = maxValue.subtract(todayStorage.subtract(dischargeValue));//115-(储能-放能) 当前可上涨空间 |
| | | // 充电阶段处理逻辑 |
| | | private void handleChargePhase() { |
| | | BigDecimal todayStorage = getTodayStorage(); |
| | | |
| | | // 随机增量0.5—1.0 |
| | | BigDecimal increment = randomBigDecimal(minIncrement,maxIncrement); |
| | | BigDecimal newStorage; |
| | | if (availableSpace.compareTo(increment) >= 0 ) { |
| | | //可用空间大于等于当前增量 |
| | | newStorage = todayStorage.add(increment) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | }else { |
| | | //可用空间不足当前增量 |
| | | newStorage = maxValue.add(dischargeValue);//115 + 放能 (如:上午放90,下午就只能充90) |
| | | // 如果已经充满,则不再充电 |
| | | if (todayStorage.compareTo(storageMax) >= 0) { |
| | | if (!isFirstChargeCompleted && todayStorage.compareTo(storageMax) >= 0) { |
| | | isFirstChargeCompleted = true; |
| | | System.out.println("第一轮充电已完成,当前储能: " + todayStorage); |
| | | } else if (!isSecondChargeCompleted && todayStorage.compareTo(storageMax.multiply(new BigDecimal("2"))) >= 0) { |
| | | isSecondChargeCompleted = true; |
| | | System.out.println("第二轮充电已完成,当前储能: " + todayStorage); |
| | | } |
| | | if (newStorage.compareTo(todayStorage)==0){ |
| | | //新增值等于当前储能值 说明已达到最大值,没必要更新了 |
| | | return; |
| | | } |
| | | |
| | | // 随机增量0.5-1.0 |
| | | BigDecimal increment = randomBigDecimal(minChargeIncrement, maxChargeIncrement); |
| | | BigDecimal newStorage = todayStorage.add(increment).setScale(2, RoundingMode.HALF_UP); |
| | | |
| | | // 确保不超过最大值 |
| | | BigDecimal maxAllowed = isFirstChargeCompleted ? storageMax.multiply(new BigDecimal("2")) : storageMax; |
| | | if (newStorage.compareTo(maxAllowed) > 0) { |
| | | newStorage = maxAllowed; |
| | | } |
| | | |
| | | updateStorageValue(newStorage); |
| | | System.out.printf("储能阶段:当前时间 %s,今日储能:%.2f%n", LocalTime.now(), newStorage); |
| | | System.out.printf("充电阶段:当前时间 %s,今日储能:%.2f%n", LocalTime.now(), newStorage); |
| | | } |
| | | |
| | | // 放电阶段处理逻辑 |
| | | private void handleDischargePhase(BigDecimal maxDischarge) { |
| | | BigDecimal currentDischarge = getTodayDischarge();//当前放电量 |
| | | BigDecimal todayStorage = getTodayStorage();//储能量 |
| | | //今日储能-115,就是耗能(基数),在这个基数上加90 |
| | | BigDecimal baseDischarge = todayStorage.subtract(storageMaxAfternoon); |
| | | BigDecimal newMaxDischarge = baseDischarge.add(maxDischarge);//上限 基数+90 |
| | | |
| | | // 随机增量0.5—1.0 |
| | | BigDecimal increment = randomBigDecimal(minIncrement,maxIncrement); |
| | | BigDecimal newDischarge = currentDischarge.add(increment);//当前值 + 增量 |
| | | if (newDischarge.compareTo(newMaxDischarge) >=0) { |
| | | //超出 用最大值 |
| | | newDischarge = newMaxDischarge; |
| | | } |
| | | |
| | | if (newDischarge.compareTo(currentDischarge)==0){ |
| | | //新增值等于当前值,说明已超出,没必要更新了 |
| | | private void handleDischargePhase(boolean isSecondPhase) { |
| | | // 如果是第二轮放电且第一轮未完成,则不执行 |
| | | if (isSecondPhase && !isFirstChargeCompleted) { |
| | | return; |
| | | } |
| | | |
| | | // 如果已经达到目标放电量,则不再放电 |
| | | BigDecimal todayDischarge = getTodayDischarge(); |
| | | BigDecimal target = isSecondPhase ? targetDischargeTotal.multiply(new BigDecimal("2")) : targetDischargeTotal; |
| | | if (todayDischarge.compareTo(target) >= 0) { |
| | | return; |
| | | } |
| | | |
| | | // 如果是新一轮放电阶段,重置计数器 |
| | | if (currentPhaseDischarge.compareTo(BigDecimal.ZERO) == 0) { |
| | | dischargeCount = 0; |
| | | } |
| | | |
| | | // 计算剩余需要放电的量 |
| | | BigDecimal remainingDischarge = target.subtract(todayDischarge); |
| | | |
| | | // 随机本次放电量 (25-35) |
| | | BigDecimal dischargeAmount = randomBigDecimal(minDischargeAmount.doubleValue(), maxDischargeAmount.doubleValue()); |
| | | |
| | | // 如果剩余量不足,则只放剩余量 |
| | | if (dischargeAmount.compareTo(remainingDischarge) > 0) { |
| | | dischargeAmount = remainingDischarge; |
| | | } |
| | | |
| | | // 更新放电量 |
| | | BigDecimal newDischarge = todayDischarge.add(dischargeAmount).setScale(2, RoundingMode.HALF_UP); |
| | | updateDischargeValue(newDischarge); |
| | | System.out.printf("放电阶段:当前时间 %s,今日放电:%.2f%n", LocalTime.now(), newDischarge); |
| | | |
| | | // 更新当前阶段放电总量 |
| | | currentPhaseDischarge = currentPhaseDischarge.add(dischargeAmount); |
| | | dischargeCount++; |
| | | |
| | | System.out.printf("放电阶段:当前时间 %s,第%d次放电,本次放电:%.2f,今日总放电:%.2f%n", |
| | | LocalTime.now(), dischargeCount, dischargeAmount, newDischarge); |
| | | |
| | | // 如果达到最大放电次数或完成目标放电量,重置当前阶段放电量 |
| | | if (dischargeCount >= maxDischargeTimes || remainingDischarge.subtract(dischargeAmount).compareTo(BigDecimal.ZERO) <= 0) { |
| | | currentPhaseDischarge = BigDecimal.ZERO; |
| | | } |
| | | } |
| | | |
| | | // 重置任务(每天凌晨0点) |
| | | @Scheduled(cron = "0 0 0 * * ?") |
| | | public void reset() { |
| | | // 重置所有状态 |
| | | isFirstChargeCompleted = false; |
| | | isSecondChargeCompleted = false; |
| | | dischargeCount = 0; |
| | | currentPhaseDischarge = BigDecimal.ZERO; |
| | | |
| | | // 初始化今日储能和放电为0 |
| | | updateStorageValue(BigDecimal.ZERO); |
| | | updateDischargeValue(BigDecimal.ZERO); |
| | |
| | | // 转换为两位小数的 BigDecimal |
| | | return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | // 更新今日储能值到数据库 |
| | | private void updateStorageValue(BigDecimal value) { |
| | | updateConfigField("todayStorage", value); |
| | | } |
| | | |
| | | // 更新今日放电值到数据库(原逻辑保留) |
| | | private void updateDischargeValue(BigDecimal value) { |
| | | updateConfigField("todayDischarge", value); |
| | | } |
| | | |
| | | // 通用配置更新方法 |
| | | private void updateConfigField(String field, BigDecimal value) { |
| | |
| | | return time.isAfter(LocalTime.of(17, 0)) && time.isBefore(LocalTime.of(22, 0)); |
| | | } |
| | | |
| | | |
| | | // 更新今日储能值到数据库 |
| | | private void updateStorageValue(BigDecimal value) { |
| | | updateConfigField("todayStorage", value); |
| | | } |
| | | |
| | | // 更新今日放电值到数据库(原逻辑保留) |
| | | private void updateDischargeValue(BigDecimal value) { |
| | | updateConfigField("todayDischarge", value); |
| | | } |
| | | |
| | | public BigDecimal getTodayStorage() { |
| | | TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne( |
| | | new LambdaQueryWrapper<TSystemConfiguration>() |