Files
cloud-services/pkg/cache/vehicle_state_multi.go

99 lines
2.4 KiB
Go

package cache
import (
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/fiskerinc/cloud-services/pkg/logger"
"github.com/fiskerinc/cloud-services/pkg/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
}