xuhy
昨天 bd1e1c6a99c228ece8ece17be462b81d5494c7a1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
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("每日重置完成:今日储能和放电已清零");
    }
 
    /**
     * 生成指定范围内的随机 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;
    }
 
 
 
 
    public static BigDecimal refreshValueOne = new BigDecimal("0");
    /**
     *光伏发电和消纳
     */
    @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))) {
            refreshValueOne = refreshValueOne.add(new BigDecimal("0.5"));
            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(refreshValueOne.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(9, 0)) && now.isBefore(LocalTime.of(16, 59))) {
            refreshValueOne = refreshValueOne.add(new BigDecimal(3 + (3.5 - 3) * random.nextDouble())
                    .setScale(2, RoundingMode.HALF_UP));
            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(refreshValueOne.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(3 + (3.5 - 3) * 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))) {
            refreshValueOne = refreshValueOne.add(new BigDecimal("0.5"));
            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(refreshValueOne.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);
        }
    }
 
 
 
 
}