Ver Fonte

将已停用的 mock 假数据改为注释保留

Co-authored-by: Cursor <cursoragent@cursor.com>
fuyuchuan há 4 dias atrás
pai
commit
18b9f85b01

+ 39 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppBaselineServiceImpl.java

@@ -103,6 +103,7 @@ public class VppBaselineServiceImpl implements VppBaselineService {
         result.setResponseStartTime(startTime);
         result.setResponseStartTime(startTime);
 
 
         if (deviceUuids.isEmpty()) {
         if (deviceUuids.isEmpty()) {
+            // return buildMockResult(result, siteId, responseDate, startTime);
             return result;
             return result;
         }
         }
 
 
@@ -134,6 +135,7 @@ public class VppBaselineServiceImpl implements VppBaselineService {
                 VppBaselineHelper.INTERVAL_MINUTES,
                 VppBaselineHelper.INTERVAL_MINUTES,
                 null);
                 null);
         if (originalBaselineByTime.isEmpty()) {
         if (originalBaselineByTime.isEmpty()) {
+            // return buildMockResult(result, siteId, responseDate, startTime);
             return result;
             return result;
         }
         }
 
 
@@ -214,6 +216,7 @@ public class VppBaselineServiceImpl implements VppBaselineService {
 
 
         List<String> deviceUuids = listControllableDeviceUuids(siteId);
         List<String> deviceUuids = listControllableDeviceUuids(siteId);
         if (deviceUuids.isEmpty()) {
         if (deviceUuids.isEmpty()) {
+            // return buildMockDeclaredCapacityResult(result, siteId, responseDate, startTime, endTime);
             return result;
             return result;
         }
         }
 
 
@@ -256,6 +259,7 @@ public class VppBaselineServiceImpl implements VppBaselineService {
                 VppBaselineHelper.INTERVAL_MINUTES,
                 VppBaselineHelper.INTERVAL_MINUTES,
                 null);
                 null);
         if (historicalAvgByTime.isEmpty()) {
         if (historicalAvgByTime.isEmpty()) {
+            // return buildMockDeclaredCapacityResult(result, siteId, responseDate, startTime, endTime);
             return result;
             return result;
         }
         }
 
 
@@ -269,6 +273,26 @@ public class VppBaselineServiceImpl implements VppBaselineService {
         return result;
         return result;
     }
     }
 
 
