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 的工步与循环数据取数
---
ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java | 67 +++++++++++++++++++++++++++++++--
1 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java b/ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java
index c6eb367..a7761fc 100644
--- a/ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java
+++ b/ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java
@@ -185,11 +185,12 @@
Instant started = Instant.parse("2026-09-02T04:00:10Z");
Instant ended = Instant.parse("2026-09-02T04:00:50Z");
when(fixture.simulator.stepRecords(any(ChannelIdentity.class))).thenReturn(List.of(new StepRecord(
- "STEP-1", 1, 2, "恒流充电", "cc", started, ended, 3.4, 2.5, 8.4, ended.toString(), "UTC", ended,
+ "STEP-1", 1, 2, "恒流充电", "cc", started, ended, 3.4, 2.6, 2.5, 8.4, ended.toString(), "UTC", ended,
java.util.Map.of("stepDuration", new BigDecimal("40.125"), "startVoltage", new BigDecimal("3.1"),
"chargeMedianVoltage", new BigDecimal("3.25"), "dischargeMedianVoltage", BigDecimal.ZERO))));
when(fixture.simulator.cycleRecords(any(ChannelIdentity.class))).thenReturn(List.of(new CycleRecord(
- "CYCLE-1-1-1", 1, started, ended, 2.5, 2.4, 8.4, 8.0, 96, ended.toString(), "UTC", ended)));
+ "CYCLE-1-1-1", 1, started, ended, 2.5, 2.4, 8.4, 8.0, 96d, ended.toString(), "UTC", ended,
+ CycleRecord.SOURCE_DEVICE)));
when(fixture.mapper.insertStepRecord(any())).thenReturn(1);
when(fixture.mapper.insertCycleRecord(any())).thenReturn(1);
@@ -207,8 +208,29 @@
assertEquals(BigDecimal.ZERO, metrics.getBigDecimal("dischargeMedianVoltage"));
assertEquals("CYCLE-1-1-1", cycle.getValue().getSourceRecordId());
assertEquals("record:CYCLE-1-1-1", cycle.getValue().getDedupeKey());
+ // 设备或文件直接提供的循环统计保留原有来源类别。
+ assertEquals(CycleRecord.SOURCE_DEVICE, cycle.getValue().getSourceKind());
+ // 工步结束时的设备读数:电压与电流一起落库。
+ assertEquals(new BigDecimal("3.4"), step.getValue().getVoltageV());
+ assertEquals(new BigDecimal("2.6"), step.getValue().getCurrentA());
assertEquals(Date.from(ended), step.getValue().getServerReceivedAtUtc());
assertEquals(Date.from(ended), cycle.getValue().getServerReceivedAtUtc());
+ }
+
+ /** 接收调度每秒运行,但来源按自己的写库节奏产出工步:不按来源节奏限流会每秒重查厂商库。 */
+ @Test void readsTheStepLayerOncePerSourceCadenceInsteadOfEverySchedulerTick()
+ {
+ Fixture fixture = fixture();
+ when(fixture.simulator.stepRecords(any(ChannelIdentity.class))).thenReturn(List.of());
+ when(fixture.simulator.cycleRecords(any(ChannelIdentity.class))).thenReturn(List.of());
+
+ TestDataReceptionServiceImpl service = fixture.service();
+ service.captureReceivedData();
+ service.captureReceivedData();
+ service.captureReceivedData();
+
+ verify(fixture.simulator, times(1)).stepRecords(any(ChannelIdentity.class));
+ verify(fixture.simulator, times(1)).cycleRecords(any(ChannelIdentity.class));
}
@Test
@@ -251,19 +273,54 @@
fixture.tests.selectTestById(1L).setReceptionBoundaryAtUtc(Date.from(CAPTURED_AT));
Instant pausedAt = CAPTURED_AT.minusSeconds(10);
when(fixture.simulator.stepRecords(any())).thenReturn(List.of(new StepRecord("paused", 1, 1, "工步", "cc",
- pausedAt.minusSeconds(20), pausedAt, 3, 1, 2, pausedAt.toString(), "UTC", pausedAt, java.util.Map.of())));
+ pausedAt.minusSeconds(20), pausedAt, 3d, 1.5d, 1d, 2d, pausedAt.toString(), "UTC", pausedAt,
+ java.util.Map.of())));
when(fixture.simulator.cycleRecords(any())).thenReturn(List.of(new CycleRecord("paused", 1,
- pausedAt.minusSeconds(20), pausedAt, 1, 1, 2, 2, 100, pausedAt.toString(), "UTC", pausedAt)));
+ pausedAt.minusSeconds(20), pausedAt, 1, 1, 2, 2, 100d, pausedAt.toString(), "UTC", pausedAt,
+ CycleRecord.SOURCE_DEVICE)));
fixture.service().captureReceivedData();
verify(fixture.mapper, never()).insertStepRecord(any());
verify(fixture.mapper, never()).insertCycleRecord(any());
+ }
+
+ /** 循环统计的来源类别随记录落库:聚合值必须能与设备或文件提供的值区分。 */
+ @Test void persistsCycleSourceKindAndKeepsMissingMetricsEmpty()
+ {
+ Fixture fixture = fixture();
+ when(fixture.simulator.cycleRecords(any(ChannelIdentity.class))).thenReturn(List.of(
+ new CycleRecord("neware:442:cycle:3", 3, CAPTURED_AT.minusSeconds(600), CAPTURED_AT, 2.375, 1.383,
+ 4.059, 1.715, null, CAPTURED_AT.toString(), "Asia/Hong_Kong", CAPTURED_AT,
+ CycleRecord.SOURCE_AGGREGATED)));
+ when(fixture.simulator.stepRecords(any(ChannelIdentity.class))).thenReturn(List.of(new StepRecord(
+ "neware:442:step:3:7", 3, 7, null, "7", CAPTURED_AT.minusSeconds(60), CAPTURED_AT, 1.3, 0.4, null, null,
+ CAPTURED_AT.toString(), "Asia/Hong_Kong", CAPTURED_AT,
+ java.util.Map.of("chargeCapacity", new BigDecimal("13.888888888889")))));
+ when(fixture.mapper.insertCycleRecord(any())).thenReturn(1);
+ when(fixture.mapper.insertStepRecord(any())).thenReturn(1);
+
+ fixture.service().captureReceivedData();
+
+ ArgumentCaptor<TTestCycleRecord> cycle = ArgumentCaptor.forClass(TTestCycleRecord.class);
+ verify(fixture.mapper).insertCycleRecord(cycle.capture());
+ assertEquals(CycleRecord.SOURCE_AGGREGATED, cycle.getValue().getSourceKind());
+ // 没有可用充电容量就没有效率:空值不是零。
+ assertNull(cycle.getValue().getEfficiency());
+ assertEquals(new BigDecimal("2.375"), cycle.getValue().getChargeCapacityAh());
+
+ ArgumentCaptor<TTestStepRecord> step = ArgumentCaptor.forClass(TTestStepRecord.class);
+ verify(fixture.mapper).insertStepRecord(step.capture());
+ // 方向未确认的工步没有单项容量与能量:落库保持空值,四组明细仍在扩展里。
+ assertNull(step.getValue().getCapacityAh());
+ assertNull(step.getValue().getEnergyWh());
+ assertTrue(step.getValue().getExtensionMeasurementsJson().contains("chargeCapacity"));
}
@Test void deletedAggregateDoesNotReturnOnRepeatedObservation()
{
Fixture fixture = fixture();
when(fixture.simulator.stepRecords(any())).thenReturn(List.of(new StepRecord("deleted", 1, 1, "工步", "cc",
- CAPTURED_AT.minusSeconds(10), CAPTURED_AT, 3, 1, 2, CAPTURED_AT.toString(), "UTC", CAPTURED_AT, java.util.Map.of())));
+ CAPTURED_AT.minusSeconds(10), CAPTURED_AT, 3d, 1.5d, 1d, 2d, CAPTURED_AT.toString(), "UTC", CAPTURED_AT,
+ java.util.Map.of())));
when(fixture.mapper.wasAggregateDeleted(1L, "STEP", 4L, "dev-sim:22:1:1:1", "record:deleted")).thenReturn(true);
fixture.service().captureReceivedData();
verify(fixture.mapper, never()).insertStepRecord(any());
--
Gitblit v1.7.1