| | |
| | | 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(); |
| | | @Resource |
| | | private TSystemConfigurationMapper systemConfigurationMapper; |
| | | |
| | | private final BigDecimal targetLow = new BigDecimal("85"); |
| | | // 储能相关参数 |
| | | 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 targetHigh = new BigDecimal("87"); |
| | | private final double minIncrement = 0.5; // 最小增量(储能/放电共用) |
| | | private final double maxIncrement = 1.0; // 最大增量(储能/放电共用) |
| | | |
| | | |
| | | |
| | | private final int maxIncrement = 10; |
| | | |
| | | private boolean isRunning = true; // 控制任务是否继续执行 |
| | | |
| | | // 定时任务方法 |
| | | @Scheduled(cron = "0 */15 * * * ?")//15分钟执行一次 |
| | | // 定时任务方法 - 能量刷新 |
| | | @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次(原15分钟改为1分钟) |
| | | public synchronized void refreshValue() { |
| | | // 检查当前时间是否在允许的时间段内 |
| | | 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) { |
| | | return; |
| | | // 根据时间段执行不同逻辑 |
| | | 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); |
| | | } |
| | | |
| | | //获取当前值 |
| | | BigDecimal currentValue = getCurrentValue(); |
| | | // 检查是否已停止或达到目标范围 |
| | | if (!isRunning || isWithinTargetRange(currentValue)) { |
| | | isRunning = false; |
| | | return; |
| | | } |
| | | |
| | | if(currentValue.doubleValue()==87){ |
| | | return; |
| | | } |
| | | if(currentValue.doubleValue()>87){ |
| | | updateCurrentValue(new BigDecimal("87")); |
| | | return; |
| | | } |
| | | |
| | | // 生成随机增量并更新值 |
| | | int increment = random.nextInt(maxIncrement + 1); |
| | | currentValue = currentValue.add(BigDecimal.valueOf(increment)) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | //更新值 |
| | | updateCurrentValue(currentValue); |
| | | System.out.printf("定时刷新:当前时间 %s,当前值:%.2f%n", now, currentValue); |
| | | } |
| | | |
| | | private boolean isWithinTargetRange(BigDecimal value) { |
| | | return value.compareTo(targetLow) >= 0 && value.compareTo(targetHigh) <= 0; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前值 |
| | | */ |
| | | public BigDecimal getCurrentValue() { |
| | | //获取系统建设日期和累计储能放电量 |
| | | TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne(new LambdaQueryWrapper<TSystemConfiguration>() |
| | | .eq(TSystemConfiguration::getType,3)); |
| | | //解析 |
| | | ScreenStorageConfigVO configVO = JSON.parseObject(sysConfig.getContent(), ScreenStorageConfigVO.class); |
| | | return configVO.getCurrentValue(); |
| | | // 储能阶段处理逻辑 |
| | | public void handleStoragePhase(BigDecimal maxValue, BigDecimal dischargeValue) { |
| | | BigDecimal todayStorage=getTodayStorage();//当前储能值 |
| | | BigDecimal availableSpace = maxValue.subtract(todayStorage.subtract(dischargeValue));//115-(储能-放能) 当前可上涨空间 |
| | | |
| | | // 随机增量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 (newStorage.compareTo(todayStorage)==0){ |
| | | //新增值等于当前储能值 说明已达到最大值,没必要更新了 |
| | | return; |
| | | } |
| | | updateStorageValue(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){ |
| | | //新增值等于当前值,说明已超出,没必要更新了 |
| | | return; |
| | | } |
| | | updateDischargeValue(newDischarge); |
| | | System.out.printf("放电阶段:当前时间 %s,今日放电:%.2f%n", LocalTime.now(), newDischarge); |
| | | } |
| | | |
| | | /** |
| | | * 更新当前值 |
| | | */ |
| | | private void updateCurrentValue(BigDecimal currentValue) { |
| | | //获取系统建设日期和累计储能放电量 |
| | | TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne(new LambdaQueryWrapper<TSystemConfiguration>() |
| | | .eq(TSystemConfiguration::getType,3)); |
| | | //解析 |
| | | ScreenStorageConfigVO configVO = JSON.parseObject(sysConfig.getContent(), ScreenStorageConfigVO.class); |
| | | //更新 |
| | | configVO.setCurrentValue(currentValue); |
| | | String json = JSON.toJSONString(configVO); |
| | | sysConfig.setContent(json); |
| | | systemConfigurationMapper.updateById(sysConfig); |
| | | } |
| | | |
| | | |
| | | |
| | | // 重置任务 |
| | | @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨0点执行 |
| | | // 重置任务(每天凌晨0点) |
| | | @Scheduled(cron = "0 0 0 * * ?") |
| | | public void reset() { |
| | | BigDecimal currentValue = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); |
| | | updateCurrentValue(currentValue); |
| | | |
| | | refreshValueOne = new BigDecimal("0"); |
| | | TSystemConfiguration sysConfigs = systemConfigurationMapper.selectList(new LambdaQueryWrapper<TSystemConfiguration>() |
| | | .eq(TSystemConfiguration::getType,4)).get(0); |
| | | sysConfigs.setContent("0"); |
| | | systemConfigurationMapper.updateById(sysConfigs); |
| | | |
| | | //更新 |
| | | this.isRunning = true; |
| | | // 初始化今日储能和放电为0 |
| | | updateStorageValue(BigDecimal.ZERO); |
| | | updateDischargeValue(BigDecimal.ZERO); |
| | | System.out.println("每日重置完成:今日储能和放电已清零"); |
| | | } |
| | | |
| | | /** |
| | | * 生成指定范围内的随机 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 updateStorageValue(BigDecimal value) { |
| | | updateConfigField("todayStorage", value); |
| | | } |
| | | |
| | | // 更新今日放电值到数据库(原逻辑保留) |
| | | private void updateDischargeValue(BigDecimal value) { |
| | | updateConfigField("todayDischarge", value); |
| | | } |
| | | |
| | | // 通用配置更新方法 |
| | | 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)); |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public static BigDecimal refreshValueOne = new BigDecimal("0"); |