+    /*
+    private SiteDeclaredCapacityVO buildMockDeclaredCapacityResult(SiteDeclaredCapacityVO result,
+                                                                 Long siteId,
+                                                                 LocalDate responseDate,
+                                                                 LocalDateTime startTime,
+                                                                 LocalDateTime endTime) {
+        BigDecimal correctionFactorK = VppBaselineHelper.mockCorrectionFactor(siteId, responseDate);
+        result.setReferenceDates(new ArrayList<>());
+        result.setResponseDayType(VppWorkdayHelper.resolveDayType(responseDate));
+        result.setResponseDayTypeLabel(VppWorkdayHelper.resolveDayTypeLabel(responseDate));
+        result.setCorrectionFactorK(correctionFactorK);
+        result.setDeclaredCapacityKw(VppBaselineHelper.mockDeclaredCapacityKw(
+                siteId, responseDate, startTime, endTime, correctionFactorK));
+        result.setPoints(VppBaselineHelper.buildMockDeclaredCapacityPoints(
+                siteId, responseDate, startTime, endTime, correctionFactorK));
+        result.setDataSource("mock");
+        return result;
+    }
+    */
+
     private Map<String, BigDecimal> applyCorrection(Map<String, BigDecimal> originalBaselineByTime,
     private Map<String, BigDecimal> applyCorrection(Map<String, BigDecimal> originalBaselineByTime,
                                                     BigDecimal correctionFactorK) {
                                                     BigDecimal correctionFactorK) {
         Map<String, BigDecimal> corrected = new TreeMap<>();
         Map<String, BigDecimal> corrected = new TreeMap<>();
@@ -279,6 +303,21 @@ public class VppBaselineServiceImpl implements VppBaselineService {
         return corrected;
         return corrected;
     }
     }
 
 
+    /*
+    private SiteBaselineVO buildMockResult(SiteBaselineVO result,
+                                           Long siteId,
+                                           LocalDate responseDate,
+                                           LocalDateTime responseStartTime) {
+        result.setReferenceDates(new ArrayList<>());
+        result.setResponseDayType(VppWorkdayHelper.resolveDayType(responseDate));
+        result.setResponseDayTypeLabel(VppWorkdayHelper.resolveDayTypeLabel(responseDate));
+        result.setCorrectionFactorK(VppBaselineHelper.mockCorrectionFactor(siteId, responseDate));
+        result.setPoints(VppBaselineHelper.buildMockBaselinePoints(siteId, responseDate, responseStartTime));
+        result.setDataSource("mock");
+        return result;
+    }
+    */
+
     private List<String> listControllableDeviceUuids(Long siteId) {
     private List<String> listControllableDeviceUuids(Long siteId) {
         List<VppResourcePoint> resources = resourcePointMapper.selectList(
         List<VppResourcePoint> resources = resourcePointMapper.selectList(
                 new LambdaQueryWrapper<VppResourcePoint>()
                 new LambdaQueryWrapper<VppResourcePoint>()

+ 3 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppCapabilityEvalServiceImpl.java

@@ -173,6 +173,9 @@ public class VppCapabilityEvalServiceImpl implements VppCapabilityEvalService {
             }
             }
             return new LoadCurveBuildResult(Collections.emptyList(), "tsdb");
             return new LoadCurveBuildResult(Collections.emptyList(), "tsdb");
         }
         }
+        // return new LoadCurveBuildResult(
+        //         VppCapabilityEvalHelper.buildLoadCurve(resources, devices, siteId, statDate),
+        //         "mock");
         return new LoadCurveBuildResult(Collections.emptyList(), null);
         return new LoadCurveBuildResult(Collections.emptyList(), null);
     }
     }
 
 

+ 3 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppDrMonitorServiceImpl.java

@@ -257,6 +257,9 @@ public class VppDrMonitorServiceImpl implements VppDrMonitorService {
         if (baseline != null && StringUtils.hasText(baseline.getDataSource())) {
         if (baseline != null && StringUtils.hasText(baseline.getDataSource())) {
             curve.setDataSource(baseline.getDataSource());
             curve.setDataSource(baseline.getDataSource());
         }
         }
+        // if (dataSources.isEmpty()) {
+        //     curve.setDataSource("mock");
+        // }
 
 
         if (baseline == null || CollectionUtils.isEmpty(baseline.getPoints())) {
         if (baseline == null || CollectionUtils.isEmpty(baseline.getPoints())) {
             return curve;
             return curve;

+ 2 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppResourceBoardServiceImpl.java

@@ -194,6 +194,8 @@ public class VppResourceBoardServiceImpl implements VppResourceBoardService {
             item.setDistrict(site.getDistrict());
             item.setDistrict(site.getDistrict());
         }
         }
         applyTsdbMetrics(item, tsdbMetrics, resource.getResourceType());
         applyTsdbMetrics(item, tsdbMetrics, resource.getResourceType());
+        // item.setSocPercent(VppResourceMockHelper.mockSocPercent(resource));
+        // item.setEvcsChargePowerKw(VppResourceMockHelper.mockEvcsChargePowerKw(resource));
     }
     }
 
 
     private void applyTsdbMetrics(ResourceBoardItemVO item, Map<String, BigDecimal> tsdbMetrics, String resourceType) {
     private void applyTsdbMetrics(ResourceBoardItemVO item, Map<String, BigDecimal> tsdbMetrics, String resourceType) {

+ 11 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppResourceOverviewServiceImpl.java

@@ -71,6 +71,7 @@ public class VppResourceOverviewServiceImpl implements VppResourceOverviewServic
 
 
     @Override
     @Override
     public List<AlarmLevelStatVO> getAlarmStats() {
     public List<AlarmLevelStatVO> getAlarmStats() {
+        // return buildAlarmStatsMock();
         return buildAlarmStats();
         return buildAlarmStats();
     }
     }
 
 
@@ -450,6 +451,16 @@ public class VppResourceOverviewServiceImpl implements VppResourceOverviewServic
         return stats;
         return stats;
     }
     }
 
 
