fix: normalize yutong mqtt mileage units

This commit is contained in:
lingniu
2026-07-02 01:04:14 +08:00
parent 3ee1d6f52b
commit 7ad1a25e8e
2 changed files with 32 additions and 1 deletions

View File

@@ -69,7 +69,7 @@ func fieldsFromData(data map[string]any) map[string]any {
fields[envelope.FieldSpeedKMH] = speed fields[envelope.FieldSpeedKMH] = speed
} }
if mileage, ok := firstFloat(data, "TOTAL_MILEAGE", "totalMileage", "total_mileage_km"); ok { if mileage, ok := firstFloat(data, "TOTAL_MILEAGE", "totalMileage", "total_mileage_km"); ok {
fields[envelope.FieldTotalMileageKM] = mileage fields[envelope.FieldTotalMileageKM] = normalizeTotalMileageKM(mileage)
} }
if soc, ok := firstFloat(data, "BATTERY_CAPACITY_SOC", "soc", "SOC", "soc_percent"); ok { if soc, ok := firstFloat(data, "BATTERY_CAPACITY_SOC", "soc", "SOC", "soc_percent"); ok {
fields[envelope.FieldSOCPercent] = soc fields[envelope.FieldSOCPercent] = soc
@@ -166,6 +166,14 @@ func parseTimeMS(raw string, fallback int64) int64 {
if raw == "" { if raw == "" {
return fallback return fallback
} }
for _, layout := range []string{
"2006-01-02 15:04:05.000",
"2006-01-02 15:04:05",
} {
if parsed, err := time.ParseInLocation(layout, raw, time.FixedZone("Asia/Shanghai", 8*3600)); err == nil {
return parsed.UnixMilli()
}
}
if len(raw) == 14 { if len(raw) == 14 {
if parsed, err := time.ParseInLocation("20060102150405", raw, time.FixedZone("Asia/Shanghai", 8*3600)); err == nil { if parsed, err := time.ParseInLocation("20060102150405", raw, time.FixedZone("Asia/Shanghai", 8*3600)); err == nil {
return parsed.UnixMilli() return parsed.UnixMilli()
@@ -187,3 +195,10 @@ func looksLikeVIN(value string) bool {
value = strings.TrimSpace(value) value = strings.TrimSpace(value)
return len(value) == 17 return len(value) == 17
} }
func normalizeTotalMileageKM(value float64) float64 {
if value > 1_000_000 {
return value / 1000
}
return value
}

View File

@@ -64,6 +64,22 @@ func TestParseMessageUsesDeviceAsVehicleKeyWhenNotVIN(t *testing.T) {
assertFloatField(t, env, envelope.FieldSpeedKMH, 12.3) assertFloatField(t, env, envelope.FieldSpeedKMH, 12.3)
} }
func TestParseMessageNormalizesProductionMileageMeters(t *testing.T) {
payload := []byte(`{
"device":"LMRKH9AC3R1004101",
"time":"2026-07-02 01:02:04.085",
"data":{"TOTAL_MILEAGE":56905000,"METER_SPEED":19}
}`)
env, err := ParseMessage("yutong", "/ytforward/shln/1", payload, 1782940000000)
if err != nil {
t.Fatalf("ParseMessage() error = %v", err)
}
assertFloatField(t, env, envelope.FieldTotalMileageKM, 56905)
if env.EventTimeMS != 1782925324085 {
t.Fatalf("event time = %d, want 1782925324085", env.EventTimeMS)
}
}
func TestParseMessageRejectsMalformedJSON(t *testing.T) { func TestParseMessageRejectsMalformedJSON(t *testing.T) {
_, err := ParseMessage("endpoint-a", "/bad", []byte("{bad-json"), 1782745114999) _, err := ParseMessage("endpoint-a", "/bad", []byte("{bad-json"), 1782745114999)
if !errors.Is(err, ErrInvalidJSON) { if !errors.Is(err, ErrInvalidJSON) {