| | |
| | | * </ul> |
| | | * |
| | | * <p>方向的判定沿用既有解析器;{@code cap}/{@code eng} 在接口上是**单一值**(不分充放), |
| | | * 只在方向已确认时给出,方向未知时留空——不按数值大小猜它属于哪一侧(ADR-0069 §3)。 |
| | | * 只在**充放电方向**给出。搁置步留空不是保守,是实测结论:接口对搁置步给的是跨步过渡值 |
| | | * (实测等于上一步充电容量、甚至取负),照抄会写出不成立的事实(ADR-0069 §3)。 |
| | | * |
| | | * @param xml 应答原文 |
| | | * @param receivedAt 服务器接收时间 |
| | |
| | | int cycleNo = requiredInteger(data, "cycleid") - 1; |
| | | BigDecimal capacity = optionalDecimal(data, "cap"); |
| | | BigDecimal energy = optionalDecimal(data, "eng"); |
| | | boolean directionKnown = direction != StepDirectionResolver.Direction.UNKNOWN; |
| | | // 单项容量能量只在**充放电方向**给出:接口的 cap/eng 是单一值,实测它对搁置步给的是 |
| | | // 跨步过渡值(C 那台实测搁置步给 +0.290039804444444,等于上一步充电的容量;还有一次取负 |
| | | // −0.178807573333333),并不是该步自身累计。照抄会写出"搁置步容量 0.29 Ah"这种不成立的事实; |
| | | // 而该步自身累计为 0 这件事设备没给,所以留空而不是补零(ADR-0069 §3)。 |
| | | boolean singleValued = direction == StepDirectionResolver.Direction.CHARGE |
| | | || direction == StepDirectionResolver.Direction.DISCHARGE; |
| | | steps.add(new StepRecord(testId.isBlank() ? null : "neware:" + testId + ":step:" + stepIndex, cycleNo, |
| | | requiredInteger(data, "stepid"), direction.displayName(), stepType, |
| | | durationMillis == null ? endedAt : endedAt.minusMillis(durationMillis), |
| | | endedAt, doubleValue(data, "endvolt"), doubleValue(data, "endcurr"), |
| | | directionKnown && capacity != null ? capacity.doubleValue() : null, |
| | | directionKnown && energy != null ? energy.doubleValue() : null, |
| | | rawTime, zoneId, receivedAt, stepMeasurements(data, durationMillis))); |
| | | singleValued && capacity != null ? capacity.doubleValue() : null, |
| | | singleValued && energy != null ? energy.doubleValue() : null, |
| | | rawTime, zoneId, receivedAt, stepMeasurements(data, durationMillis, capacity, energy))); |
| | | } |
| | | return List.copyOf(steps); |
| | | } |
| | | |
| | | /** 工步的设备事实明细;映射表按已有键名口径命名,值全部来自应答原文。 */ |
| | | private static Map<String, BigDecimal> stepMeasurements(Element data, Long durationMillis) |
| | | /** |
| | | * 工步的设备事实明细;映射表按已有键名口径命名,值全部来自应答原文。 |
| | | * |
| | | * <p>应答给的 {@code cap}/{@code eng} 在搁置步是跨步过渡值(见上),所以明细里也按方向归属: |
| | | * 充放步留 {@code cap}/{@code eng} 原文,其余方向不留——明细与单项列不得互相矛盾。 |
| | | */ |
| | | private static Map<String, BigDecimal> stepMeasurements(Element data, Long durationMillis, |
| | | BigDecimal capacity, BigDecimal energy) |
| | | { |
| | | Map<String, BigDecimal> measurements = new LinkedHashMap<>(); |
| | | if (durationMillis != null) measurements.put("stepDuration", BigDecimal.valueOf(durationMillis).movePointLeft(3)); |
| | |
| | | put(measurements, data, "startVoltage", "startvolt"); |
| | | put(measurements, data, "startCurrent", "startcurr"); |
| | | put(measurements, data, "dcir", "dcir"); |
| | | put(measurements, data, "endVoltage", "endvolt"); |
| | | put(measurements, data, "endCurrent", "endcurr"); |
| | | if (capacity != null) measurements.put("capacity", capacity); |
| | | if (energy != null) measurements.put("energy", energy); |
| | | return Map.copyOf(measurements); |
| | | } |
| | | |