feat: expand vehicle data platform capabilities

This commit is contained in:
lingniu
2026-07-27 16:46:15 +08:00
parent e3a1f80f86
commit 3c4bece72c
650 changed files with 62155 additions and 2552 deletions

View File

@@ -118,6 +118,40 @@ func TestSamplesFromEnvelopeMapsProtocolMileageFields(t *testing.T) {
}
}
func TestSamplesFromEnvelopeCarriesPureHydrogenWorkMode(t *testing.T) {
loc := time.FixedZone("Asia/Shanghai", 8*3600)
tests := []struct {
name string
protocol envelope.Protocol
mode int
}{
{name: "gb32960 fuel cell engine running", protocol: envelope.ProtocolGB32960, mode: 2},
{name: "yutong fuel cell driving", protocol: envelope.ProtocolYutongMQTT, mode: 11},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fields := map[string]any{envelope.FieldFuelCellWorkMode: test.mode}
if test.protocol == envelope.ProtocolGB32960 {
fields["gb32960.vehicle.total_mileage_km"] = 12000.5
} else {
fields["yutong_mqtt.data.total_mileage"] = 12000500
}
samples, err := SamplesFromEnvelope(envelope.FrameEnvelope{
Protocol: test.protocol,
VIN: "LNBVIN00000000001",
EventTimeMS: time.Date(2026, 7, 23, 8, 30, 0, 0, loc).UnixMilli(),
Fields: fields,
}, loc)
if err != nil || len(samples) != 1 {
t.Fatalf("SamplesFromEnvelope() samples=%d error=%v", len(samples), err)
}
if !samples[0].PureHydrogenModeKnown || !samples[0].PureHydrogenActive {
t.Fatalf("pure hydrogen evidence missing: %#v", samples[0])
}
})
}
}
func TestSamplesFromEnvelopeFallsBackToReceivedTimeWhenEventTimeIsFuture(t *testing.T) {
loc := time.FixedZone("Asia/Shanghai", 8*3600)
received := time.Date(2026, 7, 8, 23, 59, 0, 0, loc)
@@ -1035,9 +1069,13 @@ func TestWriterAppendUsesCurrentSampleWhenNoHistoricalBaseline(t *testing.T) {
float64(4123.9),
float64(4123.9),
float64(0),
float64(0),
int64(1),
int64(0),
eventTime,
eventTime,
false,
false,
QualityOK,
QualityReasonCurrentDayFirst,
).
@@ -1115,9 +1153,13 @@ func TestWriterCachesMissingBaselineAfterSuccessfulFirstSample(t *testing.T) {
float64(4123.9),
float64(4123.9),
float64(0),
float64(0),
int64(1),
int64(0),
firstTime,
firstTime,
false,
false,
QualityOK,
QualityReasonCurrentDayFirst,
).
@@ -1161,9 +1203,13 @@ func TestWriterCachesMissingBaselineAfterSuccessfulFirstSample(t *testing.T) {
float64(4123.9),
float64(4124.4),
approxFloat64{want: 0.5, tolerance: 0.000001},
float64(0),
int64(1),
int64(0),
firstTime,
secondTime,
false,
false,
QualityOK,
QualityReasonCurrentDayFirst,
).
@@ -1356,9 +1402,13 @@ func TestWriterAppendUsesPreviousSourceBaselineForRealtimeCandidate(t *testing.T
float64(4100.8),
float64(4123.9),
approxFloat64{want: 23.1, tolerance: 0.000001},
float64(0),
int64(1),
int64(0),
previousTime,
currentTime,
false,
false,
QualityOK,
QualityReasonHistorical,
).
@@ -1441,9 +1491,13 @@ func TestWriterAppendUsesOlderHistoricalSourceBaseline(t *testing.T) {
float64(120672.0),
float64(120788.0),
approxFloat64{want: 116.0, tolerance: 0.000001},
float64(0),
int64(1),
int64(0),
historicalTime,
currentTime,
false,
false,
QualityOK,
QualityReasonHistorical,
).
@@ -1776,9 +1830,13 @@ func TestWriterAppendMarksCandidateNoPreviousBaselineWhenPreviousBaselineMissing
float64(4136.8),
float64(4136.8),
float64(0),
float64(0),
int64(1),
int64(0),
currentTime,
currentTime,
false,
false,
QualityOK,
QualityReasonCurrentDayFirst,
).
@@ -1836,7 +1894,7 @@ func TestWriterEnsuresSchemaAndUpsertsDailyMileage(t *testing.T) {
t.Fatalf("Append() error = %v", err)
}
schemaCalls := 4 + len(DailyMileageAlterSQL)
schemaCalls := 6 + len(DailyMileageAlterSQL)
if len(exec.calls) != schemaCalls+5 {
t.Fatalf("exec calls = %d", len(exec.calls))
}
@@ -1845,6 +1903,8 @@ func TestWriterEnsuresSchemaAndUpsertsDailyMileage(t *testing.T) {
"CREATE TABLE IF NOT EXISTS vehicle_daily_gps_mileage_state",
"CREATE TABLE IF NOT EXISTS vehicle_daily_mileage_source",
"CREATE TABLE IF NOT EXISTS vehicle_daily_mileage",
"CREATE TABLE IF NOT EXISTS vehicle_hydrogen_tank_capacity",
"CREATE TABLE IF NOT EXISTS vehicle_open_hydrogen_stream_state",
} {
if !strings.Contains(exec.calls[i].query, want) {
t.Fatalf("schema call %d = %s, want %s", i, exec.calls[i].query, want)
@@ -2040,7 +2100,7 @@ func TestWriterCarriesPreviousYutongMileageIntoStationaryDay(t *testing.T) {
if got := sourceWrite.args[11]; got != float64(0) {
t.Fatalf("daily mileage = %#v, want explicit zero", got)
}
if got := sourceWrite.args[16]; got != QualityReasonStationaryCarry {
if got := sourceWrite.args[20]; got != QualityReasonStationaryCarry {
t.Fatalf("quality reason = %#v, want %q", got, QualityReasonStationaryCarry)
}
}
@@ -2249,9 +2309,13 @@ func TestWriterRollsBackMileageTransactionWhenProjectionFails(t *testing.T) {
float64(4123.9),
float64(4123.9),
float64(0),
float64(0),
int64(1),
int64(0),
eventTime,
eventTime,
false,
false,
QualityOK,
QualityReasonCurrentDayFirst,
).