+    /*
+    private List<AlarmLevelStatVO> buildAlarmStatsMock() {
+        List<AlarmLevelStatVO> stats = new ArrayList<>();
+        stats.add(buildAlarmStat(1, "紧急", 3L));
+        stats.add(buildAlarmStat(2, "重要", 8L));
+        stats.add(buildAlarmStat(3, "一般", 15L));
+        return stats;
+    }
+    */
+
     private AlarmLevelStatVO buildAlarmStat(int level, String label, long count) {
     private AlarmLevelStatVO buildAlarmStat(int level, String label, long count) {
         AlarmLevelStatVO stat = new AlarmLevelStatVO();
         AlarmLevelStatVO stat = new AlarmLevelStatVO();
         stat.setAlarmLevel(level);
         stat.setAlarmLevel(level);

+ 7 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppResponseMonitorServiceImpl.java

@@ -176,6 +176,7 @@ public class VppResponseMonitorServiceImpl implements VppResponseMonitorService
         LocalDate statDate = parseDate(date);
         LocalDate statDate = parseDate(date);
         ResponseCompareVO result = new ResponseCompareVO();
         ResponseCompareVO result = new ResponseCompareVO();
         result.setDate(statDate.format(DATE_FMT));
         result.setDate(statDate.format(DATE_FMT));
+        // String dataSource = "mock";
         String dataSource = null;
         String dataSource = null;
 
 
         for (Long siteId : ids) {
         for (Long siteId : ids) {
@@ -210,6 +211,9 @@ public class VppResponseMonitorServiceImpl implements VppResponseMonitorService
                                         DrContext drContext) {
                                         DrContext drContext) {
         List<String> deviceUuids = resolveDeviceUuids(resources, devices);
         List<String> deviceUuids = resolveDeviceUuids(resources, devices);
         if (deviceUuids.isEmpty()) {
         if (deviceUuids.isEmpty()) {
+            // return new CurveBuildResult(
+            //         VppResponseMonitorHelper.buildMockCurve(resources, devices, siteId, statDate, declaredCapacityKw),
+            //         "mock");
             return new CurveBuildResult(Collections.emptyList(), null);
             return new CurveBuildResult(Collections.emptyList(), null);
         }
         }
 
 
@@ -242,6 +246,9 @@ public class VppResponseMonitorServiceImpl implements VppResponseMonitorService
                 LocalTime.MIN, LocalTime.of(23, 59, 59),
                 LocalTime.MIN, LocalTime.of(23, 59, 59),
                 VppBaselineHelper.POWER_METRICS, interval, null);
                 VppBaselineHelper.POWER_METRICS, interval, null);
         if (originalBaseline.isEmpty()) {
         if (originalBaseline.isEmpty()) {
+            // return new CurveBuildResult(
+            //         VppResponseMonitorHelper.buildMockCurve(resources, devices, siteId, statDate, declaredCapacityKw),
+            //         "mock");
             return new CurveBuildResult(Collections.emptyList(), "tsdb");
             return new CurveBuildResult(Collections.emptyList(), "tsdb");
         }
         }
 
 

+ 118 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/util/VppBaselineHelper.java

@@ -238,6 +238,49 @@ public final class VppBaselineHelper {
         return VppCapabilityEvalHelper.hasTsdbPowerData(deviceMetricData, POWER_METRICS);
         return VppCapabilityEvalHelper.hasTsdbPowerData(deviceMetricData, POWER_METRICS);
     }
     }
 
 
+    /*
+    public static List<BaselinePointVO> buildMockBaselinePoints(Long siteId,
+                                                                LocalDate responseDate,
+                                                                LocalDateTime responseStartTime) {
+        List<BaselinePointVO> points = new ArrayList<>();
+        long seed = (siteId != null ? siteId : 0L) + responseDate.toEpochDay();
+        for (int minute = 0; minute < 1440; minute += INTERVAL_MINUTES) {
+            LocalTime time = LocalTime.of(minute / 60, minute % 60);
+            String timeKey = time.format(TIME_FMT);
+            double hourFactor = mockHourFactor(time);
+            double noise = 0.9 + pseudoRandom(seed, minute, 0) * 0.2;
+
+            BigDecimal yesterday = scale(BigDecimal.valueOf(900 * hourFactor * noise));
+            BigDecimal original = yesterday.multiply(BigDecimal.valueOf(0.98 + pseudoRandom(seed, minute, 1) * 0.04))
+                    .setScale(2, RoundingMode.HALF_UP);
+            BigDecimal predicted = original.multiply(BigDecimal.valueOf(1.03)).setScale(2, RoundingMode.HALF_UP);
+
+            BaselinePointVO point = new BaselinePointVO();
+            point.setTime(timeKey);
+            point.setPredictedBaselineKw(predicted);
+            point.setYesterdayActualKw(yesterday);
+            if (!responseDate.atTime(time).isAfter(responseStartTime)) {
+                point.setTodayActualKw(scale(original.multiply(BigDecimal.valueOf(1.01 + pseudoRandom(seed, minute, 2) * 0.05))));
+            }
+            points.add(point);
+        }
+        return points;
+    }
+
+    public static BigDecimal mockCorrectionFactor(Long siteId, LocalDate responseDate) {
+        long seed = (siteId != null ? siteId : 0L) + responseDate.toEpochDay();
+        double raw = 0.85 + pseudoRandom(seed, 99, 3) * 0.25;
+        BigDecimal k = BigDecimal.valueOf(raw).setScale(4, RoundingMode.HALF_UP);
+        if (k.compareTo(K_MIN) < 0) {
+            return K_MIN;
+        }
+        if (k.compareTo(K_MAX) > 0) {
+            return K_MAX;
+        }
+        return k;
+    }
+    */
+
     public static String formatDate(LocalDate date) {
     public static String formatDate(LocalDate date) {
         return date.format(DATE_FMT);
         return date.format(DATE_FMT);
     }
     }
@@ -318,6 +361,49 @@ public final class VppBaselineHelper {
         return points;
         return points;
     }
     }
 
 
