yeg
2026-09-29 b78295e8da96c3e5e76befeef9582ce5273dbb74
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;
        }
    }
}