fix: keep valid realtime mileage
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -155,6 +156,9 @@ func mergeFields(snapshot *Snapshot, fields map[string]any, eventMS int64) {
|
|||||||
snapshot.FieldTimesMS = map[string]int64{}
|
snapshot.FieldTimesMS = map[string]int64{}
|
||||||
}
|
}
|
||||||
for key, value := range fields {
|
for key, value := range fields {
|
||||||
|
if key == envelope.FieldTotalMileageKM && !positiveNumber(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if eventMS >= snapshot.FieldTimesMS[key] {
|
if eventMS >= snapshot.FieldTimesMS[key] {
|
||||||
snapshot.Fields[key] = value
|
snapshot.Fields[key] = value
|
||||||
snapshot.FieldTimesMS[key] = eventMS
|
snapshot.FieldTimesMS[key] = eventMS
|
||||||
@@ -162,6 +166,28 @@ func mergeFields(snapshot *Snapshot, fields map[string]any, eventMS int64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func positiveNumber(value any) bool {
|
||||||
|
switch typed := value.(type) {
|
||||||
|
case float64:
|
||||||
|
return typed > 0
|
||||||
|
case float32:
|
||||||
|
return typed > 0
|
||||||
|
case int:
|
||||||
|
return typed > 0
|
||||||
|
case int64:
|
||||||
|
return typed > 0
|
||||||
|
case uint16:
|
||||||
|
return typed > 0
|
||||||
|
case uint32:
|
||||||
|
return typed > 0
|
||||||
|
case string:
|
||||||
|
parsed, err := strconv.ParseFloat(strings.TrimSpace(typed), 64)
|
||||||
|
return err == nil && parsed > 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func cloneFields(fields map[string]any) map[string]any {
|
func cloneFields(fields map[string]any) map[string]any {
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
return map[string]any{}
|
return map[string]any{}
|
||||||
|
|||||||
@@ -94,6 +94,47 @@ func TestRepositoryOnlineStatus(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoryDoesNotOverwritePositiveMileageWithZero(t *testing.T) {
|
||||||
|
repo, closeFn := newTestRepository(t)
|
||||||
|
defer closeFn()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
if err := repo.Update(ctx, envelope.FrameEnvelope{
|
||||||
|
Protocol: envelope.ProtocolJT808,
|
||||||
|
VIN: "VIN001",
|
||||||
|
EventTimeMS: 1000,
|
||||||
|
ReceivedAtMS: 1100,
|
||||||
|
Fields: map[string]any{
|
||||||
|
envelope.FieldTotalMileageKM: 12345.6,
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("Update() error = %v", err)
|
||||||
|
}
|
||||||
|
if err := repo.Update(ctx, envelope.FrameEnvelope{
|
||||||
|
Protocol: envelope.ProtocolJT808,
|
||||||
|
VIN: "VIN001",
|
||||||
|
EventTimeMS: 2000,
|
||||||
|
ReceivedAtMS: 2100,
|
||||||
|
Fields: map[string]any{
|
||||||
|
envelope.FieldSpeedKMH: 22.0,
|
||||||
|
envelope.FieldTotalMileageKM: 0,
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("Update() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
merged, err := repo.GetMerged(ctx, "VIN001")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetMerged() error = %v", err)
|
||||||
|
}
|
||||||
|
if merged.Fields[envelope.FieldTotalMileageKM] != 12345.6 {
|
||||||
|
t.Fatalf("zero mileage overwrote positive value: %#v", merged.Fields)
|
||||||
|
}
|
||||||
|
if merged.Fields[envelope.FieldSpeedKMH] != 22.0 {
|
||||||
|
t.Fatalf("new speed should still merge: %#v", merged.Fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestHandlerReturnsMergedSnapshot(t *testing.T) {
|
func TestHandlerReturnsMergedSnapshot(t *testing.T) {
|
||||||
repo, closeFn := newTestRepository(t)
|
repo, closeFn := newTestRepository(t)
|
||||||
defer closeFn()
|
defer closeFn()
|
||||||
|
|||||||
Reference in New Issue
Block a user