+    /*
+    public static BigDecimal mockDeclaredCapacityKw(Long siteId,
+                                                    LocalDate responseDate,
+                                                    LocalDateTime windowStart,
+                                                    LocalDateTime windowEnd,
+                                                    BigDecimal correctionFactorK) {
+        return calculateDeclaredCapacityKw(
+                buildMockHistoricalWindow(siteId, responseDate, windowStart, windowEnd),
+                windowStart,
+                windowEnd,
+                correctionFactorK);
+    }
+
+    public static List<DeclaredCapacityPointVO> buildMockDeclaredCapacityPoints(Long siteId,
+                                                                                LocalDate responseDate,
+                                                                                LocalDateTime windowStart,
+                                                                                LocalDateTime windowEnd,
+                                                                                BigDecimal correctionFactorK) {
+        return buildDeclaredCapacityPoints(
+                buildMockHistoricalWindow(siteId, responseDate, windowStart, windowEnd),
+                windowStart,
+                windowEnd,
+                correctionFactorK);
+    }
+
+    private static Map<String, BigDecimal> buildMockHistoricalWindow(Long siteId,
+                                                                     LocalDate responseDate,
+                                                                     LocalDateTime windowStart,
+                                                                     LocalDateTime windowEnd) {
+        Map<String, BigDecimal> mockHistorical = new TreeMap<>();
+        long seed = (siteId != null ? siteId : 0L) + responseDate.toEpochDay();
+        LocalDateTime cursor = windowStart;
+        while (!cursor.isAfter(windowEnd)) {
+            double hourFactor = mockHourFactor(cursor.toLocalTime());
+            double noise = 0.9 + pseudoRandom(seed, cursor.getHour() * 60 + cursor.getMinute(), 4) * 0.2;
+            mockHistorical.put(cursor.toLocalTime().format(TIME_FMT),
+                    BigDecimal.valueOf(900 * hourFactor * noise).setScale(2, RoundingMode.HALF_UP));
+            cursor = cursor.plusMinutes(INTERVAL_MINUTES);
+        }
+        return mockHistorical;
+    }
+    */
+
     private static BigDecimal averageValuesInWindow(Map<String, BigDecimal> valuesByTime,
     private static BigDecimal averageValuesInWindow(Map<String, BigDecimal> valuesByTime,
                                                     LocalDateTime windowStart,
                                                     LocalDateTime windowStart,
                                                     LocalDateTime windowEnd) {
                                                     LocalDateTime windowEnd) {
@@ -430,4 +516,36 @@ public final class VppBaselineHelper {
         }
         }
         return value.setScale(2, RoundingMode.HALF_UP);
         return value.setScale(2, RoundingMode.HALF_UP);
     }
     }
