Added schema in import of car catalog
MODIFY
src/assets/cars/car-catalogs-definition.json
src/assets/cars/car-catalogs-definition.json
"vehicleMake": "GOUPIL",
"vehicleModel": "G5 benne",
"vehicleModelVersion": "",
- "availabilityStatus": null,
- "availabilityDateFrom": null,
- "availabilityDateTo": null,
- "priceFromDE": 0,
- "priceFromDEEstimate": null,
- "priceFromNL": 0,
- "priceFromNLEstimate": null,
- "priceFromUK": 0,
- "priceGrantPICGUK": 0,
- "priceFromUKEstimate": null,
- "drivetrainType": null,
- "drivetrainFuel": null,
- "drivetrainPropulsion": null,
- "drivetrainPower": 0,
"drivetrainPowerHP": 21,
"drivetrainTorque": 37,
- "performanceAcceleration": 0,
"performanceTopspeed": 50,
- "rangeWLTP": 0,
- "rangeWLTPEstimate": null,
- "rangeNEDC": 0,
- "rangeNEDCEstimate": null,
"rangeReal": 40,
- "rangeRealMode": null,
- "rangeRealWHwy": null,
- "rangeRealWCmb": null,
- "rangeRealWCty": null,
- "rangeRealBHwy": null,
- "rangeRealBCmb": null,
- "rangeRealBCty": null,
- "efficiencyWLTP": 0,
- "efficiencyWLTPFuelEq": 0,
- "efficiencyWLTPV": 0,
- "efficiencyWLTPFuelEqV": 0,
- "efficiencyWLTPCO2": 0,
- "efficiencyNEDC": 0,
- "efficiencyNEDCFuelEq": 0,
- "efficiencyNEDCV": 0,
- "efficiencyNEDCFuelEqV": 0,
- "efficiencyNEDCCO2": 0,
- "efficiencyReal": 0,
- "efficiencyRealFuelEqV": 0,
- "efficiencyRealCO2": 0,
- "efficiencyRealWHwy": 0,
- "efficiencyRealWCmb": 0,
- "efficiencyRealWCty": 0,
- "efficiencyRealBHwy": 0,
- "efficiencyRealBCmb": 0,
- "efficiencyRealBCty": 0,
- "chargePlug": null,
- "chargePlugEstimate": null,
- "chargePlugLocation": null,
"chargeStandardPower": 13,
"chargeStandardPhase": 1,
"chargeStandardPhaseAmp": 16,
"chargeStandardChargeTime": 0,
"chargeStandardChargeSpeed": 0,
- "chargeStandardEstimate": null,
"chargeStandardTables": [
{
"type": "230V16A1X",
"chargeSpeed": 7
}
],
- "chargeAlternativePower": 0,
- "chargeAlternativePhase": 0,
- "chargeAlternativePhaseAmp": 0,
- "chargeAlternativeChargeTime": 0,
- "chargeAlternativeChargeSpeed": 0,
"chargeAlternativeTables": [],
- "chargeOptionPower": 0,
- "chargeOptionPhase": 0,
- "chargeOptionPhaseAmp": 0,
- "chargeOptionChargeTime": 0,
- "chargeOptionChargeSpeed": 0,
"chargeOptionTables": [],
- "fastChargePlug": null,
- "fastChargePlugEstimate": null,
- "fastChargePlugLocation": null,
- "fastChargePowerMax": 0,
- "fastChargePowerAvg": 0,
- "fastChargeTime": 0,
- "fastChargeSpeed": 0,
- "fastChargeOptional": null,
- "fastChargeEstimate": null,
- "batteryCapacityUseable": 0,
"batteryCapacityFull": 8.6,
- "batteryCapacityEstimate": null,
- "dimsLength": 0,
- "dimsWidth": 0,
- "dimsHeight": 0,
- "dimsWheelbase": null,
- "dimsWeight": 0,
- "dimsBootspace": 0,
- "dimsBootspaceMax": 0,
- "dimsTowWeightUnbraked": 0,
- "dimsTowWeightBraked": 0,
- "dimsRoofLoadMax": 0,
- "miscBody": null,
- "miscSegment": null,
- "miscSeats": 0,
- "miscRoofrails": null,
- "miscIsofix": null,
- "miscIsofixSeats": null,
- "miscTurningCircle": null,
- "euroNCAPRating": 0,
- "euroNCAPYear": null,
- "euroNCAPAdult": 0,
- "euroNCAPChild": 0,
- "euroNCAPVRU": 0,
- "euroNCAPSA": 0,
- "relatedVehicleIDSuccessor": 0,
- "eVDBDetailURL": null,
- "videos": null,
- "hash": null,
"imageURLs": [
"100000-goupil-g5-benne-1.jpg",
"100000-goupil-g5-benne-2.jpg"
"vehicleMake": "Renault",
"vehicleModel": "Twizy",
"vehicleModelVersion": "Life",
- "availabilityStatus": null,
- "availabilityDateFrom": null,
- "availabilityDateTo": null,
- "priceFromDE": 0,
- "priceFromDEEstimate": null,
- "priceFromNL": 0,
- "priceFromNLEstimate": null,
- "priceFromUK": 0,
- "priceGrantPICGUK": 0,
- "priceFromUKEstimate": null,
- "drivetrainType": null,
- "drivetrainFuel": null,
- "drivetrainPropulsion": null,
- "drivetrainPower": 0,
"drivetrainPowerHP": 17,
"drivetrainTorque": 57,
- "performanceAcceleration": 0,
"performanceTopspeed": 80,
- "rangeWLTP": 0,
- "rangeWLTPEstimate": null,
- "rangeNEDC": 0,
- "rangeNEDCEstimate": null,
"rangeReal": 80,
- "rangeRealMode": null,
- "rangeRealWHwy": null,
- "rangeRealWCmb": null,
- "rangeRealWCty": null,
- "rangeRealBHwy": null,
- "rangeRealBCmb": null,
- "rangeRealBCty": null,
- "efficiencyWLTP": 0,
- "efficiencyWLTPFuelEq": 0,
- "efficiencyWLTPV": 0,
- "efficiencyWLTPFuelEqV": 0,
- "efficiencyWLTPCO2": 0,
- "efficiencyNEDC": 0,
- "efficiencyNEDCFuelEq": 0,
- "efficiencyNEDCV": 0,
- "efficiencyNEDCFuelEqV": 0,
- "efficiencyNEDCCO2": 0,
- "efficiencyReal": 0,
- "efficiencyRealFuelEqV": 0,
- "efficiencyRealCO2": 0,
- "efficiencyRealWHwy": 0,
- "efficiencyRealWCmb": 0,
- "efficiencyRealWCty": 0,
- "efficiencyRealBHwy": 0,
- "efficiencyRealBCmb": 0,
- "efficiencyRealBCty": 0,
- "chargePlug": null,
- "chargePlugEstimate": null,
- "chargePlugLocation": null,
"chargeStandardPower": 13,
"chargeStandardPhase": 1,
"chargeStandardPhaseAmp": 16,
- "chargeStandardChargeTime": 0,
- "chargeStandardChargeSpeed": 0,
- "chargeStandardEstimate": null,
"chargeStandardTables": [
{
"type": "230V16A1X",
"chargeSpeed": 7
}
],
- "chargeAlternativePower": 0,
- "chargeAlternativePhase": 0,
- "chargeAlternativePhaseAmp": 0,
- "chargeAlternativeChargeTime": 0,
- "chargeAlternativeChargeSpeed": 0,
"chargeAlternativeTables": [],
- "chargeOptionPower": 0,
- "chargeOptionPhase": 0,
- "chargeOptionPhaseAmp": 0,
- "chargeOptionChargeTime": 0,
- "chargeOptionChargeSpeed": 0,
"chargeOptionTables": [],
- "fastChargePlug": null,
- "fastChargePlugEstimate": null,
- "fastChargePlugLocation": null,
- "fastChargePowerMax": 0,
- "fastChargePowerAvg": 0,
- "fastChargeTime": 0,
- "fastChargeSpeed": 0,
- "fastChargeOptional": null,
- "fastChargeEstimate": null,
- "batteryCapacityUseable": 0,
"batteryCapacityFull": 6.1,
- "batteryCapacityEstimate": null,
- "dimsLength": 0,
- "dimsWidth": 0,
- "dimsHeight": 0,
- "dimsWheelbase": null,
- "dimsWeight": 0,
- "dimsBootspace": 0,
- "dimsBootspaceMax": 0,
- "dimsTowWeightUnbraked": 0,
- "dimsTowWeightBraked": 0,
- "dimsRoofLoadMax": 0,
- "miscBody": null,
- "miscSegment": null,
- "miscSeats": 0,
- "miscRoofrails": null,
- "miscIsofix": null,
- "miscIsofixSeats": null,
- "miscTurningCircle": null,
- "euroNCAPRating": 0,
- "euroNCAPYear": null,
- "euroNCAPAdult": 0,
- "euroNCAPChild": 0,
- "euroNCAPVRU": 0,
- "euroNCAPSA": 0,
- "relatedVehicleIDSuccessor": 0,
- "eVDBDetailURL": null,
- "videos": null,
"imageURLs": [
"100001-renault-twizy-1.jpg",
"100001-renault-twizy-2.jpg",
"vehicleMake": "TATA Motors",
"vehicleModel": "Nexon",
"vehicleModelVersion": "EV",
- "availabilityStatus": null,
- "availabilityDateFrom": null,
- "availabilityDateTo": null,
- "priceFromDE": 0,
- "priceFromDEEstimate": null,
- "priceFromNL": 0,
- "priceFromNLEstimate": null,
- "priceFromUK": 0,
- "priceGrantPICGUK": 0,
- "priceFromUKEstimate": null,
- "drivetrainType": null,
- "drivetrainFuel": null,
- "drivetrainPropulsion": null,
- "drivetrainPower": 0,
"drivetrainPowerHP": 21,
"drivetrainTorque": 37,
- "performanceAcceleration": 0,
"performanceTopspeed": 50,
- "rangeWLTP": 0,
- "rangeWLTPEstimate": null,
- "rangeNEDC": 0,
- "rangeNEDCEstimate": null,
"rangeReal": 40,
- "rangeRealMode": null,
- "rangeRealWHwy": null,
- "rangeRealWCmb": null,
- "rangeRealWCty": null,
- "rangeRealBHwy": null,
- "rangeRealBCmb": null,
- "rangeRealBCty": null,
- "efficiencyWLTP": 0,
- "efficiencyWLTPFuelEq": 0,
- "efficiencyWLTPV": 0,
- "efficiencyWLTPFuelEqV": 0,
- "efficiencyWLTPCO2": 0,
- "efficiencyNEDC": 0,
- "efficiencyNEDCFuelEq": 0,
- "efficiencyNEDCV": 0,
- "efficiencyNEDCFuelEqV": 0,
- "efficiencyNEDCCO2": 0,
- "efficiencyReal": 0,
- "efficiencyRealFuelEqV": 0,
- "efficiencyRealCO2": 0,
- "efficiencyRealWHwy": 0,
- "efficiencyRealWCmb": 0,
- "efficiencyRealWCty": 0,
- "efficiencyRealBHwy": 0,
- "efficiencyRealBCmb": 0,
- "efficiencyRealBCty": 0,
- "chargePlug": null,
- "chargePlugEstimate": null,
- "chargePlugLocation": null,
"chargeStandardPower": 13,
"chargeStandardPhase": 1,
"chargeStandardPhaseAmp": 16,
- "chargeStandardChargeTime": 0,
- "chargeStandardChargeSpeed": 0,
- "chargeStandardEstimate": null,
"chargeStandardTables": [
{
"type": "230V16A1X",
"chargeSpeed": 7
}
],
- "chargeAlternativePower": 0,
- "chargeAlternativePhase": 0,
- "chargeAlternativePhaseAmp": 0,
- "chargeAlternativeChargeTime": 0,
- "chargeAlternativeChargeSpeed": 0,
"chargeAlternativeTables": [],
- "chargeOptionPower": 0,
- "chargeOptionPhase": 0,
- "chargeOptionPhaseAmp": 0,
- "chargeOptionChargeTime": 0,
- "chargeOptionChargeSpeed": 0,
"chargeOptionTables": [],
- "fastChargePlug": null,
- "fastChargePlugEstimate": null,
- "fastChargePlugLocation": null,
- "fastChargePowerMax": 0,
- "fastChargePowerAvg": 0,
- "fastChargeTime": 0,
- "fastChargeSpeed": 0,
- "fastChargeOptional": null,
- "fastChargeEstimate": null,
- "batteryCapacityUseable": 0,
"batteryCapacityFull": 8.6,
- "batteryCapacityEstimate": null,
- "dimsLength": 0,
- "dimsWidth": 0,
- "dimsHeight": 0,
- "dimsWheelbase": null,
- "dimsWeight": 0,
- "dimsBootspace": 0,
- "dimsBootspaceMax": 0,
- "dimsTowWeightUnbraked": 0,
- "dimsTowWeightBraked": 0,
- "dimsRoofLoadMax": 0,
- "miscBody": null,
- "miscSegment": null,
- "miscSeats": 0,
- "miscRoofrails": null,
- "miscIsofix": null,
- "miscIsofixSeats": null,
- "miscTurningCircle": null,
- "euroNCAPRating": 0,
- "euroNCAPYear": null,
- "euroNCAPAdult": 0,
- "euroNCAPChild": 0,
- "euroNCAPVRU": 0,
- "euroNCAPSA": 0,
- "relatedVehicleIDSuccessor": 0,
- "eVDBDetailURL": null,
- "videos": null,
"imageURLs": [
"100002-tata-nexon-1.jpg",
"100002-tata-nexon-2.jpg"

ADD
src/assets/schemas/car/car-catalog.json
+{
+ "$id": "car-catalog",
+ "title": "Validate the Car Catalog",
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "number"
+ },
+ "vehicleMake": {
+ "type": "string"
+ },
+ "vehicleModel": {
+ "type": "string"
+ },
+ "vehicleModelVersion": {
+ "type": "string"
+ },
+ "availabilityStatus": {
+ "type": "string"
+ },
+ "availabilityDateFrom": {
+ "type": ["string", "object"],
+ "format": "date"
+ },
+ "availabilityDateTo": {
+ "type": ["string", "object"],
+ "format": "date"
+ },
+ "priceFromDE": {
+ "type": "number"
+ },
+ "priceFromDEEstimate": {
+ "type": "boolean"
+ },
+ "priceFromNL": {
+ "type": "number"
+ },
+ "priceFromNLEstimate": {
+ "type": "boolean"
+ },
+ "priceFromUK": {
+ "type": "number"
+ },
+ "priceGrantPICGUK": {
+ "type": "number"
+ },
+ "priceFromUKEstimate": {
+ "type": "boolean"
+ },
+ "drivetrainType": {
+ "type": "string"
+ },
+ "drivetrainFuel": {
+ "type": "string"
+ },
+ "drivetrainPropulsion": {
+ "type": "string"
+ },
+ "drivetrainPower": {
+ "type": "number"
+ },
+ "drivetrainPowerHP": {
+ "type": "number"
+ },
+ "drivetrainTorque": {
+ "type": "number"
+ },
+ "performanceAcceleration": {
+ "type": "number"
+ },
+ "performanceTopspeed": {
+ "type": "number"
+ },
+ "rangeWLTP": {
+ "type": "number"
+ },
+ "rangeWLTPEstimate": {
+ "type": "boolean"
+ },
+ "rangeNEDC": {
+ "type": "number"
+ },
+ "rangeNEDCEstimate": {
+ "type": "boolean"
+ },
+ "rangeReal": {
+ "type": "number"
+ },
+ "rangeRealMode": {
+ "type": "string"
+ },
+ "rangeRealWHwy": {
+ "type": "number"
+ },
+ "rangeRealWCmb": {
+ "type": "number"
+ },
+ "rangeRealWCty": {
+ "type": "number"
+ },
+ "rangeRealBHwy": {
+ "type": "number"
+ },
+ "rangeRealBCmb": {
+ "type": "number"
+ },
+ "rangeRealBCty": {
+ "type": "number"
+ },
+ "efficiencyWLTP": {
+ "type": "number"
+ },
+ "efficiencyWLTPFuelEq": {
+ "type": "number"
+ },
+ "efficiencyWLTPV": {
+ "type": "number"
+ },
+ "efficiencyWLTPFuelEqV": {
+ "type": "number"
+ },
+ "efficiencyWLTPCO2": {
+ "type": "number"
+ },
+ "efficiencyNEDC": {
+ "type": "number"
+ },
+ "efficiencyNEDCFuelEq": {
+ "type": "number"
+ },
+ "efficiencyNEDCV": {
+ "type": "number"
+ },
+ "efficiencyNEDCFuelEqV": {
+ "type": "number"
+ },
+ "efficiencyNEDCCO2": {
+ "type": "number"
+ },
+ "efficiencyReal": {
+ "type": "number"
+ },
+ "efficiencyRealFuelEqV": {
+ "type": "number"
+ },
+ "efficiencyRealCO2": {
+ "type": "number"
+ },
+ "efficiencyRealWHwy": {
+ "type": "number"
+ },
+ "efficiencyRealWCmb": {
+ "type": "number"
+ },
+ "efficiencyRealWCty": {
+ "type": "number"
+ },
+ "efficiencyRealBHwy": {
+ "type": "number"
+ },
+ "efficiencyRealBCmb": {
+ "type": "number"
+ },
+ "efficiencyRealBCty": {
+ "type": "number"
+ },
+ "chargePlug": {
+ "type": "string"
+ },
+ "chargePlugEstimate": {
+ "type": "boolean"
+ },
+ "chargePlugLocation": {
+ "type": "string"
+ },
+ "chargeStandardPower": {
+ "type": "number"
+ },
+ "chargeStandardPhase": {
+ "type": "number"
+ },
+ "chargeStandardPhaseAmp": {
+ "type": "number"
+ },
+ "chargeStandardChargeTime": {
+ "type": "number"
+ },
+ "chargeStandardChargeSpeed": {
+ "type": "number"
+ },
+ "chargeStandardEstimate": {
+ "type": "boolean"
+ },
+ "chargeStandardTables": {
+ "$ref": "#/definitions/chargeTables"
+ },
+ "chargeAlternativePower": {
+ "type": "number"
+ },
+ "chargeAlternativePhase": {
+ "type": "number"
+ },
+ "chargeAlternativePhaseAmp": {
+ "type": "number"
+ },
+ "chargeAlternativeChargeTime": {
+ "type": "number"
+ },
+ "chargeAlternativeChargeSpeed": {
+ "type": "number"
+ },
+ "chargeAlternativeTables": {
+ "$ref": "#/definitions/chargeTables"
+ },
+ "chargeOptionPower": {
+ "type": "number"
+ },
+ "chargeOptionPhase": {
+ "type": "number"
+ },
+ "chargeOptionPhaseAmp": {
+ "type": "number"
+ },
+ "chargeOptionChargeTime": {
+ "type": "number"
+ },
+ "chargeOptionChargeSpeed": {
+ "type": "number"
+ },
+ "chargeOptionTables": {
+ "$ref": "#/definitions/chargeTables"
+ },
+ "fastChargePlug": {
+ "type": "string"
+ },
+ "fastChargePlugEstimate": {
+ "type": "boolean"
+ },
+ "fastChargePlugLocation": {
+ "type": "string"
+ },
+ "fastChargePowerMax": {
+ "type": "number"
+ },
+ "fastChargePowerAvg": {
+ "type": "number"
+ },
+ "fastChargeTime": {
+ "type": "number"
+ },
+ "fastChargeSpeed": {
+ "type": "number"
+ },
+ "fastChargeOptional": {
+ "type": "boolean"
+ },
+ "fastChargeEstimate": {
+ "type": "boolean"
+ },
+ "batteryCapacityUseable": {
+ "type": "number"
+ },
+ "batteryCapacityFull": {
+ "type": "number"
+ },
+ "batteryCapacityEstimate": {
+ "type": "string"
+ },
+ "dimsLength": {
+ "type": "number"
+ },
+ "dimsWidth": {
+ "type": "number"
+ },
+ "dimsHeight": {
+ "type": "number"
+ },
+ "dimsWheelbase": {
+ "type": "number"
+ },
+ "dimsWeight": {
+ "type": "number"
+ },
+ "dimsBootspace": {
+ "type": "number"
+ },
+ "dimsBootspaceMax": {
+ "type": "number"
+ },
+ "dimsTowWeightUnbraked": {
+ "type": "number"
+ },
+ "dimsTowWeightBraked": {
+ "type": "number"
+ },
+ "dimsRoofLoadMax": {
+ "type": "number"
+ },
+ "miscBody": {
+ "type": "string"
+ },
+ "miscSegment": {
+ "type": "string"
+ },
+ "miscSeats": {
+ "type": "number"
+ },
+ "miscRoofrails": {
+ "type": "boolean"
+ },
+ "miscIsofix": {
+ "type": "boolean"
+ },
+ "miscIsofixSeats": {
+ "type": "number"
+ },
+ "miscTurningCircle": {
+ "type": "number"
+ },
+ "euroNCAPRating": {
+ "type": "number"
+ },
+ "euroNCAPYear": {
+ "type": "number"
+ },
+ "euroNCAPAdult": {
+ "type": "number"
+ },
+ "euroNCAPChild": {
+ "type": "number"
+ },
+ "euroNCAPVRU": {
+ "type": "number"
+ },
+ "euroNCAPSA": {
+ "type": "number"
+ },
+ "relatedVehicleIDSuccessor": {
+ "type": "number"
+ },
+ "eVDBDetailURL": {
+ "type": "string"
+ },
+ "videos": {
+ "type": "string"
+ },
+ "hash": {
+ "type": "string"
+ },
+ "imageURLs": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "lastChangedOn": {
+ "type": ["string", "object"],
+ "format": "date"
+ }
+ },
+ "required": [
+ "id",
+ "vehicleMake",
+ "vehicleModel",
+ "vehicleModelVersion"
+ ],
+ "definitions": {
+ "chargeTables": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "evsePhaseVolt": {
+ "type": "number"
+ },
+ "evsePhaseAmp": {
+ "type": "number"
+ },
+ "evsePhase": {
+ "type": "number"
+ },
+ "evsePhaseVoltCalculated": {
+ "type": "number"
+ },
+ "chargePhaseVolt": {
+ "type": "number"
+ },
+ "chargePhaseAmp": {
+ "type": "number"
+ },
+ "chargePhase": {
+ "type": "number"
+ },
+ "chargePower": {
+ "type": "number"
+ },
+ "chargeTime": {
+ "type": "number"
+ },
+ "chargeSpeed": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+}

MODIFY
src/integration/car/ev-database/EVDatabaseCarIntegration.ts
src/integration/car/ev-database/EVDatabaseCarIntegration.ts
-import { CarCatalog, CarCatalogChargeAlternativeTable, CarCatalogChargeOptionTable, CarCatalogConverter } from '../../../types/Car';
+import { CarCatalog, CarCatalogConverter } from '../../../types/Car';
import AxiosFactory from '../../../utils/AxiosFactory';
import { AxiosInstance } from 'axios';
@@ -36,8 +36,8 @@ export default class EVDatabaseCarIntegration extends CarIntegration {
// Build result
for (const data of response.data) {
const chargeStandardTables: CarCatalogConverter[] = [];
- const chargeAlternativeTables: CarCatalogChargeAlternativeTable[] = [];
- const chargeOptionTables: CarCatalogChargeOptionTable[] = [];
+ const chargeAlternativeTables: CarCatalogConverter[] = [];
+ const chargeOptionTables: CarCatalogConverter[] = [];
for (const chargeStandard of Object.keys(data.Charge_Standard_Table)) {
const chargeStandardTable: CarCatalogConverter = {
type: chargeStandard,
@@ -56,7 +56,7 @@ export default class EVDatabaseCarIntegration extends CarIntegration {
}
if (data.Charge_Alternative_Table) {
for (const chargeAlternative of Object.keys(data.Charge_Alternative_Table)) {
- const chargeAlternativeTable: CarCatalogChargeAlternativeTable = {
+ const chargeAlternativeTable: CarCatalogConverter = {
type: chargeAlternative,
evsePhaseVolt: data.Charge_Standard_Table[chargeAlternative].EVSE_PhaseVolt,
evsePhaseAmp: data.Charge_Standard_Table[chargeAlternative].EVSE_PhaseAmp,
@@ -73,7 +73,7 @@ export default class EVDatabaseCarIntegration extends CarIntegration {
}
if (data.Charge_Option_Table) {
for (const chargeOption of Object.keys(data.Charge_Option_Table)) {
- const chargeAlternativeTable: CarCatalogChargeOptionTable = {
+ const chargeAlternativeTable: CarCatalogConverter = {
type: chargeOption,
evsePhaseVolt: data.Charge_Standard_Table[chargeOption].EVSE_PhaseVolt,
evsePhaseAmp: data.Charge_Standard_Table[chargeOption].EVSE_PhaseAmp,

MODIFY
src/storage/mongodb/CarStorage.ts
src/storage/mongodb/CarStorage.ts
-import { Car, CarCatalog, CarCatalogChargeAlternativeTable, CarCatalogChargeOptionTable, CarCatalogConverter, CarMaker, CarType } from '../../types/Car';
+import { Car, CarCatalog, CarCatalogConverter, CarMaker, CarType } from '../../types/Car';
import global, { DatabaseCount, FilterParams, Image } from '../../types/GlobalType';
+import CarValidatorStorage from './validator/CarValidatorStorage';
import Constants from '../../utils/Constants';
import { DataResult } from '../../types/DataResult';
import DatabaseUtils from './DatabaseUtils';
@@ -143,164 +144,16 @@ export default class CarStorage {
public static async saveCarCatalog(carToSave: CarCatalog): Promise<number> {
// Debug
const startTime = Logging.traceDatabaseRequestStart();
- // Build Request
+ // Validate
+ const carCatalog = CarValidatorStorage.getInstance().validateCarCatalog(
+ carToSave as unknown as Record<string, unknown>);
// Properties to save
const carMDB: any = {
- _id: Utils.convertToInt(carToSave.id),
- vehicleMake: carToSave.vehicleMake,
- vehicleModel: carToSave.vehicleModel,
- vehicleModelVersion: carToSave.vehicleModelVersion,
- availabilityStatus: carToSave.availabilityStatus,
- availabilityDateFrom: carToSave.availabilityDateFrom,
- availabilityDateTo: carToSave.availabilityDateTo,
- priceFromDE: Utils.convertToFloat(carToSave.priceFromDE),
- priceFromDEEstimate: carToSave.priceFromDEEstimate,
- priceFromNL: Utils.convertToFloat(carToSave.priceFromNL),
- priceFromNLEstimate: carToSave.priceFromNLEstimate,
- priceFromUK: Utils.convertToFloat(carToSave.priceFromUK),
- priceGrantPICGUK: Utils.convertToFloat(carToSave.priceGrantPICGUK),
- priceFromUKEstimate: carToSave.priceFromUKEstimate,
- drivetrainType: carToSave.drivetrainType,
- drivetrainFuel: carToSave.drivetrainFuel,
- drivetrainPropulsion: carToSave.drivetrainPropulsion,
- drivetrainPower: Utils.convertToInt(carToSave.drivetrainPower),
- drivetrainPowerHP: Utils.convertToInt(carToSave.drivetrainPowerHP),
- drivetrainTorque: Utils.convertToInt(carToSave.drivetrainTorque),
- performanceAcceleration: Utils.convertToFloat(carToSave.performanceAcceleration),
- performanceTopspeed: Utils.convertToInt(carToSave.performanceTopspeed),
- rangeWLTP: Utils.convertToInt(carToSave.rangeWLTP),
- rangeWLTPEstimate: carToSave.rangeWLTPEstimate,
- rangeNEDC: Utils.convertToInt(carToSave.rangeNEDC),
- rangeNEDCEstimate: carToSave.rangeNEDCEstimate,
- rangeReal: Utils.convertToInt(carToSave.rangeReal),
- rangeRealMode: carToSave.rangeRealMode,
- rangeRealWHwy: carToSave.rangeRealWHwy,
- rangeRealWCmb: carToSave.rangeRealWCmb,
- rangeRealWCty: carToSave.rangeRealWCty,
- rangeRealBHwy: carToSave.rangeRealBHwy,
- rangeRealBCmb: carToSave.rangeRealBCmb,
- rangeRealBCty: carToSave.rangeRealBCty,
- efficiencyWLTP: Utils.convertToFloat(carToSave.efficiencyWLTP),
- efficiencyWLTPFuelEq: Utils.convertToFloat(carToSave.efficiencyWLTPFuelEq),
- efficiencyWLTPV: Utils.convertToFloat(carToSave.efficiencyWLTPV),
- efficiencyWLTPFuelEqV: Utils.convertToFloat(carToSave.efficiencyWLTPFuelEqV),
- efficiencyWLTPCO2: Utils.convertToFloat(carToSave.efficiencyWLTPCO2),
- efficiencyNEDC: Utils.convertToFloat(carToSave.efficiencyNEDC),
- efficiencyNEDCFuelEq: Utils.convertToFloat(carToSave.efficiencyNEDCFuelEq),
- efficiencyNEDCV: Utils.convertToFloat(carToSave.efficiencyNEDCV),
- efficiencyNEDCFuelEqV: Utils.convertToFloat(carToSave.efficiencyNEDCFuelEqV),
- efficiencyNEDCCO2: Utils.convertToFloat(carToSave.efficiencyNEDCCO2),
- efficiencyReal: Utils.convertToFloat(carToSave.efficiencyReal),
- efficiencyRealFuelEqV: Utils.convertToFloat(carToSave.efficiencyRealFuelEqV),
- efficiencyRealCO2: Utils.convertToFloat(carToSave.efficiencyRealCO2),
- efficiencyRealWHwy: Utils.convertToFloat(carToSave.efficiencyRealWHwy),
- efficiencyRealWCmb: Utils.convertToFloat(carToSave.efficiencyRealWCmb),
- efficiencyRealWCty: Utils.convertToFloat(carToSave.efficiencyRealWCty),
- efficiencyRealBHwy: Utils.convertToFloat(carToSave.efficiencyRealBHwy),
- efficiencyRealBCmb: Utils.convertToFloat(carToSave.efficiencyRealBCmb),
- efficiencyRealBCty: Utils.convertToFloat(carToSave.efficiencyRealBCty),
- chargePlug: carToSave.chargePlug,
- chargePlugEstimate: carToSave.chargePlugEstimate,
- chargePlugLocation: carToSave.chargePlugLocation,
- chargeStandardPower: Utils.convertToFloat(carToSave.chargeStandardPower),
- chargeStandardPhase: Utils.convertToInt(carToSave.chargeStandardPhase),
- chargeStandardPhaseAmp: Utils.convertToInt(carToSave.chargeStandardPhaseAmp),
- chargeStandardChargeTime: Utils.convertToInt(carToSave.chargeStandardChargeTime),
- chargeStandardChargeSpeed: Utils.convertToInt(carToSave.chargeStandardChargeSpeed),
- chargeStandardEstimate: carToSave.chargeStandardEstimate,
- chargeStandardTables: carToSave.chargeStandardTables ?
- carToSave.chargeStandardTables.map((chargeStandardTable: CarCatalogConverter): CarCatalogConverter => ({
- type: chargeStandardTable.type,
- evsePhaseVolt: Utils.convertToInt(chargeStandardTable.evsePhaseVolt),
- evsePhaseAmp: Utils.convertToInt(chargeStandardTable.evsePhaseAmp),
- evsePhase: Utils.convertToInt(chargeStandardTable.evsePhase),
- evsePhaseVoltCalculated: Utils.convertToInt(chargeStandardTable.evsePhaseVoltCalculated),
- chargePhaseVolt: Utils.convertToInt(chargeStandardTable.chargePhaseVolt),
- chargePhaseAmp: Utils.convertToInt(chargeStandardTable.chargePhaseAmp),
- chargePhase: Utils.convertToInt(chargeStandardTable.chargePhase),
- chargePower: Utils.convertToFloat(chargeStandardTable.chargePower),
- chargeTime: Utils.convertToInt(chargeStandardTable.chargeTime),
- chargeSpeed: Utils.convertToInt(chargeStandardTable.chargeSpeed)
- })) : [],
- chargeAlternativePower: Utils.convertToInt(carToSave.chargeAlternativePower),
- chargeAlternativePhase: Utils.convertToInt(carToSave.chargeAlternativePhase),
- chargeAlternativePhaseAmp: Utils.convertToInt(carToSave.chargeAlternativePhaseAmp),
- chargeAlternativeChargeTime: Utils.convertToInt(carToSave.chargeAlternativeChargeTime),
- chargeAlternativeChargeSpeed: Utils.convertToInt(carToSave.chargeAlternativeChargeSpeed),
- chargeAlternativeTables: carToSave.chargeAlternativeTables ?
- carToSave.chargeAlternativeTables.map((chargeAlternativeTable: CarCatalogChargeAlternativeTable): CarCatalogChargeAlternativeTable => ({
- type: chargeAlternativeTable.type,
- evsePhaseVolt: Utils.convertToInt(chargeAlternativeTable.evsePhaseVolt),
- evsePhaseAmp: Utils.convertToInt(chargeAlternativeTable.evsePhaseAmp),
- evsePhase: Utils.convertToInt(chargeAlternativeTable.evsePhase),
- chargePhaseVolt: Utils.convertToInt(chargeAlternativeTable.chargePhaseVolt),
- chargePhaseAmp: Utils.convertToInt(chargeAlternativeTable.chargePhaseAmp),
- chargePhase: Utils.convertToInt(chargeAlternativeTable.chargePhase),
- chargePower: Utils.convertToFloat(chargeAlternativeTable.chargePower),
- chargeTime: Utils.convertToInt(chargeAlternativeTable.chargeTime),
- chargeSpeed: Utils.convertToInt(chargeAlternativeTable.chargeSpeed)
- })) : [],
- chargeOptionPower: Utils.convertToInt(carToSave.chargeOptionPower),
- chargeOptionPhase: Utils.convertToInt(carToSave.chargeOptionPhase),
- chargeOptionPhaseAmp: Utils.convertToInt(carToSave.chargeOptionPhaseAmp),
- chargeOptionChargeTime: Utils.convertToInt(carToSave.chargeOptionChargeTime),
- chargeOptionChargeSpeed: Utils.convertToInt(carToSave.chargeOptionChargeSpeed),
- chargeOptionTables: carToSave.chargeOptionTables ?
- carToSave.chargeOptionTables.map((chargeOptionTables: CarCatalogChargeOptionTable): CarCatalogChargeOptionTable => ({
- type: chargeOptionTables.type,
- evsePhaseVolt: Utils.convertToInt(chargeOptionTables.evsePhaseVolt),
- evsePhaseAmp: Utils.convertToInt(chargeOptionTables.evsePhaseAmp),
- evsePhase: Utils.convertToInt(chargeOptionTables.evsePhase),
- chargePhaseVolt: Utils.convertToInt(chargeOptionTables.chargePhaseVolt),
- chargePhaseAmp: Utils.convertToInt(chargeOptionTables.chargePhaseAmp),
- chargePhase: Utils.convertToInt(chargeOptionTables.chargePhase),
- chargePower: Utils.convertToFloat(chargeOptionTables.chargePower),
- chargeTime: Utils.convertToInt(chargeOptionTables.chargeTime),
- chargeSpeed: Utils.convertToInt(chargeOptionTables.chargeSpeed)
- })) : [],
- fastChargePlug: carToSave.fastChargePlug,
- fastChargePlugEstimate: carToSave.fastChargePlugEstimate,
- fastChargePlugLocation: carToSave.fastChargePlugLocation,
- fastChargePowerMax: Utils.convertToInt(carToSave.fastChargePowerMax),
- fastChargePowerAvg: Utils.convertToInt(carToSave.fastChargePowerAvg),
- fastChargeTime: Utils.convertToInt(carToSave.fastChargeTime),
- fastChargeSpeed: Utils.convertToInt(carToSave.fastChargeSpeed),
- fastChargeOptional: carToSave.fastChargeOptional,
- fastChargeEstimate: carToSave.fastChargeEstimate,
- batteryCapacityUseable: Utils.convertToFloat(carToSave.batteryCapacityUseable),
- batteryCapacityFull: Utils.convertToFloat(carToSave.batteryCapacityFull),
- batteryCapacityEstimate: carToSave.batteryCapacityEstimate,
- dimsLength: Utils.convertToInt(carToSave.dimsLength),
- dimsWidth: Utils.convertToInt(carToSave.dimsWidth),
- dimsHeight: Utils.convertToInt(carToSave.dimsHeight),
- dimsWheelbase: carToSave.dimsWheelbase,
- dimsWeight: Utils.convertToInt(carToSave.dimsWeight),
- dimsBootspace: Utils.convertToInt(carToSave.dimsBootspace),
- dimsBootspaceMax: Utils.convertToInt(carToSave.dimsBootspaceMax),
- dimsTowWeightUnbraked: Utils.convertToInt(carToSave.dimsTowWeightUnbraked),
- dimsTowWeightBraked: Utils.convertToInt(carToSave.dimsTowWeightBraked),
- dimsRoofLoadMax: Utils.convertToInt(carToSave.dimsRoofLoadMax),
- miscBody: carToSave.miscBody,
- miscSegment: carToSave.miscSegment,
- miscSeats: Utils.convertToInt(carToSave.miscSeats),
- miscRoofrails: carToSave.miscRoofrails,
- miscIsofix: carToSave.miscIsofix,
- miscIsofixSeats: carToSave.miscIsofixSeats,
- miscTurningCircle: carToSave.miscTurningCircle,
- euroNCAPRating: Utils.convertToInt(carToSave.euroNCAPRating),
- euroNCAPYear: carToSave.euroNCAPYear,
- euroNCAPAdult: Utils.convertToInt(carToSave.euroNCAPAdult),
- euroNCAPChild: Utils.convertToInt(carToSave.euroNCAPChild),
- euroNCAPVRU: Utils.convertToInt(carToSave.euroNCAPVRU),
- euroNCAPSA: Utils.convertToInt(carToSave.euroNCAPSA),
- relatedVehicleIDSuccessor: Utils.convertToInt(carToSave.relatedVehicleIDSuccessor),
- eVDBDetailURL: carToSave.eVDBDetailURL,
- videos: carToSave.videos,
- hash: carToSave.hash,
- imageURLs: carToSave.imageURLs,
- image: carToSave.image,
- imagesHash: carToSave.imagesHash
+ _id: carToSave.id,
+ ...carCatalog,
};
+ // Remove ID
+ delete carMDB.id;
// Add Last Changed/Created props
DatabaseUtils.addLastChangedCreatedProps(carMDB, carToSave);
// Modify and return the modified document

MODIFY
src/storage/mongodb/ChargingStationStorage.ts
src/storage/mongodb/ChargingStationStorage.ts
@@ -89,7 +89,7 @@ export default class ChargingStationStorage {
// Debug
const startTime = Logging.traceDatabaseRequestStart();
// Validate
- chargingStationTemplate = ChargingStationValidatorStorage.getInstance().validateChargingStationStorageTemplate(
+ chargingStationTemplate = ChargingStationValidatorStorage.getInstance().validateChargingStationTemplate(
chargingStationTemplate as unknown as Record<string, unknown>);
// Modify and return the modified document
await global.database.getCollection<ChargingStationTemplate>(Constants.DEFAULT_TENANT, 'chargingstationtemplates').findOneAndReplace(

ADD
src/storage/mongodb/validator/CarValidatorStorage.ts
+import { ChargingStationTemplate } from '../../../types/ChargingStation';
+import Schema from '../../../types/validator/Schema';
+import SchemaValidator from '../../../validator/SchemaValidator';
+import fs from 'fs';
+import global from '../../../types/GlobalType';
+
+export default class CarValidatorStorage extends SchemaValidator {
+ private static instance: CarValidatorStorage | null = null;
+ private carCatalog: Schema;
+
+ private constructor() {
+ super('CarValidatorStorage', {
+ strict: false, // When 'true', it fails with anyOf required fields: https://github.com/ajv-validator/ajv/issues/1571
+ allErrors: true,
+ removeAdditional: false, // 'all' fails with anyOf documents: Manually added 'additionalProperties: false' in schema due filtering of data in anyOf/oneOf/allOf array (it's standard): https://github.com/ajv-validator/ajv/issues/1784
+ allowUnionTypes: true,
+ coerceTypes: true,
+ verbose: true,
+ });
+ this.carCatalog = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/car/car-catalog.json`, 'utf8'));
+ }
+
+ public static getInstance(): CarValidatorStorage {
+ if (!CarValidatorStorage.instance) {
+ CarValidatorStorage.instance = new CarValidatorStorage();
+ }
+ return CarValidatorStorage.instance;
+ }
+
+ public validateCarCatalog(data: Record<string, unknown>): ChargingStationTemplate {
+ return this.validate(this.carCatalog, data);
+ }
+}

MODIFY
src/storage/mongodb/validator/ChargingStationValidatorStorage.ts
src/storage/mongodb/validator/ChargingStationValidatorStorage.ts
@@ -27,7 +27,7 @@ export default class ChargingStationValidatorStorage extends SchemaValidator {
return ChargingStationValidatorStorage.instance;
}
- public validateChargingStationStorageTemplate(data: Record<string, unknown>): ChargingStationTemplate {
+ public validateChargingStationTemplate(data: Record<string, unknown>): ChargingStationTemplate {
return this.validate(this.chargingStationTemplate, data);
}
}

MODIFY
src/types/Car.ts
src/types/Car.ts
@@ -7,8 +7,8 @@ export interface CarCatalog extends CreatedUpdatedProps, AuthorizationActions {
vehicleModel: string;
vehicleModelVersion?: string;
availabilityStatus: string;
- availabilityDateFrom: string;
- availabilityDateTo?: string;
+ availabilityDateFrom: Date;
+ availabilityDateTo?: Date;
priceFromDE?: number;
priceFromDEEstimate: boolean;
priceFromNL?: number;
@@ -70,13 +70,13 @@ export interface CarCatalog extends CreatedUpdatedProps, AuthorizationActions {
chargeAlternativePhaseAmp: number;
chargeAlternativeChargeTime: number;
chargeAlternativeChargeSpeed: number;
- chargeAlternativeTables: CarCatalogChargeAlternativeTable[];
+ chargeAlternativeTables: CarCatalogConverter[];
chargeOptionPower?: number;
chargeOptionPhase?: number;
chargeOptionPhaseAmp?: number;
chargeOptionChargeTime?: number;
chargeOptionChargeSpeed?: number;
- chargeOptionTables: CarCatalogChargeOptionTable[];
+ chargeOptionTables: CarCatalogConverter[];
fastChargePlug?: string;
fastChargePlugEstimate?: boolean;
fastChargePlugLocation?: string;
@@ -157,34 +157,10 @@ export interface CarMaker {
carMaker: string;
}
-export interface CarCatalogChargeOptionTable {
- type: string;
- evsePhaseVolt?: number;
- evsePhaseAmp?: number;
- evsePhase?: number;
- chargePhaseVolt?: number;
- chargePhaseAmp?: number;
- chargePhase?: number;
- chargePower?: number;
- chargeTime?: number;
- chargeSpeed?: number;
-}
-export interface CarCatalogChargeAlternativeTable {
- type: string;
- evsePhaseVolt: number;
- evsePhaseAmp: number;
- evsePhase: number;
- chargePhaseVolt: number;
- chargePhaseAmp: number;
- chargePhase: number;
- chargePower: number;
- chargeTime: number;
- chargeSpeed: number;
-}
export interface CarCatalogConverter {
type: string;
evsePhaseVolt: number;
- evsePhaseVoltCalculated: number;
+ evsePhaseVoltCalculated?: number;
evsePhaseAmp: number;
evsePhase: number;
chargePhaseVolt: number;

Added schema in import of car catalog