From f522c9ffa487e3710d691e8b98df8c4f0cfafd43 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 05 九月 2026 20:07:26 +0800
Subject: [PATCH] 支持模拟器逐通道参数与工步方案配置

---
 battery-device-simulator/src/main/java/com/battery/device/simulator/BtsSimulatorStateStore.java |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsSimulatorStateStore.java b/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsSimulatorStateStore.java
index f48e4c6..9e7e01d 100644
--- a/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsSimulatorStateStore.java
+++ b/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsSimulatorStateStore.java
@@ -100,9 +100,58 @@
             long sequenceId, Instant deviceTime, String deviceTimeRaw, Instant serverReceivedAt,
             String metricCode, BigDecimal value, String unit) { }
 
-    record ChannelState(int channelId, boolean online, DeviceWorkStatus workStatus) { }
+    record ChannelState(int channelId, boolean online, DeviceWorkStatus workStatus,
+            ChannelConfiguration configuration)
+    {
+        public ChannelState
+        {
+            configuration = configuration == null ? ChannelConfiguration.defaults() : configuration;
+        }
 
-    /** BTS 检测柜的可配置厂商 profile;参数用于发现展示和边界内的演示数据生成。 */
+        public ChannelState(int channelId, boolean online, DeviceWorkStatus workStatus)
+        { this(channelId, online, workStatus, null); }
+    }
+
+    /** 通道当前观测配置与方案一起保存,避免当前工步引用不存在的方案行。 */
+    record ChannelConfiguration(BigDecimal currentA, BigDecimal voltageV, BigDecimal capacityAh,
+            BigDecimal energyWh, int cycleNo, int stepNo, int plannedCycleCount,
+            long totalTimeSeconds, long relativeTimeSeconds, List<SimulatorPlanStep> steps)
+    {
+        public ChannelConfiguration
+        {
+            for (BigDecimal value : new BigDecimal[] { currentA, voltageV, capacityAh, energyWh })
+                if (value == null || !Double.isFinite(value.doubleValue()))
+                    throw new IllegalArgumentException("通道测量值必须是有效数值");
+            if (steps == null || steps.isEmpty() || steps.stream().anyMatch(java.util.Objects::isNull))
+                throw new IllegalArgumentException("工步方案至少包含一个有效工步");
+            steps = List.copyOf(steps);
+            if (cycleNo < 1 || plannedCycleCount < cycleNo || stepNo < 1 || stepNo > steps.size()
+                    || totalTimeSeconds < 0 || relativeTimeSeconds < 0 || relativeTimeSeconds > totalTimeSeconds)
+                throw new IllegalArgumentException("循环、当前工步或时间配置无效");
+        }
+
+        /** 为新增通道和既有配置补齐固定观测值,不产生成功接收记录。 */
+        public static ChannelConfiguration defaults()
+        {
+            return new ChannelConfiguration(BigDecimal.ZERO, new BigDecimal("3.7"), new BigDecimal("1.2"),
+                    new BigDecimal("4.44"), 1, 1, 1, 0, 0,
+                    List.of(new SimulatorPlanStep("恒流充电", "cc", 60d, 3.7d)));
+        }
+    }
+
+    record SimulatorPlanStep(String name, String stepType, double durationSeconds, double voltageV)
+    {
+        public SimulatorPlanStep
+        {
+            if (name == null || name.isBlank() || stepType == null
+                    || !List.of("cc", "dc", "cv", "rest", "end", "cccv").contains(stepType)
+                    || !Double.isFinite(durationSeconds) || durationSeconds < 0 || !Double.isFinite(voltageV))
+                throw new IllegalArgumentException("工步名称、类型、时间或电压无效");
+            name = name.trim();
+        }
+    }
+
+    /** BTS 检测柜的可配置厂商 profile,用于设备发现元数据展示。 */
     record BtsDeviceProfile(int devtype, int subDeviceId, String name, String manufacturer, String model,
             String serialNumber, String firmwareVersion, int channelCount, BigDecimal currentMinA,
             BigDecimal currentMaxA, BigDecimal voltageMinV, BigDecimal voltageMaxV, int sampleIntervalMs)

--
Gitblit v1.7.1