+
+    /*
+    private static double mockHourFactor(LocalTime time) {
+        int hour = time.getHour();
+        int minute = time.getMinute();
+        double h = hour + minute / 60.0;
+        if (h < 6) {
+            return 0.45 + h / 6 * 0.15;
+        }
+        if (h < 9) {
+            return 0.6 + (h - 6) / 3 * 0.35;
+        }
+        if (h < 12) {
+            return 0.95 + (h - 9) / 3 * 0.05;
+        }
+        if (h < 14) {
+            return 0.85;
+        }
+        if (h < 17) {
+            return 0.9 + (h - 14) / 3 * 0.1;
+        }
+        if (h < 21) {
+            return 1.0 - (h - 17) / 4 * 0.35;
+        }
+        return 0.5 - (h - 21) / 3 * 0.15;
+    }
+
+    private static double pseudoRandom(long seed, int minuteOfDay, int seriesSalt) {
+        long mixed = seed * 31L + minuteOfDay * 17L + seriesSalt * 13L;
+        return (mixed % 1000) / 1000.0;
+    }
+    */
 }
 }

+ 114 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/util/VppCapabilityEvalHelper.java

@@ -160,6 +160,56 @@ public final class VppCapabilityEvalHelper {
         return false;
         return false;
     }
     }
 
 
