98 lines
2.9 KiB
Go
98 lines
2.9 KiB
Go
package envelope
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Protocol string
|
|
|
|
const (
|
|
ProtocolGB32960 Protocol = "GB32960"
|
|
ProtocolJT808 Protocol = "JT808"
|
|
ProtocolYutongMQTT Protocol = "YUTONG_MQTT"
|
|
)
|
|
|
|
type ParseStatus string
|
|
|
|
const (
|
|
ParseOK ParseStatus = "OK"
|
|
ParsePartial ParseStatus = "PARTIAL"
|
|
ParseBadFrame ParseStatus = "BAD_FRAME"
|
|
)
|
|
|
|
const (
|
|
FieldSpeedKMH = "speed_kmh"
|
|
FieldTotalMileageKM = "total_mileage_km"
|
|
FieldLongitude = "longitude"
|
|
FieldLatitude = "latitude"
|
|
FieldSOCPercent = "soc_percent"
|
|
)
|
|
|
|
type FrameEnvelope struct {
|
|
EventID string `json:"event_id"`
|
|
TraceID string `json:"trace_id"`
|
|
Protocol Protocol `json:"protocol"`
|
|
MessageID string `json:"message_id"`
|
|
Sequence uint16 `json:"sequence"`
|
|
VIN string `json:"vin,omitempty"`
|
|
VehicleKeyHint string `json:"vehicle_key,omitempty"`
|
|
Phone string `json:"phone,omitempty"`
|
|
DeviceID string `json:"device_id,omitempty"`
|
|
Plate string `json:"plate,omitempty"`
|
|
SourceEndpoint string `json:"source_endpoint,omitempty"`
|
|
EventTimeMS int64 `json:"event_time_ms"`
|
|
ReceivedAtMS int64 `json:"received_at_ms"`
|
|
RawHex string `json:"raw_hex,omitempty"`
|
|
RawText string `json:"raw_text,omitempty"`
|
|
Parsed map[string]any `json:"parsed,omitempty"`
|
|
ParsedFields map[string]any `json:"parsed_fields,omitempty"`
|
|
ParsedFieldTypes map[string]string `json:"parsed_field_types,omitempty"`
|
|
Fields map[string]any `json:"fields,omitempty"`
|
|
ParseStatus ParseStatus `json:"parse_status"`
|
|
ParseError string `json:"parse_error,omitempty"`
|
|
}
|
|
|
|
func (e FrameEnvelope) VehicleKey() string {
|
|
if key := strings.TrimSpace(e.VIN); key != "" {
|
|
return key
|
|
}
|
|
if key := strings.TrimSpace(e.Phone); key != "" {
|
|
return string(e.Protocol) + ":" + key
|
|
}
|
|
if key := strings.TrimSpace(e.VehicleKeyHint); key != "" {
|
|
return key
|
|
}
|
|
if key := strings.TrimSpace(e.DeviceID); key != "" {
|
|
return string(e.Protocol) + ":" + key
|
|
}
|
|
return string(e.Protocol) + ":unknown"
|
|
}
|
|
|
|
func (e FrameEnvelope) StableEventID() string {
|
|
if strings.TrimSpace(e.EventID) != "" {
|
|
return e.EventID
|
|
}
|
|
input := fmt.Sprintf("%s|%s|%s|%d|%d|%s",
|
|
e.Protocol, e.MessageID, e.VehicleKey(), e.Sequence, e.EventTimeMS, e.RawHex)
|
|
sum := sha256.Sum256([]byte(input))
|
|
return hex.EncodeToString(sum[:16])
|
|
}
|
|
|
|
func (e FrameEnvelope) KafkaKey() []byte {
|
|
return []byte(e.VehicleKey())
|
|
}
|
|
|
|
func (e FrameEnvelope) MarshalJSONBytes() ([]byte, error) {
|
|
if e.EventID == "" {
|
|
e.EventID = e.StableEventID()
|
|
}
|
|
if e.ParseStatus == "" {
|
|
e.ParseStatus = ParseOK
|
|
}
|
|
return json.Marshal(e)
|
|
}
|