| | |
| | | */ |
| | | CollectorRealtime latestCollector(String adapterCode, String collectorCode); |
| | | |
| | | /** 返回设备直接提供的工步统计,不从实时采样推导。 */ |
| | | /** |
| | | * 返回该通道的工步统计。来源有工步层时读设备工步层并原样交出;来源没有工步层时由适配器 |
| | | * 从采样段推导(ADR-0067)。两种形态的记录里 {@code stepName} 都是**方向名称** |
| | | * ({@link com.battery.device.api.StepDirectionResolver.Direction#displayName()}):来源给出工步类型时按该类型解释, |
| | | * 来源没有类型列时按已核对的列语义判定;判定不出方向时留空,不写默认名。 |
| | | * 未结束的段不交出,也不推导来源根本没有的工步层。 |
| | | */ |
| | | List<StepRecord> stepRecords(ChannelIdentity channel); |
| | | |
| | | /** 返回设备直接提供的循环统计,不补齐设备未返回的记录。 */ |
| | | /** |
| | | * 返回该来源的循环统计。设备直接提供循环汇总行时原样返回;设备只有工步层时由适配器按循环聚合, |
| | | * 并用 {@link CycleRecord#sourceKind()} 标注为聚合来源,使调用方与界面能区分推导值与设备事实。 |
| | | * 不补齐来源未提供的循环,也不跨循环借值。 |
| | | */ |
| | | List<CycleRecord> cycleRecords(ChannelIdentity channel); |
| | | |
| | | /** 返回适配器定义的实时持久化槽位间隔。 */ |
| | | long persistenceIntervalMillis(ChannelIdentity channel); |
| | | |
| | | /** |
| | | * 返回工步与循环这些汇总记录的读取间隔。默认与实时持久化间隔一致;来源的汇总产出节奏与 |
| | | * 数据行节奏不同的实现覆盖它——推式来源的落地表在本地(实时行按展示节奏取), |
| | | * 而汇总最快也要等来源写下下一行才可能变化,按展示节奏重算只是空跑。 |
| | | */ |
| | | default long aggregateIntervalMillis(ChannelIdentity channel) { return persistenceIntervalMillis(channel); } |
| | | |
| | | /** 返回设备计划方案;设备未提供时保持为空,不推导计划。 */ |
| | | default TestPlan testPlan(ChannelIdentity channel) { return null; } |
| | |
| | | record CollectorMeasurement(String channelCode, long sequenceId, Instant deviceTime, String deviceTimeRaw, |
| | | Instant serverReceivedAt, String metricCode, BigDecimal value, String unit) { } |
| | | |
| | | /** |
| | | * 一条设备工步层记录。来源给出工步类型时 {@code stepType} 原样保留(新威为数字枚举), |
| | | * 适配器不按电流符号改写它。 |
| | | * |
| | | * <p>{@code stepName} 是**方向名称**(`充电` / `放电` / `搁置`,ADR-0067 §4b):来源给出工步类型时 |
| | | * 按该类型解释(新威的 {@code 1}/{@code 2}/{@code 4}),来源没有类型列时(推式来源的厂商库里既没有 |
| | | * 工步层也没有循环汇总表,ADR-0067)按已核对列语义判定。方向判不出来时留空——**不是设备给的名称**, |
| | | * 界面据此标注来源,调用方不得用默认名把未知说成已知。 |
| | | * |
| | | * <p>来源没有工步层时,除方向名称外该工步的其余一切仍是设备采样行上的原文事实。 |
| | | * |
| | | * <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; |
| | | } |
| | | } |
| | | } |