90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package telemetry
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
|
)
|
|
|
|
type MileageFieldMapping struct {
|
|
Key string
|
|
Scale float64
|
|
}
|
|
|
|
// MileageFieldMappings is the single protocol-to-unit contract used by every
|
|
// projection that exposes or calculates total mileage.
|
|
func MileageFieldMappings(protocol envelope.Protocol) []MileageFieldMapping {
|
|
switch protocol {
|
|
case envelope.ProtocolGB32960:
|
|
return []MileageFieldMapping{{Key: "gb32960.vehicle.total_mileage_km", Scale: 1}}
|
|
case envelope.ProtocolJT808:
|
|
return []MileageFieldMapping{{Key: "jt808.location.total_mileage_km", Scale: 1}}
|
|
case envelope.ProtocolYutongMQTT:
|
|
return []MileageFieldMapping{
|
|
{Key: "yutong_mqtt.data.total_mileage_km", Scale: 1},
|
|
{Key: "yutong_mqtt.root.data.total_mileage_km", Scale: 1},
|
|
{Key: "yutong_mqtt.data.total_mileage", Scale: 0.001},
|
|
{Key: "yutong_mqtt.root.data.total_mileage", Scale: 0.001},
|
|
}
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func TotalMileageKM(protocol envelope.Protocol, fields map[string]any) (float64, bool) {
|
|
for _, mapping := range MileageFieldMappings(protocol) {
|
|
value, ok := Number(fields, mapping.Key)
|
|
if !ok {
|
|
continue
|
|
}
|
|
return value * mapping.Scale, true
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
func Number(fields map[string]any, key string) (float64, bool) {
|
|
if len(fields) == 0 {
|
|
return 0, false
|
|
}
|
|
value, ok := fields[key]
|
|
if !ok || value == nil {
|
|
return 0, false
|
|
}
|
|
switch typed := value.(type) {
|
|
case float64:
|
|
return typed, true
|
|
case float32:
|
|
return float64(typed), true
|
|
case int:
|
|
return float64(typed), true
|
|
case int8:
|
|
return float64(typed), true
|
|
case int16:
|
|
return float64(typed), true
|
|
case int32:
|
|
return float64(typed), true
|
|
case int64:
|
|
return float64(typed), true
|
|
case uint:
|
|
return float64(typed), true
|
|
case uint8:
|
|
return float64(typed), true
|
|
case uint16:
|
|
return float64(typed), true
|
|
case uint32:
|
|
return float64(typed), true
|
|
case uint64:
|
|
return float64(typed), true
|
|
case json.Number:
|
|
parsed, err := typed.Float64()
|
|
return parsed, err == nil
|
|
case string:
|
|
parsed, err := strconv.ParseFloat(strings.TrimSpace(typed), 64)
|
|
return parsed, err == nil
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|