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();
|
@Resource
|
private TSystemConfigurationMapper systemConfigurationMapper;
|
|
// 储能相关参数
|
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 boolean isFirstChargeCompleted = false;
|
private boolean isSecondChargeCompleted = false;
|
// 放电次数计数器
|
private int dischargeCount = 0;
|
// 当前阶段总放电量
|
private BigDecimal currentPhaseDischarge = BigDecimal.ZERO;
|
|
// 定时任务方法 - 能量刷新
|
@Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
|
public synchronized void refreshValue() {
|
LocalTime now = LocalTime.now();
|
|
// 第一轮充电阶段 (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;
|
}
|
|
// 随机增量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 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;
|
}
|
}
|
|
// 重置任务(每天凌晨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);
|
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);
|
|
}
|
|
|
}
|