+    /*
+    public static List<CapabilityLoadPointVO> buildLoadCurve(List<VppResourcePoint> resources,
+                                                           List<VppDevice> devices,
+                                                           Long siteId,
+                                                           LocalDate date) {
+        List<CapabilityLoadPointVO> points = new ArrayList<>();
+        long seed = (siteId != null ? siteId : 0L) + date.toEpochDay();
+        for (int minute = 0; minute < 1440; minute += 10) {
+            LocalTime time = LocalTime.of(minute / 60, minute % 60);
+            double hourFactor = timeFactor(time);
+            BigDecimal baseline = aggregateLoad(resources, devices, seed, minute, hourFactor, 0);
+            BigDecimal actual = aggregateLoad(resources, devices, seed, minute, hourFactor, 1);
+            CapabilityLoadPointVO point = new CapabilityLoadPointVO();
+            point.setTime(time.format(TIME_FMT));
+            point.setBaselineLoadKw(baseline);
+            point.setActualLoadKw(actual);
+            points.add(point);
+        }
+        return points;
+    }
+
+    private static BigDecimal aggregateLoad(List<VppResourcePoint> resources,
+                                            List<VppDevice> devices,
+                                            long seed,
+                                            int minuteOfDay,
+                                            double hourFactor,
+                                            int seriesSalt) {
+        if (resources == null || resources.isEmpty()) {
+            double base = 800 * hourFactor + pseudoRandom(seed, minuteOfDay, seriesSalt) * 120;
+            return BigDecimal.valueOf(base).setScale(2, RoundingMode.HALF_UP);
+        }
+        BigDecimal total = BigDecimal.ZERO;
+        for (VppResourcePoint resource : resources) {
+            VppDevice device = findDevice(devices, resource.getDeviceId());
+            BigDecimal cap = resource.getCapacityKw() != null ? resource.getCapacityKw() : BigDecimal.valueOf(100);
+            double typeFactor = typeLoadFactor(resource.getResourceType());
+            double noise = 0.85 + pseudoRandom(seed, resource.getId() != null ? resource.getId() : 0L, minuteOfDay, seriesSalt) * 0.3;
+            double value = cap.doubleValue() * hourFactor * typeFactor * noise;
+            if (CATEGORY_GENERATION.equals(resolveCategory(resource.getResourceType()))) {
+                value *= 0.15;
+            }
+            total = total.add(BigDecimal.valueOf(value));
+        }
+        if (seriesSalt == 1) {
+            total = total.multiply(BigDecimal.valueOf(1.02 + pseudoRandom(seed, 999, minuteOfDay, seriesSalt) * 0.08));
+        }
+        return total.setScale(2, RoundingMode.HALF_UP);
+    }
+    */
+
     private static BigDecimal sumBucketPower(Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> deviceData,
     private static BigDecimal sumBucketPower(Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> deviceData,
                                              List<String> metricCandidates,
                                              List<String> metricCandidates,
                                              LocalDateTime bucketStart,
                                              LocalDateTime bucketStart,
@@ -240,4 +290,68 @@ public final class VppCapabilityEvalHelper {
         }
         }
         return value.setScale(2, RoundingMode.HALF_UP);
         return value.setScale(2, RoundingMode.HALF_UP);
     }
     }
+
+    /*
+    private static VppDevice findDevice(List<VppDevice> devices, Long deviceId) {
+        if (devices == null || deviceId == null) {
+            return null;
+        }
+        return devices.stream().filter(d -> deviceId.equals(d.getId())).findFirst().orElse(null);
+    }
+
+    private static double timeFactor(LocalTime time) {
+        int hour = time.getHour();
+        int minute = time.getMinute();
+        double h = hour + minute / 60.0;
+        if (h < 6) {
+            return 0.45 + h / 6 * 0.15;
+        }
+        if (h < 9) {
+            return 0.6 + (h - 6) / 3 * 0.35;
+        }
+        if (h < 12) {
+            return 0.95 + (h - 9) / 3 * 0.05;
+        }
+        if (h < 14) {
+            return 0.85;
+        }
+        if (h < 17) {
+            return 0.9 + (h - 14) / 3 * 0.1;
+        }
+        if (h < 21) {
+            return 1.0 - (h - 17) / 4 * 0.35;
+        }
+        return 0.5 - (h - 21) / 3 * 0.15;
+    }
+
+    private static double typeLoadFactor(String resourceType) {
+        if (resourceType == null) {
+            return 0.7;
+        }
+        switch (resourceType.toUpperCase()) {
+            case "IND_LOAD":
+                return 0.75;
+            case "COM_BLDG":
+                return 0.65;
+            case "EVCS":
+                return 0.55;
+            case "ESS":
+                return 0.4;
+            case "PV":
+                return 1.0;
+            default:
+                return 0.7;
+        }
+    }
+
+    private static double pseudoRandom(long seed, long a, int b, int c) {
+        long mixed = seed * 31L + a * 17L + b * 13L + c * 7L;
+        return (mixed % 1000) / 1000.0;
+    }
+
+    private static double pseudoRandom(long seed, int minuteOfDay, int seriesSalt) {
+        long mixed = seed * 31L + minuteOfDay * 17L + seriesSalt * 13L;
+        return (mixed % 1000) / 1000.0;
+    }
+    */
 }
 }

