feat: build vehicle data platform and production pipeline
This commit is contained in:
@@ -14,33 +14,93 @@ func IsRealtimeTelemetryFrame(env FrameEnvelope) bool {
|
||||
command = strings.TrimSpace(stringAny(header["command"]))
|
||||
}
|
||||
}
|
||||
if strings.EqualFold(command, "0x02") || strings.EqualFold(command, "0x03") {
|
||||
return true
|
||||
if command != "" && !strings.EqualFold(command, "0x02") && !strings.EqualFold(command, "0x03") {
|
||||
return false
|
||||
}
|
||||
_, hasDataUnits := env.Parsed["data_units"]
|
||||
return hasDataUnits || hasRealtimeField(env)
|
||||
return hasDataUnits || hasGB32960ParsedTelemetryField(env) || hasRealtimeField(env)
|
||||
case ProtocolJT808:
|
||||
if strings.EqualFold(strings.TrimSpace(env.MessageID), "0x0200") {
|
||||
return true
|
||||
messageID := strings.TrimSpace(env.MessageID)
|
||||
if messageID != "" && !strings.EqualFold(messageID, "0x0200") {
|
||||
return false
|
||||
}
|
||||
if _, ok := env.Parsed["location"]; ok {
|
||||
return true
|
||||
}
|
||||
return hasRealtimeField(env)
|
||||
return hasParsedFieldPrefix(env, "jt808.location.") || hasRealtimeField(env)
|
||||
case ProtocolYutongMQTT:
|
||||
data, ok := env.Parsed["data"].(map[string]any)
|
||||
return ok && len(data) > 0
|
||||
if ok && len(data) > 0 {
|
||||
return true
|
||||
}
|
||||
return hasParsedFieldPrefix(env, "yutong_mqtt.data.") ||
|
||||
hasParsedFieldPrefix(env, "yutong_mqtt.root.data.")
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func hasGB32960ParsedTelemetryField(env FrameEnvelope) bool {
|
||||
for field := range env.ParsedFields {
|
||||
if !strings.HasPrefix(field, "gb32960.") {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(field, "gb32960.header.") ||
|
||||
strings.HasPrefix(field, "gb32960.platform.") ||
|
||||
strings.HasPrefix(field, "gb32960.identity.") ||
|
||||
strings.HasPrefix(field, "gb32960.device_time.") {
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RequiresVehicleIdentity keeps platform/control frames out of vehicle identity
|
||||
// quality metrics while preserving JT808's phone-centric registration/auth flow.
|
||||
func RequiresVehicleIdentity(env FrameEnvelope) bool {
|
||||
if env.ParseStatus == ParseBadFrame {
|
||||
return false
|
||||
}
|
||||
switch env.Protocol {
|
||||
case ProtocolGB32960:
|
||||
return IsRealtimeTelemetryFrame(env)
|
||||
case ProtocolJT808:
|
||||
return true
|
||||
case ProtocolYutongMQTT:
|
||||
return IsRealtimeTelemetryFrame(env)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func hasRealtimeField(env FrameEnvelope) bool {
|
||||
return env.Fields[FieldLatitude] != nil ||
|
||||
if env.Fields[FieldLatitude] != nil ||
|
||||
env.Fields[FieldLongitude] != nil ||
|
||||
env.Fields[FieldTotalMileageKM] != nil ||
|
||||
env.Fields[FieldSpeedKMH] != nil ||
|
||||
env.Fields[FieldSOCPercent] != nil
|
||||
env.Fields[FieldSOCPercent] != nil {
|
||||
return true
|
||||
}
|
||||
for field := range env.ParsedFields {
|
||||
if strings.HasSuffix(field, ".latitude") ||
|
||||
strings.HasSuffix(field, ".longitude") ||
|
||||
strings.HasSuffix(field, ".total_mileage_km") ||
|
||||
strings.HasSuffix(field, ".speed_kmh") ||
|
||||
strings.HasSuffix(field, ".soc_percent") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasParsedFieldPrefix(env FrameEnvelope, prefix string) bool {
|
||||
for field := range env.ParsedFields {
|
||||
if strings.HasPrefix(field, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func stringAny(value any) string {
|
||||
|
||||
Reference in New Issue
Block a user