From 9c93934b70ccfca081102944a47f3baafad3c218 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 28 九月 2026 16:43:57 +0800
Subject: [PATCH] 实现新威 7.6 的工步与循环数据取数

---
 battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java |   45 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java b/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
index ef44f5d..e8d0ea8 100644
--- a/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
+++ b/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
@@ -22,7 +22,11 @@
     /** 返回设备直接提供的工步统计,不从实时采样推导。 */
     List<StepRecord> stepRecords(ChannelIdentity channel);
 
-    /** 返回设备直接提供的循环统计,不补齐设备未返回的记录。 */
+    /**
+     * 返回该来源的循环统计。设备直接提供循环汇总行时原样返回;设备只有工步层时由适配器按循环聚合,
+     * 并用 {@link CycleRecord#sourceKind()} 标注为聚合来源,使调用方与界面能区分推导值与设备事实。
+     * 不补齐来源未提供的循环,也不跨循环借值。
+     */
     List<CycleRecord> cycleRecords(ChannelIdentity channel);
 
     /** 返回适配器定义的实时持久化槽位间隔。 */
@@ -84,13 +88,44 @@
     record CollectorMeasurement(String channelCode, long sequenceId, Instant deviceTime, String deviceTimeRaw,
             Instant serverReceivedAt, String metricCode, BigDecimal value, String unit) { }
 
+    /**
+     * 一条设备工步层记录。{@code stepType} 保留设备给出的原始类型(新威为数字枚举),
+     * 方向由调用方按该类型解释,不由适配器按电流符号推断。
+     *
+     * <p>{@code endVoltageV} 与 {@code endCurrentA} 是该工步结束时的设备读数。
+     * {@code capacityAh} 与 {@code energyWh} 是该工步自身累计的单项值,只在方向已确认时给出;
+     * 方向未知时保持为空,四个方向的容量能量仍在 {@code measurements} 中作为设备事实保留。
+     */
     record StepRecord(String sourceRecordId, int cycleNo, int stepNo, String stepName, String stepType,
-            Instant startedAt, Instant endedAt, double endVoltageV, double capacityAh, double energyWh,
-            String deviceTimeRaw, String timezoneId, Instant serverReceivedAt,
+            Instant startedAt, Instant endedAt, double endVoltageV, double endCurrentA, Double capacityAh,
+            Double energyWh, String deviceTimeRaw, String timezoneId, Instant serverReceivedAt,
             java.util.Map<String, BigDecimal> measurements) { }
 
+    /**
+     * 一条循环统计。{@code sourceRecordId} 是来源行的稳定身份,供幂等与冲突判定使用。
+     *
+     * <p>设备没有循环汇总行时,循环统计由工步层按循环聚合得出;{@code sourceKind} 记录这个来源事实,
+     * 使界面与导出能明确标注"这个数是聚合的还是设备给的",取值只能是下面三个常量之一。
+     *
+     * <p>{@code efficiency} 为单位为百分比的充放电效率。该循环没有可用的充电容量时保持为空:
+     * 未知比率不用零代替,零值只表示设备确实给出零。
+     */
     record CycleRecord(String sourceRecordId, int cycleNo, Instant startedAt, Instant endedAt,
             double chargeCapacityAh, double dischargeCapacityAh, double chargeEnergyWh,
-            double dischargeEnergyWh, double efficiency, String deviceTimeRaw, String timezoneId,
-            Instant serverReceivedAt) { }
+            double dischargeEnergyWh, Double efficiency, String deviceTimeRaw, String timezoneId,
+            Instant serverReceivedAt, String sourceKind)
+    {
+        /** 来源类别:设备直接提供。 */
+        public static final String SOURCE_DEVICE = "DEVICE";
+        /** 来源类别:来源没有循环汇总行,由工步层按循环聚合得出。 */
+        public static final String SOURCE_AGGREGATED = "AGGREGATED";
+        /** 来源类别:授权文件导入。 */
+        public static final String SOURCE_IMPORTED = "IMPORTED";
+
+        public CycleRecord
+        {
+            // 未标注一律按设备事实:引入聚合之前写进库的循环记录都来自设备或文件。
+            sourceKind = sourceKind == null || sourceKind.isBlank() ? SOURCE_DEVICE : sourceKind;
+        }
+    }
 }

--
Gitblit v1.7.1