package common import ( "encoding/json" "log" "time" "github.com/fiskerinc/cloud-services/pkg/grpc/kafka_grpc" "github.com/fiskerinc/cloud-services/pkg/logger" "github.com/google/uuid" ) type ConsumerPayloadInterface interface { GetHandler() string GetData() []byte } type ConsumerPayload struct { Handler string Data []byte } func (cp *ConsumerPayload) GetHandler() string { return cp.Handler } func (cp *ConsumerPayload) GetData() []byte { return cp.Data } // ##################################################################################################### // ################################## Depot ############################################################ // ##################################################################################################### func DepotRouteTRexPayload(payload *kafka_grpc.GRPC_DepotPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "init": data := GRPCToMessage(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func DepotRouteHMIPayload(payload *kafka_grpc.GRPC_DepotPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "init": data := GRPCToHMISession(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func DepotRouteMobilePayload(payload *kafka_grpc.GRPC_DepotPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } return message, nil } func GRPCToMessage(payload *kafka_grpc.GRPC_DepotPayload) map[string]string { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_DepotPayload_InitPayload: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_DepotPayload_InitPayload) return data.InitPayload.Data } func GRPCToHMISession(payload *kafka_grpc.GRPC_DepotPayload) *HMISessionData { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_DepotPayload_HmiSession: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_DepotPayload_HmiSession) return &HMISessionData{ SessionID: data.HmiSession.SessionId, VIN: data.HmiSession.Vin, Salt: data.HmiSession.Salt, } } // ##################################################################################################### // ################################## End Depot ######################################################## // ##################################################################################################### // ##################################################################################################### // ################################## Attendant ######################################################## // ##################################################################################################### func AttendantRouteTRexPayload(payload *kafka_grpc.GRPC_AttendantPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "car_state": data := GRPCToCarState(payload) if data == nil { break } message.Data, _ = json.Marshal(data) case "car_update_status", "car_update_download", "car_update_install": data := GRPCToCarUpdate(payload) if data == nil { break } message.Data, _ = json.Marshal(data) case "get_filekeys": data := GRPCToCarFileKeysRequest(payload) if data == nil { break } message.Data, _ = json.Marshal(data) case "ecc_keys": data := GRPCToCarUpdateRequest(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func AttendantRouteHMIPayload(payload *kafka_grpc.GRPC_AttendantPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "update_approve": if payload.Data != nil { data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_UpdateApprove) if data == nil { break } m := map[string]int{ "id": int(data.UpdateApprove.Id), } message.Data, _ = json.Marshal(m) } case "car_update_status", "car_update_download", "car_update_install": data := GRPCToCarUpdate(payload) if data == nil { break } message.Data, _ = json.Marshal(data) case "get_filekeys": data := GRPCToCarFileKeysRequest(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func AttendantRouteMobilePayload(payload *kafka_grpc.GRPC_AttendantPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "update_approve": if payload.Data != nil { data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_UpdateApprove) if data == nil || data.UpdateApprove == nil { break } m := map[string]int{ "id": int(data.UpdateApprove.Id), } message.Data, _ = json.Marshal(m) } case "updates_get": if payload.Data != nil { data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_UpdateGet) if data == nil || data.UpdateGet == nil { break } m := map[string]string{ "vin": data.UpdateGet.Vin, } message.Data, _ = json.Marshal(m) } } return message, nil } func AttendantRouteServicePayload(payload *kafka_grpc.GRPC_AttendantPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "send_manifest": data := GRPCToUpdateManifest(payload) if data == nil { break } message.Data, _ = json.Marshal(data) case "order_updated": data := GRPCToOrder(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func GRPCToCarUpdateRequest(payload *kafka_grpc.GRPC_AttendantPayload) *CarUpdateRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_CarUpdateRequest: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_CarUpdateRequest) if data == nil { return nil } carReq := &CarUpdateRequest{ CarUpdateID: data.CarUpdateRequest.CarUpdateId, } return carReq } func GRPCToCarUpdate(payload *kafka_grpc.GRPC_AttendantPayload) *CarUpdateProgress { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_CarUpdateProgress: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_CarUpdateProgress) if data == nil { return nil } carProg := &CarUpdateProgress{ FileCurrent: data.CarUpdateProgress.FileCurrent, FileTotal: data.CarUpdateProgress.FileTotal, PackageCurrent: data.CarUpdateProgress.PkgCurrent, PackageTotal: data.CarUpdateProgress.PkgTotal, InstalledFiles: int(data.CarUpdateProgress.InstalledFiles), TotalFiles: int(data.CarUpdateProgress.TotalFiles), CarUpdateID: data.CarUpdateProgress.CarUpdateID, ECU: data.CarUpdateProgress.Ecu, Status: data.CarUpdateProgress.Status, Info: data.CarUpdateProgress.Info, ErrorCode: int(data.CarUpdateProgress.ErrCode), } return carProg } func GRPCToCarFileKeysRequest(payload *kafka_grpc.GRPC_AttendantPayload) *FileKeysRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_FileKeyReq: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_FileKeyReq) if data == nil { return nil } fileReq := &FileKeysRequest{ FileIDs: data.FileKeyReq.FileIDs, } return fileReq } func GRPCToECCKeys(payload *kafka_grpc.GRPC_AttendantPayload) []ECCKeys { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_Keys: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_Keys) if data == nil { return nil } var keys []ECCKeys for _, e := range data.Keys.EccKeys { output := toECCKey(e) keys = append(keys, *output) } return keys } func toECCKey(req *kafka_grpc.ECCKey) *ECCKeys { if req == nil { return nil } e := &ECCKeys{ ECU: req.Ecu, Env: req.Env, } if req.PubKeyLevel_1 != nil && req.PubKeyLevel_1.Data != nil { e.PubKey1 = (*BinaryHex)(&req.PubKeyLevel_1.Data) } if req.PubKeyLevel_2 != nil && req.PubKeyLevel_2.Data != nil { e.PubKey2 = (*BinaryHex)(&req.PubKeyLevel_2.Data) } if req.PubKeyLevel_3 != nil && req.PubKeyLevel_3.Data != nil { e.PubKey3 = (*BinaryHex)(&req.PubKeyLevel_3.Data) } if req.Level_1 != nil && req.Level_1.Data != nil { e.PrivKey1 = (*BinaryHex)(&req.Level_1.Data) } if req.Level_2 != nil && req.Level_2.Data != nil { e.PrivKey2 = (*BinaryHex)(&req.Level_2.Data) } if req.Level_3 != nil && req.Level_3.Data != nil { e.PrivKey3 = (*BinaryHex)(&req.Level_3.Data) } if req.Created != nil { t := milliToDate(*req.Created) e.CreatedAt = &t } if req.Updated != nil { t := milliToDate(*req.Updated) e.UpdatedAt = &t } return e } func GRPCToCarState(payload *kafka_grpc.GRPC_AttendantPayload) *CarStateUpdate { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_CarUpdateStatus: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_CarUpdateStatus) if data == nil { return nil } var ecus map[string]CarECU for key, val := range data.CarUpdateStatus.Ecus { if ecus == nil { ecus = make(map[string]CarECU) } carECU := CarECU{ VIN: val.Vin, ECU: val.Ecu, Version: val.SwVersion, SerialNumber: val.SerialNumber, HWVersion: val.HwVersion, BootLoaderVersion: val.BootLoaderVersion, Fingerprint: val.Fingerprint, Config: val.CodeDataString, Vendor: val.Vendor, SupplierSWVersion: val.SupplierSwVersion, Epoch_usec: val.EpochUsec, ASSYNumber: val.AssyNumber, } if val.CreatedAt != nil { t := milliToDate(*val.CreatedAt) carECU.CreatedAt = &t } if val.UpdatedAt != nil { t := milliToDate(*val.UpdatedAt) carECU.UpdatedAt = &t } ecus[key] = carECU } carState := &CarStateUpdate{ ECUs: ecus, } return carState } func GRPCToUpdateManifest(payload *kafka_grpc.GRPC_AttendantPayload) *UpdateManifest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_AttendantPayload_UpdateManifest: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_AttendantPayload_UpdateManifest) updateManifest := &UpdateManifest{ ID: data.UpdateManifest.Id, Name: data.UpdateManifest.Name, Version: data.UpdateManifest.Version, Description: data.UpdateManifest.Description, ReleaseNotes: data.UpdateManifest.ReleaseNotes, ECUList: data.UpdateManifest.EcuList, Fingerprint: data.UpdateManifest.Fingerprint, CarUpdateID: data.UpdateManifest.CarUpdateId, RollbackEnabled: data.UpdateManifest.Rollback, Type: data.UpdateManifest.Type, VOD: data.UpdateManifest.Vod, ManifestType: UpdateManifestType(data.UpdateManifest.ManifestType), Env: data.UpdateManifest.Env, UpdateDuration: int(data.UpdateManifest.UpdateDuration), MaxAttempts: int(data.UpdateManifest.MaxAttempts), Active: data.UpdateManifest.Active, Country: data.UpdateManifest.Country, BodyType: data.UpdateManifest.BodyType, Restraint: data.UpdateManifest.Restraint, PowerTrain: data.UpdateManifest.Powertrain, Model: data.UpdateManifest.Model, Trim: data.UpdateManifest.Trim, Year: int(data.UpdateManifest.Year), SUMS: data.UpdateManifest.Sums, } if data.UpdateManifest.Created != nil { t := milliToDate(*data.UpdateManifest.Created) updateManifest.CreatedAt = &t } if data.UpdateManifest.Updated != nil { t := milliToDate(*data.UpdateManifest.Updated) updateManifest.UpdatedAt = &t } var updateManifestECU []*UpdateManifestECU updateManifestECU = GRPCUpdateManifestECUToUpdateManifestECU(data.UpdateManifest.EcuUpdates, updateManifestECU) updateManifest.ECUs = updateManifestECU return updateManifest } func GRPCUpdateManifestECUToUpdateManifestECU(input []*kafka_grpc.UpdateManifestECU, output []*UpdateManifestECU) []*UpdateManifestECU { if len(input) == 0 { return nil } for _, u := range input { update := &UpdateManifestECU{ ID: u.Id, UpdateManifestID: u.ManifestId, ECU: u.Name, Version: u.Version, CurrentVersion: u.CurrentVersion, HWVersion: u.HwVersion, HWVersions: u.HwVersions, ConfigurationMask: u.ConfigurationMask, Configuration: u.Configuration, SelfDownload: u.SelfDownload, Mode: u.Mode, InstallPriority: int(u.InstallPriority), } if u.Created != nil { t := milliToDate(*u.Created) update.CreatedAt = &t } if u.Updated != nil { t := milliToDate(*u.Updated) update.UpdatedAt = &t } update.ECCKeys = toECCKey(u.EccKeys) if len(u.Files) > 0 { fileInBytes := toBinaryArray(u.Files) if len(fileInBytes) > 0 { var files []*UpdateManifestFile err := json.Unmarshal(fileInBytes, &files) if err != nil { log.Println(err) log.Println(string(fileInBytes)) logger.Warn().Msgf("unable to parse Files of %s", string(fileInBytes)) } update.Files = files } } if len(u.Rollback) > 0 { update.Rollback = make([]*UpdateManifestECU, 0, len(u.Rollback)) update.Rollback = GRPCUpdateManifestECUToUpdateManifestECU(u.Rollback, update.Rollback) } output = append(output, update) } return output } // func UpdateNotificationToGRPC(notification *UpdateAvailableNotification) *kafka_grpc.GRPC_AttendantPayload { // if notification == nil { // return nil // } // updateManifest := &kafka_grpc.UpdateManifest{ // Id: // Name: notification.Name, // Description: notification.Description, // Version: notification.Version, // ReleaseNotes: notification.ReleaseNotes, // CarUpdateId: notification.CarUpdateID, // } // grpcPayload := &kafka_grpc.GRPC_AttendantPayload{ // Data: &kafka_grpc.GRPC_AttendantPayload_UpdateManifest{ // UpdateManifest: updateManifest, // }, // } // return grpcPayload // } func milliToDate(timestamp int64) time.Time { seconds := timestamp / 1000 nanoseconds := (timestamp % 1000) * int64(time.Millisecond) return time.Unix(seconds, nanoseconds) } // ##################################################################################################### // ################################## End Attendant ######################################################## // ##################################################################################################### // ##################################################################################################### // ################################## Valet ######################################################## // ##################################################################################################### func ValetRouteTRexPayload(payload *kafka_grpc.GRPC_ValetPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "departure_schedule": message.Data = toBinaryArray(GRPCToDepartureSchedule(payload)) case "charge_settings": message.Data = toBinaryArray(GRPCToChargeSetting(payload)) case "charging_command": if payload.Data == nil { break } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_ChCMD) message.Data = toBinaryArray(data.ChCMD) } return message, nil } func ValetRouteHMIPayload(payload *kafka_grpc.GRPC_ValetPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "ble_key": data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_BLEKey) message.Data = toBinaryArray(data.BLEKey) case "profiles": break case "settings_update": message.Data = toBinaryArray(GRPCToHMISettingsUpdate(payload)) case "map_history": message.Data = toBinaryArray(GRPCToHMIMapHistory(payload)) case "user_pois": message.Data = toBinaryArray(GRPCToHMIPOIsMessage(payload)) case "consent": message.Data = toBinaryArray(GRPCToUserConsentFromHMI(payload)) case "profile_delete": message.Data = toBinaryArray(GRPCToJSONHMIDeleteProfile(payload)) } return message, nil } func ValetRouteMobilePayload(payload *kafka_grpc.GRPC_ValetPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "charge_settings_get", "departure_schedule_get": message.Data = toBinaryArray(GRPCToEmptyMessageFromMobile(payload)) case "remote_command": message.Data = toBinaryArray(GRPCToRemotCMD(payload)) case "car_locations", "map_history_get", "profiles", "store_inventory", "user_pois_get": break // no payload for these handlers case "digital_twin": message.Data = toBinaryArray(GRPCToDigitalTwinRequest(payload)) case "map_destination": message.Data = toBinaryArray(GRPCToMapDestinationRequest(payload)) case "map_route": message.Data = toBinaryArray(GRPCToMapRouteRequest(payload)) case "map_history_add": message.Data = toBinaryArray(GRPCToMapHistory(payload)) case "settings_update": message.Data = toBinaryArray(GRPCToMobileSettingsUpdate(payload)) case "charge_settings": message.Data = toBinaryArray(GRPCToMobileChargeSetting(payload)) case "store_purchase": message.Data = toBinaryArray(GRPCToStorePurchases(payload)) case "user_poi_create": message.Data = toBinaryArray(GRPCToPointOfInterest(payload)) case "user_poi_edit": message.Data = toBinaryArray(GRPCToMobilePOIEditMessage(payload)) case "user_poi_delete": message.Data = toBinaryArray(GRPCToMobilePOIDeleteMessage(payload)) case "departure_schedule": message.Data = toBinaryArray(GRPCToMobileDepartureSchedule(payload)) case "wake_car": message.Data = toBinaryArray(GRPCToWakeCar(payload)) case "manual_issue": message.Data = toBinaryArray(GRPCToAddIssueRequest(payload)) } return message, nil } func ValetRouteServicePayload(payload *kafka_grpc.GRPC_ValetPayload) (*ConsumerPayload, error) { message := &ConsumerPayload{ Handler: payload.Handler, } switch payload.Handler { case "remote_command": data := GRPCToRemotCMD(payload) if data == nil { break } message.Data, _ = json.Marshal(data) } return message, nil } func GRPCToRemotCMD(payload *kafka_grpc.GRPC_ValetPayload) *RemoteCommandRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_RemoteCmd: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_RemoteCmd) b := toBinaryArray(data.RemoteCmd) if len(b) > 0 { var cmd RemoteCommandRequest err := json.Unmarshal(b, &cmd) if err != nil { return nil } return &cmd } return nil } func GRPCToEmptyMessageFromMobile(payload *kafka_grpc.GRPC_ValetPayload) *EmptyMessageFromMobile { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_EmptyMsg: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_EmptyMsg) emtMsq := &EmptyMessageFromMobile{ VIN: data.EmptyMsg.Vin, } return emtMsq } func GRPCToDigitalTwinRequest(payload *kafka_grpc.GRPC_ValetPayload) *DigitalTwinRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_DigitalTwinReq: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_DigitalTwinReq) obj := &DigitalTwinRequest{ VIN: data.DigitalTwinReq.Vin, } return obj } func GRPCToMapDestinationRequest(payload *kafka_grpc.GRPC_ValetPayload) *MapDestinationRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_MapDestReq: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_MapDestReq) obj := &MapDestinationRequest{ VIN: data.MapDestReq.Vin, Name: data.MapDestReq.Name, } if data.MapDestReq.Address != nil { obj.Address = &TomTomAddress{} obj.Address.StreetName = data.MapDestReq.Address.StreetName obj.Address.StreetNumber = data.MapDestReq.Address.StreetNumber obj.Address.LocalName = data.MapDestReq.Address.LocalName obj.Address.PostalCode = data.MapDestReq.Address.PostalCode obj.Address.CountrySubdivisionName = data.MapDestReq.Address.CountrySubdivisionName obj.Address.CountryCodeIso3 = data.MapDestReq.Address.CountryCodeIso3 } if data.MapDestReq.Coordinates != nil { obj.Coordinates = MapCoordinates{ Latitude: data.MapDestReq.Coordinates.Latitude, Longitude: data.MapDestReq.Coordinates.Longitude, } } return obj } func GRPCToMapRouteRequest(payload *kafka_grpc.GRPC_ValetPayload) *MapRouteRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_MapRouteReq: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_MapRouteReq) obj := &MapRouteRequest{ VIN: data.MapRouteReq.Vin, } if len(data.MapRouteReq.Route) > 0 { var routes []MapCoordinates for _, r := range data.MapRouteReq.Route { routes = append(routes, MapCoordinates{ Latitude: r.Latitude, Longitude: r.Latitude, }) } obj.Route = routes } if len(data.MapRouteReq.Waypoints) > 0 { var points []MapWaypoint for _, p := range data.MapRouteReq.Waypoints { point := MapWaypoint{ Type: p.Type, Title: p.Title, } point.Latitude = p.Coordinates.Latitude point.Longitude = p.Coordinates.Longitude points = append(points, point) } obj.Waypoints = points } return obj } func GRPCToMapHistory(payload *kafka_grpc.GRPC_ValetPayload) *MapHistory { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_MapHistory: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_MapHistory) obj := &MapHistory{ Name: data.MapHistory.Name, Description: data.MapHistory.Description, } if data.MapHistory.Location != nil { obj.Location = &MapCoordinates{ Latitude: data.MapHistory.Location.Latitude, Longitude: data.MapHistory.Location.Longitude, } } return obj } func GRPCToMobileDepartureSchedule(payload *kafka_grpc.GRPC_ValetPayload) *MobileDepartureSchedule { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_MobileDepartureSchedule: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_MobileDepartureSchedule) obj := &MobileDepartureSchedule{ VIN: data.MobileDepartureSchedule.Vin, } if data.MobileDepartureSchedule.DepartureSchedule != nil { obj.DepartureSchedule = DepartureSchedule{ NextDayDeparture: data.MobileDepartureSchedule.DepartureSchedule.NextDayDeparture, } if len(data.MobileDepartureSchedule.DepartureSchedule.DepartureDays) > 0 { var days []DepartureDay for _, d := range data.MobileDepartureSchedule.DepartureSchedule.DepartureDays { days = append(days, DepartureDay{ DayOfWeek: d.DayOfWeek, Time: d.Time, }) } obj.DepartureSchedule.DepartureDays = days } } return obj } func GRPCToAddIssueRequest(payload *kafka_grpc.GRPC_ValetPayload) *AddIssueRequest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_AddIssueReq: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_AddIssueReq) obj := &AddIssueRequest{ Images: data.AddIssueReq.Images, } if data.AddIssueReq.Issue != nil { obj.VIN = data.AddIssueReq.Issue.Vin obj.Description = data.AddIssueReq.Issue.Description obj.DriverID = data.AddIssueReq.Issue.DriverId obj.ID = int(data.AddIssueReq.Issue.Id) obj.Title = data.AddIssueReq.Issue.Title obj.Timestamp = milliToDate(data.AddIssueReq.Issue.Timestamp) if len(data.AddIssueReq.Issue.Images) > 0 { var images []IssueImage for _, img := range data.AddIssueReq.Issue.Images { iimg := IssueImage{ ID: int(img.Id), Image: img.Image, IssueID: int(img.IssueId), } images = append(images, iimg) } obj.IssueImages = images } } return obj } func GRPCToWakeCar(payload *kafka_grpc.GRPC_ValetPayload) *EmptyMessageFromMobile { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_Wakecar: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_Wakecar) obj := &EmptyMessageFromMobile{ VIN: data.Wakecar.Vin, } return obj } func GRPCToMobilePOIEditMessage(payload *kafka_grpc.GRPC_ValetPayload) *MobilePOIEditMessage { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_PoiEdit: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_PoiEdit) obj := &MobilePOIEditMessage{ OldName: data.PoiEdit.OldName, } if data.PoiEdit.UserPoi != nil { pointOdInterest := &PointOfInterest{ Name: data.PoiEdit.UserPoi.Name, } if data.PoiEdit.UserPoi != nil { pointOdInterest.Location = POILocation{ Latitude: data.PoiEdit.UserPoi.Location.Latitude, Longitude: data.PoiEdit.UserPoi.Location.Longitude, } } } return obj } func GRPCToMobilePOIDeleteMessage(payload *kafka_grpc.GRPC_ValetPayload) *MobilePOIDeleteMessage { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_PoiDelete: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_PoiDelete) obj := &MobilePOIDeleteMessage{ Name: data.PoiDelete.Name, } return obj } func GRPCToPointOfInterest(payload *kafka_grpc.GRPC_ValetPayload) *PointOfInterest { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_PoiCreate: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_PoiCreate) obj := &PointOfInterest{ Name: data.PoiCreate.Name, } if data.PoiCreate.Location != nil { obj.Location = POILocation{ Latitude: data.PoiCreate.Location.Latitude, Longitude: data.PoiCreate.Location.Longitude, } } return obj } func GRPCToStorePurchases(payload *kafka_grpc.GRPC_ValetPayload) *StorePurchases { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_StorePurchases: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_StorePurchases) obj := &StorePurchases{ VIN: data.StorePurchases.Vin, } if len(data.StorePurchases.Purchases) > 0 { var purchases []StorePurchaseItem for _, p := range data.StorePurchases.Purchases { uuidObj, err := uuid.Parse(p.Id) if err != nil { continue } purchase := StorePurchaseItem{ ID: uuidObj, } purchases = append(purchases, purchase) } obj.Purchases = purchases } return obj } func GRPCToMobileSettingsUpdate(payload *kafka_grpc.GRPC_ValetPayload) *MobileSettingsUpdate { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_SettingsUpdate: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_SettingsUpdate) obj := &MobileSettingsUpdate{ VIN: data.SettingsUpdate.Vin, } if len(data.SettingsUpdate.Settings) > 0 { var settings []CarSetting for _, s := range data.SettingsUpdate.Settings { setting := CarSetting{ VIN: s.Vin, DriverID: s.DriverId, Name: s.Name, Value: s.Value, Type: s.Type, } if s.Created != nil { t := milliToDate(*s.Created) setting.CreatedAt = &t } if s.Updated != nil { t := milliToDate(*s.Updated) setting.UpdatedAt = &t } settings = append(settings, setting) } obj.Settings = settings } return obj } func GRPCToMobileChargeSetting(payload *kafka_grpc.GRPC_ValetPayload) *MobileChargeSetting { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_MobileChargeSetting: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_MobileChargeSetting) obj := &MobileChargeSetting{ VIN: data.MobileChargeSetting.Vin, } if data.MobileChargeSetting.ChargeSettings != nil { obj.ChargeSettings = ChargeSettings{ ChargeLimit: int(data.MobileChargeSetting.ChargeSettings.ChargeLimit), MaxCurrent: int(data.MobileChargeSetting.ChargeSettings.MaxCurrent), } if data.MobileChargeSetting.ChargeSettings.OffPeakCcharging != nil { obj.ChargeSettings.OffPeakCharging = &OffPeakCharging{ Start: milliToDate(data.MobileChargeSetting.ChargeSettings.OffPeakCcharging.Start), End: milliToDate(data.MobileChargeSetting.ChargeSettings.OffPeakCcharging.End), } } if data.MobileChargeSetting.ChargeSettings.MinCharge != nil { t := int(*data.MobileChargeSetting.ChargeSettings.MinCharge) obj.ChargeSettings.MinCharge = &t } } return obj } func GRPCToHMISettingsUpdate(payload *kafka_grpc.GRPC_ValetPayload) *HMISettingsUpdate { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_HmiSettingsUpdate: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_HmiSettingsUpdate) obj := &HMISettingsUpdate{ DriverID: data.HmiSettingsUpdate.DriverId, } if len(data.HmiSettingsUpdate.Settings) > 0 { var carSettings []CarSetting for _, s := range data.HmiSettingsUpdate.Settings { carSetting := CarSetting{ VIN: s.Vin, DriverID: s.DriverId, Name: s.Name, Type: s.Type, Value: s.Value, } if s.Created != nil { t := milliToDate(*s.Created) carSetting.CreatedAt = &t } if s.Updated != nil { t := milliToDate(*s.Updated) carSetting.UpdatedAt = &t } carSettings = append(carSettings, carSetting) } obj.Settings = carSettings } return obj } func GRPCToHMIMapHistory(payload *kafka_grpc.GRPC_ValetPayload) *HMIMapHistory { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_HmiMapHistory: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_HmiMapHistory) obj := &HMIMapHistory{ DriverID: data.HmiMapHistory.DriverId, } if len(data.HmiMapHistory.Searches) > 0 { var searches []MapHistory for _, s := range data.HmiMapHistory.Searches { search := MapHistory{ Name: s.Name, Description: s.Description, } if s.Location != nil { search.Location = &MapCoordinates{ Latitude: s.Location.Latitude, Longitude: s.Location.Longitude, } } searches = append(searches, search) } obj.Searches = searches } return obj } func GRPCToHMIPOIsMessage(payload *kafka_grpc.GRPC_ValetPayload) *HMIPOIsMessage { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_HmiPOIsMessage: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_HmiPOIsMessage) obj := &HMIPOIsMessage{ DriverID: data.HmiPOIsMessage.DriverId, } if len(data.HmiPOIsMessage.UserPOIs) > 0 { var pois []PointOfInterest for _, p := range data.HmiPOIsMessage.UserPOIs { poi := PointOfInterest{ Name: p.Name, } if p.Location != nil { poi.Location = POILocation{ Latitude: p.Location.Latitude, Longitude: p.Location.Longitude, } } pois = append(pois, poi) } obj.UserPOIs = pois } return obj } func GRPCToUserConsentFromHMI(payload *kafka_grpc.GRPC_ValetPayload) []*UserConsentFromHMI { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_UserConsentFromHMI: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_UserConsentFromHMI) if data.UserConsentFromHMI != nil && len(data.UserConsentFromHMI.UserConsent) > 0 { var userConsentFromHMI []*UserConsentFromHMI for _, d := range data.UserConsentFromHMI.UserConsent { obj := &UserConsentFromHMI{ Name: d.Name, Accept: d.Accept, DriverID: d.DriverId, } userConsentFromHMI = append(userConsentFromHMI, obj) } return userConsentFromHMI } return nil } func GRPCToJSONHMIDeleteProfile(payload *kafka_grpc.GRPC_ValetPayload) *JSONHMIDeleteProfile { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_HmiDeleteProfile: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_HmiDeleteProfile) obj := &JSONHMIDeleteProfile{ DriverID: data.HmiDeleteProfile.DriverId, } return obj } func GRPCToDepartureSchedule(payload *kafka_grpc.GRPC_ValetPayload) *DepartureSchedule { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_DepartureSchedule: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_DepartureSchedule) obj := &DepartureSchedule{ NextDayDeparture: data.DepartureSchedule.NextDayDeparture, } if len(data.DepartureSchedule.DepartureDays) > 0 { var days []DepartureDay for _, d := range data.DepartureSchedule.DepartureDays { days = append(days, DepartureDay{ DayOfWeek: d.DayOfWeek, Time: d.Time, }) } obj.DepartureDays = days } return obj } func GRPCToChargeSetting(payload *kafka_grpc.GRPC_ValetPayload) *ChargeSettings { if payload.Data == nil { return nil } switch payload.Data.(type) { case *kafka_grpc.GRPC_ValetPayload_ChargeSetting: break default: return nil } data := payload.Data.(*kafka_grpc.GRPC_ValetPayload_ChargeSetting) obj := &ChargeSettings{ ChargeLimit: int(data.ChargeSetting.ChargeLimit), MaxCurrent: int(data.ChargeSetting.MaxCurrent), } if data.ChargeSetting.OffPeakCcharging != nil { obj.OffPeakCharging = &OffPeakCharging{ Start: milliToDate(data.ChargeSetting.OffPeakCcharging.Start), End: milliToDate(data.ChargeSetting.OffPeakCcharging.End), } } if data.ChargeSetting.MinCharge != nil { t := int(*data.ChargeSetting.MinCharge) obj.MinCharge = &t } return obj } func toBinaryArray(data interface{}) []byte { if data == nil { return nil } bytes, _ := json.Marshal(data) if string(bytes) == "null" { return nil } return bytes } // it's mapping to contollers.DTCEntry type CommonDTCEntry struct { CreatedAt time.Time `bson:"created_at"` VIN string `bson:"vin"` ECU string `json:"ecu" bson:"ecu"` DTC uint64 `json:"dtc" bson:"dtc"` Status uint8 `json:"status" bson:"status"` Timestamp time.Time `json:"timestamp" bson:"timestamp"` Speed uint16 `json:"speed" bson:"speed"` Mileage uint32 `json:"mileage" bson:"mileage"` Voltage uint16 `json:"voltage" bson:"voltage"` SnapshotBase64 string `json:"snapshot,omitempty" bson:"snapshot,omitempty"` }