+ 64 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/util/VppResourceMockHelper.java

@@ -0,0 +1,64 @@
+package com.usky.vpp.util;
+
+/**
+ * 资源看板/概览模拟数据生成(已停用,保留注释备查)
+ */
+public final class VppResourceMockHelper {
+
+    private VppResourceMockHelper() {
+    }
+
+    /*
+    import com.usky.vpp.domain.VppDevice;
+    import com.usky.vpp.domain.VppResourcePoint;
+
+    import java.math.BigDecimal;
+    import java.math.RoundingMode;
+    import java.time.LocalDateTime;
+    import java.util.concurrent.ThreadLocalRandom;
+
+    public static BigDecimal mockSocPercent(VppResourcePoint resource) {
+        if (!"ESS".equalsIgnoreCase(resource.getResourceType())) {
+            return null;
+        }
+        return BigDecimal.valueOf(20 + pseudoRandom(resource.getId(), 2) * 70).setScale(1, RoundingMode.HALF_UP);
+    }
+
+    public static BigDecimal mockEvcsChargePowerKw(VppResourcePoint resource) {
+        if (!"EVCS".equalsIgnoreCase(resource.getResourceType())) {
+            return null;
+        }
+        BigDecimal base = resource.getCapacityKw() != null ? resource.getCapacityKw() : BigDecimal.valueOf(60);
+        return base.multiply(BigDecimal.valueOf(0.2 + pseudoRandom(resource.getId(), 3) * 0.7))
+                .setScale(2, RoundingMode.HALF_UP);
+    }
+
+    public static String resourceTypeLabel(String resourceType) {
+        if (resourceType == null) {
+            return "未知";
+        }
+        switch (resourceType.toUpperCase()) {
+            case "PV":
+                return "光伏";
+            case "ESS":
+                return "储能";
+            case "EVCS":
+                return "充电桩";
+            case "IND_LOAD":
+                return "工业负荷";
+            case "COM_BLDG":
+                return "商业楼宇";
+            default:
+                return resourceType;
+        }
+    }
+
+    private static double pseudoRandom(Long seed, int salt) {
+        if (seed == null) {
+            return ThreadLocalRandom.current().nextDouble();
+        }
+        long mixed = seed * 31L + salt + LocalDateTime.now().getMinute();
+        return (mixed % 1000) / 1000.0;
+    }
+    */
+}

+ 96 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/util/VppResponseMonitorHelper.java

@@ -74,6 +74,34 @@ public final class VppResponseMonitorHelper {
         return points;
         return points;
     }
     }
 
 
+    /*
+    public static List<ResponseLoadPointVO> buildMockCurve(List<VppResourcePoint> resources,
+                                                         List<VppDevice> devices,
+                                                         Long siteId,
+                                                         LocalDate date,
+                                                         BigDecimal declaredCapacityKw) {
+        List<ResponseLoadPointVO> points = new ArrayList<>();
+        long seed = (siteId != null ? siteId : 0L) + date.toEpochDay();
+        for (int minute = 0; minute < 1440; minute += BUCKET_MINUTES) {
+            LocalTime time = LocalTime.of(minute / 60, minute % 60);
+            double hourFactor = dayTimeFactor(time);
+            BigDecimal baseline = mockAggregate(resources, devices, seed, minute, hourFactor, 0);
+            BigDecimal actual = mockAggregate(resources, devices, seed, minute, hourFactor, 1);
+            BigDecimal response = baseline.subtract(actual).max(BigDecimal.ZERO);
+
+            ResponseLoadPointVO point = new ResponseLoadPointVO();
+            point.setTime(time.format(TIME_FMT));
+            point.setDatetime(date.atTime(time).format(DATETIME_FMT));
+            point.setBaselineLoadKw(baseline);
+            point.setActualLoadKw(actual);
+            point.setDeclaredCapacityKw(declaredCapacityKw != null ? declaredCapacityKw : BigDecimal.ZERO);
+            point.setActualResponseLoadKw(response);
+            points.add(point);
+        }
+        return points;
+    }
+    */
+
     /**
     /**
      * 基于预计算的预测基线和今日实际,构建曲线点(替代直接操作 TSDB 原始时序)。
      * 基于预计算的预测基线和今日实际,构建曲线点(替代直接操作 TSDB 原始时序)。
      */
      */
