package hwversion import ( "fmt" "fiskerinc.com/modules/common" "fiskerinc.com/modules/db/queries" "fiskerinc.com/modules/logger" "fiskerinc.com/modules/utils/whereami" ) // Because of import loops, I moved this out to its own file and package func SetHWVersion(um *common.UpdateManifest, vin string, carsDB queries.CarsInterface) (err error) { // We want to get the set of the car's ecus and the HW version they are on // Then for each ecu we will check if the hardware version is compatible // Should provide this sort of action as an API route as well carECUMap, err := getCarECUsMap(um, vin, carsDB) if err != nil { return } if whereami.Service == whereami.AFTERSALES { p, ok := carECUMap["OBC"] if ok { p.ECU = "PDU" delete(carECUMap, "OBC") carECUMap["PDU"] = p } } failedECUs := make([]string, 0) // We have the list of ecu's and their list of hw version // we also have the list of car ecu's and its hw version // check that the versions match up for _, ume := range um.ECUs { // A patch over for trex's that haven't been updated if dontVersionCheckECU(ume.ECU) { ume.HWVersion = "placeholder" ume.HWVersions = []string{} continue } if len(ume.HWVersions) == 0 { failedECUs = append(failedECUs, fmt.Sprintf("no hw versions provided for %s", ume.ECU)) ume.HWVersion = "placeholder" ume.HWVersions = []string{} continue } // Get the relevant ecu from the car that is in the manifest carECU, ok := carECUMap[ume.ECU] if !ok { // FAIL failedECUs = append(failedECUs, fmt.Sprintf("car missing entry for ecu %s", ume.ECU)) ume.HWVersion = "placeholder" ume.HWVersions = []string{} continue } // Check if the car and the manifest have matching versions if doesManifestHaveHardwareVersion(carECU.HWVersion, ume.HWVersions) { ume.HWVersion = carECU.HWVersion ume.HWVersions = []string{} } else { // This is a fail, didn't find a match for the hw version failedECUs = append(failedECUs, fmt.Sprintf("no matching hw version for %s", carECU.ECU)) ume.HWVersion = "placeholder" ume.HWVersions = []string{} } } if len(failedECUs) != 0 { err = fmt.Errorf("manifest %s failed hw versioning for car %s: %v", um.Name, vin, failedECUs) logger.Warn().Err(err).Msg("") } err = nil return } func getCarECUsMap(um *common.UpdateManifest, vin string, carsDB queries.CarsInterface) (ecuMap map[string]common.CarECU, err error) { ecuNameList := um.GetECUs() // Just the ecu name filter := common.CarECUFilter{VIN: vin, ECUs: ecuNameList, Unique: true, HWVersionRequired: true} carECUs, err := carsDB.GetCarECUs(filter, nil) if err != nil { return } ecuMap = carECUsToMap(carECUs) return } // Using a map just simplifies the check for matching ecu's func carECUsToMap(ecus []common.CarECU) (ecuMap map[string]common.CarECU) { ecuMap = make(map[string]common.CarECU) for _, ecu := range ecus { ecuMap[ecu.ECU] = ecu } return } // If the ECU is one we don't want to check the version for because the car doesn't have it: TREX and ICC, then we return true and skip it func dontVersionCheckECU(ecuName string) (dontCheck bool) { // These names should match with project-ai/cloud/sp_manifest_generator/Sharepoint/Utils/ValidatorUtils.cs switch ecuName { case "TREX": return true case "TBOX": return true default: return false } } // Check that the manifest has the cars version for the ECU, if it does return it, otherwise return an empty string func doesManifestHaveHardwareVersion(carECUHWVersion string, manifestECUHWVersions []string) (hasVersion bool) { for _, hwVersion := range manifestECUHWVersions { if hwVersion == carECUHWVersion { // The version matches, so we set the manifests version correctly, and remove this ecu from our list of carECU's // Going to skip the removal for now, I don't think it is necessary return true } } return false }