99 lines
2.3 KiB
Go
99 lines
2.3 KiB
Go
package cache
|
|
|
|
import (
|
|
"fiskerinc.com/modules/common"
|
|
"fiskerinc.com/modules/logger"
|
|
"fiskerinc.com/modules/redis"
|
|
|
|
redigo "github.com/gomodule/redigo/redis"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
|
|
func GetVINListDigitalTwin(vins []string, clientPool redis.ClientPoolInterface) (digitalTwins map[string]common.CarState, errorList []error) {
|
|
digitalTwins = make(map[string]common.CarState)
|
|
client := clientPool.GetFromPool()
|
|
defer client.Close()
|
|
|
|
batch := redis.NewRedisBatchCommands()
|
|
for _, vin := range vins {
|
|
batch.Add("SISMEMBER", redis.CarSessionsKey(), vin)
|
|
batch.Add("SISMEMBER", redis.HMISessionsKey(), vin)
|
|
batch.Add("HGETALL", redis.CarStateHashKey(vin))
|
|
|
|
}
|
|
|
|
payload, err := redigo.Values(client.ExecuteBatch(batch))
|
|
if err != nil {
|
|
errorList = append(errorList, err)
|
|
return
|
|
}
|
|
|
|
for index, vin := range vins {
|
|
startPoint := index * 3
|
|
tempTwin, err := ParsePayloadForVehicleState(payload[startPoint:startPoint+3])
|
|
if err != nil {
|
|
err = errors.WithMessage(err, vin)
|
|
errorList = append(errorList, err)
|
|
continue
|
|
}
|
|
digitalTwins[vin] = tempTwin
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func ParsePayloadForVehicleState(payload []interface{}) (common.CarState, error) {
|
|
var state common.CarState
|
|
|
|
online, err := redigo.Bool(payload[0], nil)
|
|
if err != nil {
|
|
return state, err
|
|
} else {
|
|
state.Online = online
|
|
}
|
|
|
|
online, err = redigo.Bool(payload[1], nil)
|
|
if err != nil {
|
|
return state, errors.WithStack(err)
|
|
} else {
|
|
state.OnlineHMI = online
|
|
}
|
|
|
|
err = parseCarStatePayload(&state, payload[2])
|
|
|
|
return state, err
|
|
}
|
|
|
|
func parseCarStatePayload(state *common.CarState, payload interface{}) error {
|
|
stateValues, err := redigo.Values(payload, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(stateValues)%2 != 0 {
|
|
return errors.New("object does not contain equal number of key value pairs")
|
|
}
|
|
|
|
err = parseStateValues(state, stateValues, parseCarState)
|
|
|
|
return err
|
|
}
|
|
|
|
func parseStateValues(state *common.CarState, stateValues []interface{}, parser stateParser) error {
|
|
for i := 0; i < len(stateValues); i += 2 {
|
|
key, okKey := stateValues[i].([]byte)
|
|
value, okValue := stateValues[i+1].([]byte)
|
|
|
|
if !okKey || !okValue {
|
|
return errors.New("cannot parse object into car state")
|
|
}
|
|
|
|
err := parser(state, string(key), value)
|
|
// log error, do not return error so we can read other properties for digital twin
|
|
if err != nil {
|
|
logger.Err(err).Send()
|
|
}
|
|
}
|
|
|
|
return nil
|
|
} |