@@ -204,6 +232,32 @@ public final class VppResponseMonitorHelper {
         return row;
         return row;
     }
     }
 
 
+    /*
+    private static BigDecimal mockAggregate(List<VppResourcePoint> resources,
+                                            List<VppDevice> devices,
+                                            long seed,
+                                            int minuteOfDay,
+                                            double hourFactor,
+                                            int seriesSalt) {
+        if (resources == null || resources.isEmpty()) {
+            double base = 580 * hourFactor + pseudoRandom(seed, 0L, minuteOfDay, seriesSalt) * 80;
+            return BigDecimal.valueOf(base).setScale(2, RoundingMode.HALF_UP);
+        }
+        BigDecimal total = BigDecimal.ZERO;
+        for (VppResourcePoint resource : resources) {
+            BigDecimal cap = resource.getCapacityKw() != null ? resource.getCapacityKw() : BigDecimal.valueOf(100);
+            double noise = 0.85 + pseudoRandom(seed, resource.getId() != null ? resource.getId() : 0L,
+                    minuteOfDay, seriesSalt) * 0.3;
+            double value = cap.doubleValue() * hourFactor * 0.6 * noise;
+            total = total.add(BigDecimal.valueOf(value));
+        }
+        if (seriesSalt == 1) {
+            total = total.multiply(BigDecimal.valueOf(0.95 + pseudoRandom(seed, 999, minuteOfDay, seriesSalt) * 0.08));
+        }
+        return total.setScale(2, RoundingMode.HALF_UP);
+    }
+    */
+
     private static BigDecimal sumBucketPower(Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> deviceData,
     private static BigDecimal sumBucketPower(Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> deviceData,
                                              List<String> metricCandidates,
                                              List<String> metricCandidates,
                                              LocalDateTime bucketStart,
                                              LocalDateTime bucketStart,
@@ -281,4 +335,46 @@ public final class VppResponseMonitorHelper {
     private static BigDecimal min(List<BigDecimal> values) {
     private static BigDecimal min(List<BigDecimal> values) {
         return values.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
         return values.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
     }
     }
+
+    /*
+    private static double pseudo(String time) {
+        if (time == null) {
+            return 0.5;
+        }
+        return (time.hashCode() & 0x7FFFFFFF) % 100 / 100.0;
+    }
+
+    private static double pseudoRandom(long seed, long a, int b, int c) {
+        long x = seed * 31 + a * 17 + b * 13L + c;
+        x = ((x >> 16) ^ x) * 0x45d9f3b;
+        x = ((x >> 16) ^ x) * 0x45d9f3b;
+        x = (x >> 16) ^ x;
+        return (x & 0x7FFFFFFF) / (double) 0x7FFFFFFF;
+    }
+
+    private static double dayTimeFactor(LocalTime time) {
+        int hour = time.getHour();
+        int minute = time.getMinute();
+        double h = hour + minute / 60.0;
+        if (h < 6) {
+            return 0.45 + h / 6 * 0.15;
+        }
+        if (h < 9) {
+            return 0.6 + (h - 6) / 3 * 0.35;
+        }
+        if (h < 12) {
+            return 0.95 + (h - 9) / 3 * 0.05;
+        }
+        if (h < 14) {
+            return 0.85;
+        }
+        if (h < 18) {
+            return 0.75 + (h - 14) / 4 * 0.25;
+        }
+        if (h < 21) {
+            return 1.0 - (h - 18) / 3 * 0.2;
+        }
+        return 0.55 - (h - 21) / 3 * 0.15;
+    }
+    */
 }
 }