From 6ecf7171775a04bbcb52c9943bcafce699c837a7 Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期三, 25 六月 2025 11:11:26 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java | 351 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 306 insertions(+), 45 deletions(-) diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java index 9a90ec5..3ad10be 100644 --- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java @@ -1,72 +1,333 @@ package com.ruoyi.other.util; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.other.api.domain.TSystemConfiguration; +import com.ruoyi.other.mapper.TSystemConfigurationMapper; +import com.ruoyi.other.vo.ScreenStorageConfigVO; +import lombok.Getter; +import lombok.Setter; import lombok.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDate; import java.time.LocalTime; +import java.util.List; import java.util.Random; + +/** + * 定时任务:储能放电情况 光伏发电情况 + */ @Service public class EnergyRefreshService { private final Random random = new Random(); - private BigDecimal currentValue; - + @Resource + private TSystemConfigurationMapper systemConfigurationMapper; - private final BigDecimal targetLow = new BigDecimal("85"); + // 储能相关参数 + 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 BigDecimal targetHigh = new BigDecimal("87"); - + // 充电阶段标记 + private boolean isFirstChargeCompleted = false; + private boolean isSecondChargeCompleted = false; + // 放电次数计数器 + private int dischargeCount = 0; + // 当前阶段总放电量 + private BigDecimal currentPhaseDischarge = BigDecimal.ZERO; - private final int maxIncrement = 10; - - private boolean isRunning = true; // 控制任务是否继续执行 - - public EnergyRefreshService() { - this.currentValue = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); - } - - // 定时任务方法 - @Scheduled(cron = "${0 */15 * * * ?}")//15分钟执行一次 + // 定时任务方法 - 能量刷新 + @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 public synchronized void refreshValue() { - // 检查是否已停止或达到目标范围 - if (!isRunning || isWithinTargetRange(currentValue)) { - isRunning = false; - return; - } - - // 检查当前时间是否在允许的时间段内 LocalTime now = LocalTime.now(); - boolean isInMorning = now.isAfter(LocalTime.of(10, 0)) && now.isBefore(LocalTime.of(12, 0)); - boolean isInAfternoon = now.isAfter(LocalTime.of(15, 0)) && now.isBefore(LocalTime.of(21, 0)); - - if (!isInMorning && !isInAfternoon) { + + // 第一轮充电阶段 (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); + } + } + + // 充电阶段处理逻辑 + private void handleChargePhase() { + BigDecimal todayStorage = getTodayStorage(); + + // 如果已经充满,则不再充电 + 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); + } return; } - - // 生成随机增量并更新值 - int increment = random.nextInt(maxIncrement + 1); - currentValue = currentValue.add(BigDecimal.valueOf(increment)) - .setScale(2, RoundingMode.HALF_UP); - - System.out.printf("定时刷新:当前时间 %s,当前值:%.2f%n", now, currentValue); + + // 随机增量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); } - - private boolean isWithinTargetRange(BigDecimal value) { - return value.compareTo(targetLow) >= 0 && value.compareTo(targetHigh) <= 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); + + // 更新当前阶段放电总量 + 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; + } } - - // 提供获取当前值的方法 - public BigDecimal getCurrentValue() { - return currentValue; - } - - // 重置任务 + + // 重置任务(每天凌晨0点) + @Scheduled(cron = "0 0 0 * * ?") public void reset() { - this.currentValue = BigDecimal.ZERO; - this.isRunning = true; + // 重置所有状态 + isFirstChargeCompleted = false; + isSecondChargeCompleted = false; + dischargeCount = 0; + currentPhaseDischarge = BigDecimal.ZERO; + + // 初始化今日储能和放电为0 + updateStorageValue(BigDecimal.ZERO); + updateDischargeValue(BigDecimal.ZERO); + System.out.println("每日重置完成:今日储能和放电已清零"); + + + + TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne(new LambdaQueryWrapper<TSystemConfiguration>() + .eq(TSystemConfiguration::getType,4)); + sysConfig.setContent("0"); + systemConfigurationMapper.updateById(sysConfig); + + + } + + /** + * 生成指定范围内的随机 BigDecimal(两位小数) + * @param min 最小值(包含) + * @param max 最大值(包含) + * @return 随机 BigDecimal + */ + private BigDecimal randomBigDecimal(double min, double max) { + // 生成 [0, 1) 随机数 + double randomValue = random.nextDouble(); + // 计算范围内的随机值 + double range = max - min; + double value = min + (randomValue * range); + + // 转换为两位小数的 BigDecimal + return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP); + } + + + // 通用配置更新方法 + private void updateConfigField(String field, BigDecimal value) { + TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne( + new LambdaQueryWrapper<TSystemConfiguration>() + .eq(TSystemConfiguration::getType, 3) + ); + if (sysConfig != null) { + ScreenStorageConfigVO configVO = JSON.parseObject(sysConfig.getContent(), ScreenStorageConfigVO.class); + if ("todayStorage".equals(field)) { + configVO.setTodayStorage(value); + } else { + configVO.setTodayDischarge(value); + } + sysConfig.setContent(JSON.toJSONString(configVO)); + systemConfigurationMapper.updateById(sysConfig); + } + } + // 时间段判断方法 + private boolean isInStorageMorning(LocalTime time) { + return time.isAfter(LocalTime.of(0, 0)) && time.isBefore(LocalTime.of(8, 0)); + } + + private boolean isInDischargeMorning(LocalTime time) { + return time.isAfter(LocalTime.of(10, 0)) && time.isBefore(LocalTime.of(12, 0)); + } + + private boolean isInStorageAfternoon(LocalTime time) { + return time.isAfter(LocalTime.of(12, 0)) && time.isBefore(LocalTime.of(17, 0)); + } + + private boolean isInDischargeAfternoon(LocalTime time) { + 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>() + .eq(TSystemConfiguration::getType, 3) + ); + if (sysConfig != null) { + ScreenStorageConfigVO configVO = JSON.parseObject(sysConfig.getContent(), ScreenStorageConfigVO.class); + return configVO.getTodayStorage(); + } + return BigDecimal.ZERO; + } + + public BigDecimal getTodayDischarge() { + TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne( + new LambdaQueryWrapper<TSystemConfiguration>() + .eq(TSystemConfiguration::getType, 3) + ); + if (sysConfig != null) { + ScreenStorageConfigVO configVO = JSON.parseObject(sysConfig.getContent(), ScreenStorageConfigVO.class); + return configVO.getTodayDischarge(); + } + return BigDecimal.ZERO; + } + + + + + /** + *光伏发电和消纳 + */ +// @Scheduled(cron = "0 */1 * * * ?") // 每分钟点执行 + public void refreshValueOne() { + // 判断时间是否在6:00到8:59 + LocalTime now = LocalTime.now(); +// if (now.isAfter(LocalTime.of(6, 0)) && now.isBefore(LocalTime.of(8, 59))) { +// List<TSystemConfiguration> sysConfigs = systemConfigurationMapper.selectList(new LambdaQueryWrapper<TSystemConfiguration>() +// .in(TSystemConfiguration::getType,4,5)); +// TSystemConfiguration sysConfig = sysConfigs.stream().filter(e -> e.getType() == 4).findFirst().orElse(null); +// +// sysConfig.setContent(new BigDecimal(sysConfig.getContent()).add(new BigDecimal("0.5")).toString()); +// systemConfigurationMapper.updateById(sysConfig); +// +// +// TSystemConfiguration sysConfig1 = sysConfigs.stream().filter(e -> e.getType() == 5).findFirst().orElse(null); +// String string = new BigDecimal(sysConfig1.getContent()).add(new BigDecimal("0.5")).toString(); +// sysConfig1.setContent(string); +// systemConfigurationMapper.updateById(sysConfig1); +// // 在6:00到8:59之间,不执行 +// return; +// } + // 9:00-16:59每分钟增加随机3 到 3.5 + if (now.isAfter(LocalTime.of(6, 0)) && now.isBefore(LocalTime.of(12, 0))) { + List<TSystemConfiguration> sysConfigs = systemConfigurationMapper.selectList(new LambdaQueryWrapper<TSystemConfiguration>() + .in(TSystemConfiguration::getType,4,5)); + + TSystemConfiguration sysConfig = sysConfigs.stream().filter(e -> e.getType() == 4).findFirst().orElse(null); + sysConfig.setContent( new BigDecimal(sysConfig.getContent()).add(new BigDecimal(0.1 + (1 - 0.1) * random.nextDouble()) + .setScale(2, RoundingMode.HALF_UP)).toString()); + systemConfigurationMapper.updateById(sysConfig); + + + TSystemConfiguration sysConfig1 = sysConfigs.stream().filter(e -> e.getType() == 5).findFirst().orElse(null); + String string = new BigDecimal(sysConfig1.getContent()).add(new BigDecimal(0.1 + (1 - 0.1) * random.nextDouble())).toString(); + sysConfig1.setContent(string); + systemConfigurationMapper.updateById(sysConfig1); + return; + } + + //17:00-18:59 每分钟增加0.5 +// if (now.isAfter(LocalTime.of(17, 0)) && now.isBefore(LocalTime.of(18, 59))) { +// List<TSystemConfiguration> sysConfigs = systemConfigurationMapper.selectList(new LambdaQueryWrapper<TSystemConfiguration>() +// .in(TSystemConfiguration::getType,4,5)); +// +// TSystemConfiguration sysConfig = sysConfigs.stream().filter(e -> e.getType() == 4).findFirst().orElse(null); +// +// sysConfig.setContent(new BigDecimal(sysConfig.getContent()).add(new BigDecimal("0.5")).toString()); +// systemConfigurationMapper.updateById(sysConfig); +// +// +// TSystemConfiguration sysConfig1 = sysConfigs.stream().filter(e -> e.getType() == 5).findFirst().orElse(null); +// String string = new BigDecimal(sysConfig1.getContent()).add(new BigDecimal("0.5")).toString(); +// sysConfig1.setContent(string); +// systemConfigurationMapper.updateById(sysConfig1); +// } + } + + + public static void main(String[] args) { + Random random = new Random(); + BigDecimal bigDecimal = new BigDecimal(0.1 + (1 - 0.1) * random.nextDouble()); + System.out.println(bigDecimal); + } -- Gitblit v1.7.1