Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
247
pkg/flashpackversion/flashpack_version_update.go
Normal file
247
pkg/flashpackversion/flashpack_version_update.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package flashpackversion
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/db/queries"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
// Any time we insert new CarECUs, we want to see if the flashpack number for the car has changed
|
||||
// If so, we save it on the car, send it to SAP, and update the Version Log.
|
||||
func InsertCarECUsAndUpdateFlashpackVersion(cars queries.CarsInterface, cvl queries.CarVersionsLogInterface, vin string, ecus []common.CarECU) error {
|
||||
// Convert the ecu names to cloud compatible ecus
|
||||
for _, e := range ecus {
|
||||
e.TransformECUName()
|
||||
}
|
||||
|
||||
// Insert the new CarECUs
|
||||
err := cars.InsertCarECUs(ecus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var previousFlashpackNumber, currentFlashpackNumber string
|
||||
|
||||
// Find the previous flashpack version of the car
|
||||
car, err := cars.SelectByVIN(vin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
previousFlashpackNumber = car.Flashpack
|
||||
|
||||
// Find the current flashpack number of the car
|
||||
currentFlashpackNumber, err = FindCurrentFlashpackVersionForCar(cars, *car)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the flashpack has changed, update the car and SAP
|
||||
return updateFlashpackNumber(cars, cvl, vin, currentFlashpackNumber, previousFlashpackNumber)
|
||||
}
|
||||
|
||||
// Given the latest ECUs for a car, find out what the flashpack number for the car is
|
||||
func FindCurrentFlashpackVersionForCar(cars queries.CarsInterface, car common.Car) (currentFlashpackNumber string, err error) {
|
||||
currentFlashpackNumber = ""
|
||||
|
||||
// Get a map of key-value pairs, latest updated ECUs for the car, ECU names as keys and ECU Supplier SW Versions as values
|
||||
latestCarECUsToVersionsMap, err := getLatestCarECUsMap(cars, car.VIN)
|
||||
if err != nil {
|
||||
return currentFlashpackNumber, err
|
||||
}
|
||||
|
||||
// Get a map of all flashpack version mappings, and an array of the flashpack numbers sorted in descending numerical order
|
||||
flashpackMappings, flashpackNumbers, err := getAllFlashpackMappingsByModelTrimMap(cars, car.Model, car.Trim)
|
||||
if err != nil {
|
||||
return currentFlashpackNumber, err
|
||||
}
|
||||
|
||||
// Here is the logic to calculate the current flashpack number for the car
|
||||
// More than one version for an ECU may map to the same flashpack number
|
||||
// A car may be several versions ahead on one ECU, and several versions behind on another ECU
|
||||
// Hence the following ugly code
|
||||
|
||||
// For each flashpack number in descending order
|
||||
var ecusUpdated []string
|
||||
for _, flashpackNumber := range flashpackNumbers {
|
||||
|
||||
var flashpackNumberComplete = true
|
||||
|
||||
outer: // For each ECU version mapping for the flashpack number
|
||||
for _, flashpackMapping := range flashpackMappings[flashpackNumber] {
|
||||
var ecuUpdated = false
|
||||
|
||||
inner: // Determine whether this ECU is updated on the car to this flashpack number or a higher one
|
||||
for _, e := range ecusUpdated {
|
||||
if e == flashpackMapping.ECU {
|
||||
ecuUpdated = true
|
||||
break inner
|
||||
}
|
||||
}
|
||||
|
||||
if !ecuUpdated {
|
||||
ecuVersion, ok := latestCarECUsToVersionsMap[flashpackMapping.ECU]
|
||||
|
||||
// If the ECU has not been updated at all, or it is not at this version, then the flashpack number is incomplete and the car has not achieved it
|
||||
if !ok || ecuVersion != flashpackMapping.SupplierSWVersion {
|
||||
flashpackNumberComplete = false
|
||||
break outer
|
||||
} else {
|
||||
// We have proved that this ECU is updated on the car to this flashpack number
|
||||
ecusUpdated = append(ecusUpdated, flashpackMapping.ECU)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if flashpackNumberComplete && flashpackNumber > currentFlashpackNumber {
|
||||
currentFlashpackNumber = flashpackNumber
|
||||
}
|
||||
}
|
||||
|
||||
return currentFlashpackNumber, err
|
||||
}
|
||||
|
||||
func FindCarECUsToUpdateForNextFlashpackNumber(cars queries.CarsInterface, car common.Car, nextFlashpackNumber string) ([]common.CarECUVersion, error) {
|
||||
ecusToUpdateForNextFlashpackNumber := []common.CarECUVersion{}
|
||||
|
||||
// Get a map of key-value pairs, latest updated ECUs for the car, ECU names as keys and ECU Supplier SW Versions as values
|
||||
latestCarECUsToVersionsMap, err := getLatestCarECUsMap(cars, car.VIN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get a map of all flashpack version mappings, and an array of the flashpack numbers sorted in descending numerical order
|
||||
allFlashpackMappings, allFlashpackNumbers, err := getAllFlashpackMappingsByModelTrimMap(cars, car.Model, car.Trim)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the mappings specifically for the next flashpack version
|
||||
nextFlashpackVersionMappings := allFlashpackMappings[nextFlashpackNumber]
|
||||
|
||||
// Here is the logic to find which ECUs on the car need to be updated in order to achieve nextFlashpackNumber
|
||||
// A car may be several versions ahead on one ECU, and several versions behind on another ECU
|
||||
// Hence the following ugly code
|
||||
|
||||
// For each mapping for the next flashpack version
|
||||
for _, nextFlashpackVersionMapping := range nextFlashpackVersionMappings {
|
||||
ecuVersion, ok := latestCarECUsToVersionsMap[nextFlashpackVersionMapping.ECU]
|
||||
|
||||
if !ok {
|
||||
// If the ECU has not been updated at all on this car, we know it needs to be updated to achieve the next flashpack version
|
||||
ecusToUpdateForNextFlashpackNumber = append(ecusToUpdateForNextFlashpackNumber, common.CarECUVersion{
|
||||
CarECUName: nextFlashpackVersionMapping.ECU,
|
||||
CarECUVersion: nextFlashpackVersionMapping.SupplierSWVersion,
|
||||
})
|
||||
} else {
|
||||
// If the ECU has been updated, we need to determine whether its version applies to this flashpack number or a higher one
|
||||
// That means we need to check all the mappings for the next flashpack number and all higher ones as well
|
||||
|
||||
found := false
|
||||
|
||||
outer: // For each flashpack number in descending order
|
||||
for _, flashpackNumber := range allFlashpackNumbers {
|
||||
|
||||
inner: // For each ECU mapping for this flashpack number
|
||||
for _, carECU := range allFlashpackMappings[flashpackNumber] {
|
||||
if ecuVersion == carECU.SupplierSWVersion {
|
||||
found = true
|
||||
break inner
|
||||
}
|
||||
}
|
||||
|
||||
// Don't check flashpack numbers lower than the next flashpack number
|
||||
if flashpackNumber == nextFlashpackNumber {
|
||||
break outer
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
// We have proved that the ECU has not been updated for the next flashpack number
|
||||
ecusToUpdateForNextFlashpackNumber = append(ecusToUpdateForNextFlashpackNumber, common.CarECUVersion{
|
||||
CarECUName: nextFlashpackVersionMapping.ECU,
|
||||
CarECUVersion: nextFlashpackVersionMapping.SupplierSWVersion,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ecusToUpdateForNextFlashpackNumber, err
|
||||
}
|
||||
|
||||
// Save the flashpack number in the database, display it in the version log, and send it to SAP
|
||||
func updateFlashpackNumber(cars queries.CarsInterface, cvl queries.CarVersionsLogInterface, vin, currentFlashpack string, previousFlashpack string) error {
|
||||
if currentFlashpack != previousFlashpack {
|
||||
_, err := cars.UpdateCarFlashpackVersion(vin, currentFlashpack)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
_, err = cvl.LogVersionChange(&common.CarVersionLogs{
|
||||
VIN: vin,
|
||||
VersionSource: common.FlashpackVersionSource,
|
||||
Version: currentFlashpack,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLatestCarECUsMap(cars queries.CarsInterface, vin string) (map[string]string, error) {
|
||||
allLatestCarECUs, err := cars.GetCarECUs(common.CarECUFilter{VIN: vin, Unique: true}, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Put into a map by ECU name
|
||||
var latestCarECUsToVersionsMap = make(map[string]string)
|
||||
for _, e := range allLatestCarECUs {
|
||||
latestCarECUsToVersionsMap[e.ECU] = e.SupplierSWVersion
|
||||
}
|
||||
|
||||
// Sometimes the TBOX version is applied to MCU, or the PDU version is applied to OBC, etc.
|
||||
for ecuName, ecuReplacementName := range common.FlashpackCalculationECUReplacement {
|
||||
_, hasECUName := latestCarECUsToVersionsMap[ecuName]
|
||||
_, hasECUReplacementName := latestCarECUsToVersionsMap[ecuReplacementName]
|
||||
if hasECUName && !hasECUReplacementName {
|
||||
latestCarECUsToVersionsMap[ecuReplacementName] = latestCarECUsToVersionsMap[ecuName]
|
||||
}
|
||||
}
|
||||
|
||||
return latestCarECUsToVersionsMap, nil
|
||||
}
|
||||
|
||||
func getAllFlashpackMappingsByModelTrimMap(cars queries.CarsInterface, model string, trim string) (map[string][]common.CarECU, []string, error) {
|
||||
allFlashpackMappingsByModelTrim, err := cars.GetCarFlashpackVersionMappingsByModelTrim(model, trim, &queries.PageQueryOptions{Order: "flashpack DESC"})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Map flashpack numbers to an array of ECU names and versions
|
||||
var flashpackMappings = make(map[string][]common.CarECU)
|
||||
for _, f := range allFlashpackMappingsByModelTrim {
|
||||
flashpackMappings[f.Flashpack] =
|
||||
append(flashpackMappings[f.Flashpack],
|
||||
common.CarECU{
|
||||
ECU: f.CarECUName,
|
||||
SupplierSWVersion: f.CarECUVersion,
|
||||
})
|
||||
}
|
||||
|
||||
// Sort the flashpack numbers in descending order
|
||||
var flashpackNumbers = maps.Keys(flashpackMappings)
|
||||
sort.Slice(flashpackNumbers, func(i, j int) bool {
|
||||
iFp, _ := strconv.ParseFloat(flashpackNumbers[i], 64) // guaranteed numeric
|
||||
jFp, _ := strconv.ParseFloat(flashpackNumbers[j], 64) // guaranteed numeric
|
||||
|
||||
return iFp > jFp
|
||||
})
|
||||
|
||||
return flashpackMappings, flashpackNumbers, nil
|
||||
}
|
||||
436
pkg/flashpackversion/flashpack_version_update_test.go
Normal file
436
pkg/flashpackversion/flashpack_version_update_test.go
Normal file
@@ -0,0 +1,436 @@
|
||||
package flashpackversion_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/db/queries/mocks"
|
||||
fv "fiskerinc.com/modules/flashpackversion"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFindCurrentFlashpackVersionForCar(t *testing.T) {
|
||||
mockCars := setupMockCars()
|
||||
|
||||
car := common.Car{
|
||||
VIN: "FISKER123",
|
||||
Model: "Ocean",
|
||||
Trim: "Base",
|
||||
Year: 2023,
|
||||
}
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion2",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersionA",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "BCM",
|
||||
SupplierSWVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "OBC",
|
||||
SupplierSWVersion: "PDUVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "MCU",
|
||||
SupplierSWVersion: "TBOXVersion",
|
||||
},
|
||||
}
|
||||
|
||||
flashpack, err := fv.FindCurrentFlashpackVersionForCar(&mockCars, car)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "46.14", flashpack)
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "BCM",
|
||||
SupplierSWVersion: "BCMVersion",
|
||||
},
|
||||
}
|
||||
|
||||
flashpack, err = fv.FindCurrentFlashpackVersionForCar(&mockCars, car)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "", flashpack)
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion1",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "BCM",
|
||||
SupplierSWVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
}
|
||||
|
||||
flashpack, err = fv.FindCurrentFlashpackVersionForCar(&mockCars, car)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "41.14", flashpack)
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion1",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersion0",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "BCM",
|
||||
SupplierSWVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
}
|
||||
|
||||
flashpack, err = fv.FindCurrentFlashpackVersionForCar(&mockCars, car)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "39.14", flashpack)
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
}
|
||||
|
||||
flashpack, err = fv.FindCurrentFlashpackVersionForCar(&mockCars, car)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "37.14", flashpack)
|
||||
}
|
||||
|
||||
func TestFindCarECUsToUpdateForNextFlashpackNumber(t *testing.T) {
|
||||
mockCars := setupMockCars()
|
||||
|
||||
car := common.Car{
|
||||
VIN: "FISKER123",
|
||||
Model: "Ocean",
|
||||
Trim: "Base",
|
||||
Year: 2023,
|
||||
}
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion0",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersion0",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
}
|
||||
|
||||
ecus, err := fv.FindCarECUsToUpdateForNextFlashpackNumber(&mockCars, car, "41.14")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []common.CarECUVersion{
|
||||
{
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion",
|
||||
},
|
||||
{
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersion",
|
||||
},
|
||||
{
|
||||
CarECUName: "BCM",
|
||||
CarECUVersion: "BCMVersion",
|
||||
},
|
||||
}, ecus)
|
||||
|
||||
mockCars.SelectCarECUs = []common.CarECU{
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ADAS",
|
||||
SupplierSWVersion: "ADASVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "ACUN",
|
||||
SupplierSWVersion: "ACUNVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "PDI",
|
||||
SupplierSWVersion: "PDIVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "BCM",
|
||||
SupplierSWVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
VIN: "FISKER123",
|
||||
ECU: "OBC",
|
||||
SupplierSWVersion: "PDUVersion",
|
||||
},
|
||||
}
|
||||
|
||||
ecus, err = fv.FindCarECUsToUpdateForNextFlashpackNumber(&mockCars, car, "44.14")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []common.CarECUVersion{
|
||||
{
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion1",
|
||||
},
|
||||
{
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionA",
|
||||
},
|
||||
{
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionB",
|
||||
},
|
||||
}, ecus)
|
||||
}
|
||||
|
||||
func setupMockCars() mocks.MockCars {
|
||||
return mocks.MockCars{
|
||||
SelectResponse: &common.Car{VIN: "FISKER123", ICCID: "1111111111111111111F"},
|
||||
SelectCarSettings: []common.CarSetting{},
|
||||
SelectCarFlashpackVersions: []common.CarFlashpackVersion{
|
||||
|
||||
// 46.14
|
||||
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion2",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionA",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionB",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "BCM",
|
||||
CarECUVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "PDI",
|
||||
CarECUVersion: "PDIVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "PDU",
|
||||
CarECUVersion: "PDUVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "46.14",
|
||||
CarECUName: "TBOX",
|
||||
CarECUVersion: "TBOXVersion",
|
||||
},
|
||||
|
||||
// 44.14
|
||||
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion1",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionA",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersionB",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "BCM",
|
||||
CarECUVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "PDI",
|
||||
CarECUVersion: "PDIVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "44.14",
|
||||
CarECUName: "PDU",
|
||||
CarECUVersion: "PDUVersion",
|
||||
},
|
||||
|
||||
// 41.14
|
||||
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "41.14",
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "41.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "41.14",
|
||||
CarECUName: "BCM",
|
||||
CarECUVersion: "BCMVersion",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "41.14",
|
||||
CarECUName: "PDI",
|
||||
CarECUVersion: "PDIVersion",
|
||||
},
|
||||
|
||||
// 39.14
|
||||
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "39.14",
|
||||
CarECUName: "ADAS",
|
||||
CarECUVersion: "ADASVersion0",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "39.14",
|
||||
CarECUName: "ACUN",
|
||||
CarECUVersion: "ACUNVersion0",
|
||||
},
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "39.14",
|
||||
CarECUName: "PDI",
|
||||
CarECUVersion: "PDIVersion",
|
||||
},
|
||||
|
||||
// 37.14
|
||||
|
||||
{
|
||||
CarModel: "Ocean",
|
||||
CarTrim: "Base",
|
||||
CarYear: 2023,
|
||||
Flashpack: "37.14",
|
||||
CarECUName: "PDI",
|
||||
CarECUVersion: "PDIVersion",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user