From 27428b31edee97703b529559146cdd7eef87a7a9 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 05 九月 2026 11:00:58 +0800
Subject: [PATCH] 完成测试数据接收持久化与查询

---
 battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java b/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java
index fdb900b..5479ccc 100644
--- a/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java
+++ b/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java
@@ -20,6 +20,7 @@
 import com.battery.device.model.ChannelIdentity;
 import com.battery.device.model.AdapterCapabilities;
 import com.battery.device.api.DeviceObservationAdapter;
+import com.battery.device.api.TestDataObservationAdapter;
 import com.battery.device.simulator.BtsSimulatorStateStore;
 import com.battery.device.simulator.BtsSimulatorStateStore.ChannelState;
 import com.battery.device.simulator.BtsSimulatorStateStore.ChannelTombstone;
@@ -43,7 +44,7 @@
 import com.battery.device.simulator.DevelopmentCollectorSimulation.CollectorRealtimeSnapshot;
 
 /** 提供由开发后端托管的临时只读 BTS 模拟端点。 */
-public final class BtsDevelopmentSimulator implements DeviceObservationAdapter
+public final class BtsDevelopmentSimulator implements TestDataObservationAdapter
 {
     public static final String HOST = "127.0.0.1";
     public static final int DEFAULT_PORT = 15020;
@@ -494,6 +495,46 @@
         BtsPlaybackState playback = playbackState(btsKey(device, channelId), Instant.now());
         return Math.max(100L, 60000L / Math.max(1, playback.speedMultiplier()));
     }
+
+    @Override
+    public synchronized CabinetRealtime latestCabinet(ChannelIdentity channel)
+    {
+        BtsHistoryRecord record = btsRecords(channel.devid(), channel.chlid()).stream()
+                .max(java.util.Comparator.comparing(BtsHistoryRecord::deviceTime)).orElse(null);
+        return record == null ? null : new CabinetRealtime(record.sequenceId(), record.deviceTime(), record.currentA(),
+                record.voltageV(), record.capacityAh(), record.energyWh(), record.cycleNo(), record.stepNo(),
+                record.stepName(), record.stepType(), record.serverReceivedAt());
+    }
+
+    @Override
+    public synchronized CollectorRealtime latestCollector(long collectorId)
+    {
+        CollectorRealtimeSnapshot snapshot = collectorRealtime((int) collectorId);
+        return new CollectorRealtime(snapshot.collectorCode(), snapshot.online(), snapshot.sampleIntervalMs(),
+                snapshot.measurements().stream().map(item -> new CollectorMeasurement(item.channelCode(), item.sequenceId(),
+                        item.deviceTime(), item.deviceTimeRaw(), item.serverReceivedAt(), item.metricCode(), item.value(),
+                        item.unit())).toList());
+    }
+
+    @Override
+    public synchronized List<StepRecord> stepRecords(ChannelIdentity channel)
+    {
+        return btsSteps(channel.devid(), channel.chlid()).stream().map(item -> new StepRecord(item.recordNo(),
+                item.cycleNo(), item.stepNo(), item.stepName(), item.stepType(), item.startedAt(), item.endedAt(),
+                item.endVoltageV(), item.capacityAh(), item.energyWh())).toList();
+    }
+
+    @Override
+    public synchronized List<CycleRecord> cycleRecords(ChannelIdentity channel)
+    {
+        return btsCycles(channel.devid(), channel.chlid()).stream().map(item -> new CycleRecord(item.recordNo(),
+                item.cycleNo(), item.startedAt(), item.endedAt(), item.chargeCapacityAh(), item.dischargeCapacityAh(),
+                item.chargeEnergyWh(), item.dischargeEnergyWh(), item.efficiency())).toList();
+    }
+
+    @Override
+    public synchronized long persistenceIntervalMillis(ChannelIdentity channel)
+    { return persistenceIntervalMillis(channel.devid(), channel.chlid()); }
 
     /** 按实际出现的循环和工步汇总 record,不补齐缺失行。 */
     public synchronized List<BtsStepRecord> btsSteps(int deviceId, int channelId)
@@ -1004,7 +1045,19 @@
 
     public record BtsStepRecord(int cycleNo, int stepNo, Integer cyclePosition, String stepName, String stepType, long recordCount,
             Instant startedAt, Instant endedAt, double durationSeconds, double capacityAh, double energyWh,
-            double startVoltageV, double endVoltageV, double chargePeakVoltageV, double dischargeValleyVoltageV) { }
+            double startVoltageV, double endVoltageV, double chargePeakVoltageV, double dischargeValleyVoltageV,
+            String recordNo)
+    {
+        public BtsStepRecord(int cycleNo, int stepNo, Integer cyclePosition, String stepName, String stepType,
+                long recordCount, Instant startedAt, Instant endedAt, double durationSeconds, double capacityAh,
+                double energyWh, double startVoltageV, double endVoltageV, double chargePeakVoltageV,
+                double dischargeValleyVoltageV)
+        {
+            this(cycleNo, stepNo, cyclePosition, stepName, stepType, recordCount, startedAt, endedAt,
+                    durationSeconds, capacityAh, energyWh, startVoltageV, endVoltageV, chargePeakVoltageV,
+                    dischargeValleyVoltageV, null);
+        }
+    }
 
     public record BtsCycleRecord(String recordNo, int cycleNo, long recordCount, Instant startedAt, Instant endedAt,
             double chargeCapacityAh, double dischargeCapacityAh, double chargeEnergyWh, double dischargeEnergyWh,
@@ -1031,7 +1084,7 @@
         private double startVoltage; private double endVoltage; private double chargePeak = Double.NEGATIVE_INFINITY; private double dischargeValley = Double.POSITIVE_INFINITY;
         BtsStepAccumulator(BtsHistoryRecord first, int position) { cycle = first.cycleNo(); step = first.stepNo(); this.position = position; name = first.stepName(); type = first.stepType(); }
         void add(BtsHistoryRecord item) { count++; if (first == null) { first = item.deviceTime(); startVoltage = item.voltageV(); } last = item.deviceTime(); endVoltage = item.voltageV(); duration = first == null ? 0 : Math.max(0, java.time.Duration.between(first, last).toMillis() / 1000d); capacity = item.capacityAh(); energy = item.energyWh(); if (item.currentA() >= 0) chargePeak = Math.max(chargePeak, item.voltageV()); else dischargeValley = Math.min(dischargeValley, item.voltageV()); }
-        BtsStepRecord finish() { return new BtsStepRecord(cycle, step, position, name, type, count, first, last, duration, capacity, energy, startVoltage, endVoltage, chargePeak == Double.NEGATIVE_INFINITY ? 0 : chargePeak, dischargeValley == Double.POSITIVE_INFINITY ? 0 : dischargeValley); }
+        BtsStepRecord finish() { return new BtsStepRecord(cycle, step, position, name, type, count, first, last, duration, capacity, energy, startVoltage, endVoltage, chargePeak == Double.NEGATIVE_INFINITY ? 0 : chargePeak, dischargeValley == Double.POSITIVE_INFINITY ? 0 : dischargeValley, "STEP-" + cycle + "-" + step + "-" + last.toEpochMilli()); }
     }
 
     private static final class BtsCycleAccumulator

--
Gitblit v1.7.1