Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
143
pkg/dbc/models/can_message.go
Normal file
143
pkg/dbc/models/can_message.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"fiskerinc.com/modules/dbc/state"
|
||||
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/digitaltwin"
|
||||
)
|
||||
|
||||
type CANMessageInterface interface {
|
||||
AddSignal(signal CANSignal) CANMessageInterface
|
||||
GetID() int
|
||||
GetLength() int
|
||||
ParseState(keyvaluesOut map[string]interface{}, vin string, timestampUSec int, incomingSignals []common.CANSignal, cached digitaltwin.DigitalTwinCacheInterface) error
|
||||
Signal(position int, name string, convert func(value float64) interface{}) CANMessageInterface
|
||||
}
|
||||
|
||||
// NewCANMessage creates a top level instance for parsing a command. The id is the can signal in which individual signals exists
|
||||
// length is the number of messages inside the message, i.e. 1318 TBOX_0x526 has 2 different signals: TBOX_GPSLongi and TBOX_GPSLati
|
||||
func NewCANMessage(id int, length int) CANMessageInterface {
|
||||
return &CANMessage{
|
||||
id: id,
|
||||
length: length,
|
||||
}
|
||||
}
|
||||
|
||||
type CANMessage struct {
|
||||
id int
|
||||
length int
|
||||
signals map[int]CANSignal
|
||||
diagnostic map[int]DiagnosticSignal
|
||||
}
|
||||
|
||||
func (c *CANMessage) GetID() int {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func (c *CANMessage) GetLength() int {
|
||||
return c.length
|
||||
}
|
||||
|
||||
// position is the index of the signal in its list. Starting at zero
|
||||
func (c *CANMessage) Signal(position int, name string, convert func(value float64) interface{}) CANMessageInterface {
|
||||
c.AddSignal(NewCANSignal(position, name, convert))
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CANMessage) AddSignal(signal CANSignal) CANMessageInterface {
|
||||
m := c.getSignalsMap()
|
||||
if _, ok := m[signal.Position]; ok {
|
||||
panic(fmt.Sprintf("signal position %d already exists", signal.Position))
|
||||
}
|
||||
|
||||
m[signal.Position] = signal
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CANMessage) Diagnostic(position int, name string, alert float64) CANMessageInterface {
|
||||
c.AddDiagnostic(NewDiagnosticSignal(position, name, alert))
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CANMessage) AddDiagnostic(signal DiagnosticSignal) CANMessageInterface {
|
||||
m := c.getDiagnosticMap()
|
||||
if _, ok := m[signal.Position]; ok {
|
||||
panic(fmt.Sprintf("diagnositic position %d already exists", signal.Position))
|
||||
}
|
||||
|
||||
m[signal.Position] = signal
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CANMessage) getDiagnosticMap() map[int]DiagnosticSignal {
|
||||
if c.diagnostic == nil {
|
||||
c.diagnostic = map[int]DiagnosticSignal{}
|
||||
}
|
||||
|
||||
return c.diagnostic
|
||||
}
|
||||
|
||||
func (c *CANMessage) getSignalsMap() map[int]CANSignal {
|
||||
if c.signals == nil {
|
||||
c.signals = map[int]CANSignal{}
|
||||
}
|
||||
|
||||
return c.signals
|
||||
}
|
||||
|
||||
// cached: Checks if the new signal has the same value as it did the last time, if so don't update it
|
||||
func (c *CANMessage) ParseState(keyvaluesOut map[string]interface{}, vin string, timestampUSec int, incomingSignals []common.CANSignal, cached digitaltwin.DigitalTwinCacheInterface) error {
|
||||
var can CANSignal
|
||||
var ok bool
|
||||
|
||||
s := c.getSignalsMap()
|
||||
|
||||
for i, signal := range incomingSignals {
|
||||
if can, ok = s[i]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if can.Name != signal.Name {
|
||||
return IncorrectSignalError(can.Name, signal.Name)
|
||||
}
|
||||
|
||||
val := can.ParseState(incomingSignals[i])
|
||||
|
||||
if cached != nil && cached.Exists(vin, signal.Name, val) {
|
||||
continue
|
||||
}
|
||||
keyvaluesOut[signal.Name] = val
|
||||
|
||||
// Added updated time for each signals. Key format -> "${signal_name}:updated"
|
||||
updatedAt, _ := state.SerializeTimestampUSec(timestampUSec)
|
||||
keyvaluesOut[fmt.Sprintf("%s:%s", signal.Name, "updated")] = updatedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (c *CANMessage) DiagnosticAlert(vin string, timestampUSec int, signals []common.CANSignal) ([]DiagnosticSignal, error) {
|
||||
var flags []DiagnosticSignal
|
||||
|
||||
m := c.getDiagnosticMap()
|
||||
|
||||
for i, signal := range signals {
|
||||
if diag, ok := m[i]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if diag.Name != signal.Name {
|
||||
return nil, IncorrectSignalError(diag.Name, signal.Name)
|
||||
}
|
||||
|
||||
append(flags, diag)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user