From ccb1d6e97cc0248cd96a9505cf5e8f037d66984c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 21 May 2022 00:12:16 +0200 Subject: [PATCH] Permit to disable persistent configuration storage. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 101 +++++++++--------- .../AutomaticTransactionGenerator.ts | 8 +- src/charging-station/ChargingStation.ts | 91 +++++++++------- src/charging-station/ChargingStationUtils.ts | 34 +++--- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 2 +- src/types/ChargingStationTemplate.ts | 1 + 6 files changed, 126 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index d1bfd73b..6056973b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Summary -Simple [node.js](https://nodejs.org/) program to simulate a set of charging stations based on the OCPP-J 1.6 protocol. +Simple [node.js](https://nodejs.org/) software to simulate a set of charging stations based on the OCPP-J 1.6 protocol as part of SAP e-Mobility solution. ## Prerequisites @@ -99,55 +99,56 @@ But the modifications to test have to be done to the files in the build result d **src/assets/station-templates/\.json**: -| Key | Value(s) | Default Value | Value type | Description | -| --------------------------------- | ---------- | --------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| supervisionUrls | | '' | string \| string[] | string or array of connection URIs to OCPP-J servers | -| supervisionUser | | '' | string | basic HTTP authentication user to OCPP-J server | -| supervisionPassword | | '' | string | basic HTTP authentication password to OCPP-J server | -| supervisionUrlOcppConfiguration | true/false | false | boolean | allow supervision URL configuration via a vendor OCPP parameter key | -| supervisionUrlOcppKey | | 'ConnectionUrl' | string | the vendor string that will be used as a vendor OCPP parameter key to set the supervision URL | -| ocppVersion | 1.6 | 1.6 | string | OCPP version | -| ocppProtocol | json | json | string | OCPP protocol | -| ocppStrictCompliance | true/false | false | boolean | strict adherence to the OCPP version and protocol specifications | -| ocppPersistentConfiguration | true/false | true | boolean | enable persistent OCPP parameters storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in dist/assets/configurations | -| wsOptions | | {} | ClientOptions & ClientRequestArgs | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection | -| authorizationFile | | '' | string | RFID tags list file relative to src/assets path | -| baseName | | '' | string | base name to build charging stations id | -| nameSuffix | | '' | string | name suffix to build charging stations id | -| fixedName | true/false | false | boolean | use the baseName as the charging stations unique name | -| chargePointModel | | '' | string | charging stations model | -| chargePointVendor | | '' | string | charging stations vendor | -| chargePointSerialNumberPrefix | | '' | string | charge point serial number prefix | -| chargeBoxSerialNumberPrefix | | '' | string | charge box serial number prefix (deprecated in OCPP 1.6) | -| firmwareVersion | | '' | string | charging stations firmware version | -| power | | | float \| float[] | charging stations maximum power value(s) | -| powerSharedByConnectors | true/false | false | boolean | charging stations power shared by its connectors | -| powerUnit | W/kW | W | string | charging stations power unit | -| currentOutType | AC/DC | AC | string | charging stations current out type | -| voltageOut | | AC:230/DC:400 | integer | charging stations voltage out | -| numberOfPhases | 0/1/3 | AC:3/DC:0 | integer | charging stations number of phase(s) | -| numberOfConnectors | | | integer \| integer[] | charging stations number of connector(s) | -| useConnectorId0 | true/false | true | boolean | use connector id 0 definition from the charging station configuration template | -| randomConnectors | true/false | false | boolean | randomize runtime connector id affectation from the connector id definition in charging station configuration template | -| resetTime | | 60 | integer | seconds to wait before the charging stations come back at reset | -| autoRegister | true/false | false | boolean | set charging stations as registered at boot notification for testing purpose | -| autoReconnectMaxRetries | | -1 (unlimited) | integer | connection retries to the OCPP-J server | -| reconnectExponentialDelay | true/false | false | boolean | connection delay retry to the OCPP-J server | -| registrationMaxRetries | | -1 (unlimited) | integer | charging stations boot notification retries | -| amperageLimitationOcppKey | | undefined | string | charging stations OCPP parameter key used to set the amperage limit, per phase for each connector on AC and global for DC | -| amperageLimitationUnit | A/cA/dA/mA | A | string | charging stations amperage limit unit | -| enableStatistics | true/false | true | boolean | enable charging stations statistics | -| mayAuthorizeAtRemoteStart | true/false | true | boolean | always send authorize at remote start transaction when AuthorizeRemoteTxRequests is enabled | -| beginEndMeterValues | true/false | false | boolean | enable Transaction.{Begin,End} MeterValues | -| outOfOrderEndMeterValues | true/false | false | boolean | send Transaction.End MeterValues out of order. Need to relax OCPP specifications strict compliance ('ocppStrictCompliance' parameter) | -| meteringPerTransaction | true/false | true | boolean | enable metering history on a per transaction basis | -| transactionDataMeterValues | true/false | false | boolean | enable transaction data MeterValues at stop transaction | -| mainVoltageMeterValues | true/false | true | boolean | include charging stations main voltage MeterValues on three phased charging stations | -| phaseLineToLineVoltageMeterValues | true/false | true | boolean | include charging stations line to line voltage MeterValues on three phased charging stations | -| customValueLimitationMeterValues | true/false | true | boolean | enable limitation on custom fluctuated value in MeterValues | -| Configuration | | | ChargingStationConfiguration | charging stations OCPP parameters configuration section | -| AutomaticTransactionGenerator | | | AutomaticTransactionGenerator | charging stations ATG configuration section | -| Connectors | | | Connectors | charging stations connectors configuration section | +| Key | Value(s) | Default Value | Value type | Description | +| ---------------------------------- | ---------- | --------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| supervisionUrls | | '' | string \| string[] | string or array of connection URIs to OCPP-J servers | +| supervisionUser | | '' | string | basic HTTP authentication user to OCPP-J server | +| supervisionPassword | | '' | string | basic HTTP authentication password to OCPP-J server | +| supervisionUrlOcppConfiguration | true/false | false | boolean | allow supervision URL configuration via a vendor OCPP parameter key | +| supervisionUrlOcppKey | | 'ConnectionUrl' | string | the vendor string that will be used as a vendor OCPP parameter key to set the supervision URL | +| ocppVersion | 1.6 | 1.6 | string | OCPP version | +| ocppProtocol | json | json | string | OCPP protocol | +| ocppStrictCompliance | true/false | false | boolean | strict adherence to the OCPP version and protocol specifications | +| ocppPersistentConfiguration | true/false | true | boolean | enable persistent OCPP parameters storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in dist/assets/configurations | +| stationInfoPersistentConfiguration | true/false | true | boolean | enable persistent station information and specifications storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in dist/assets/configurations | +| wsOptions | | {} | ClientOptions & ClientRequestArgs | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection | +| authorizationFile | | '' | string | RFID tags list file relative to src/assets path | +| baseName | | '' | string | base name to build charging stations id | +| nameSuffix | | '' | string | name suffix to build charging stations id | +| fixedName | true/false | false | boolean | use the baseName as the charging stations unique name | +| chargePointModel | | '' | string | charging stations model | +| chargePointVendor | | '' | string | charging stations vendor | +| chargePointSerialNumberPrefix | | '' | string | charge point serial number prefix | +| chargeBoxSerialNumberPrefix | | '' | string | charge box serial number prefix (deprecated in OCPP 1.6) | +| firmwareVersion | | '' | string | charging stations firmware version | +| power | | | float \| float[] | charging stations maximum power value(s) | +| powerSharedByConnectors | true/false | false | boolean | charging stations power shared by its connectors | +| powerUnit | W/kW | W | string | charging stations power unit | +| currentOutType | AC/DC | AC | string | charging stations current out type | +| voltageOut | | AC:230/DC:400 | integer | charging stations voltage out | +| numberOfPhases | 0/1/3 | AC:3/DC:0 | integer | charging stations number of phase(s) | +| numberOfConnectors | | | integer \| integer[] | charging stations number of connector(s) | +| useConnectorId0 | true/false | true | boolean | use connector id 0 definition from the charging station configuration template | +| randomConnectors | true/false | false | boolean | randomize runtime connector id affectation from the connector id definition in charging station configuration template | +| resetTime | | 60 | integer | seconds to wait before the charging stations come back at reset | +| autoRegister | true/false | false | boolean | set charging stations as registered at boot notification for testing purpose | +| autoReconnectMaxRetries | | -1 (unlimited) | integer | connection retries to the OCPP-J server | +| reconnectExponentialDelay | true/false | false | boolean | connection delay retry to the OCPP-J server | +| registrationMaxRetries | | -1 (unlimited) | integer | charging stations boot notification retries | +| amperageLimitationOcppKey | | undefined | string | charging stations OCPP parameter key used to set the amperage limit, per phase for each connector on AC and global for DC | +| amperageLimitationUnit | A/cA/dA/mA | A | string | charging stations amperage limit unit | +| enableStatistics | true/false | true | boolean | enable charging stations statistics | +| mayAuthorizeAtRemoteStart | true/false | true | boolean | always send authorize at remote start transaction when AuthorizeRemoteTxRequests is enabled | +| beginEndMeterValues | true/false | false | boolean | enable Transaction.{Begin,End} MeterValues | +| outOfOrderEndMeterValues | true/false | false | boolean | send Transaction.End MeterValues out of order. Need to relax OCPP specifications strict compliance ('ocppStrictCompliance' parameter) | +| meteringPerTransaction | true/false | true | boolean | enable metering history on a per transaction basis | +| transactionDataMeterValues | true/false | false | boolean | enable transaction data MeterValues at stop transaction | +| mainVoltageMeterValues | true/false | true | boolean | include charging stations main voltage MeterValues on three phased charging stations | +| phaseLineToLineVoltageMeterValues | true/false | true | boolean | include charging stations line to line voltage MeterValues on three phased charging stations | +| customValueLimitationMeterValues | true/false | true | boolean | enable limitation on custom fluctuated value in MeterValues | +| Configuration | | | ChargingStationConfiguration | charging stations OCPP parameters configuration section | +| AutomaticTransactionGenerator | | | AutomaticTransactionGenerator | charging stations ATG configuration section | +| Connectors | | | Connectors | charging stations connectors configuration section | #### Configuration section diff --git a/src/charging-station/AutomaticTransactionGenerator.ts b/src/charging-station/AutomaticTransactionGenerator.ts index 56e4feaa..b806d5cf 100644 --- a/src/charging-station/AutomaticTransactionGenerator.ts +++ b/src/charging-station/AutomaticTransactionGenerator.ts @@ -274,7 +274,7 @@ export default class AutomaticTransactionGenerator { let startResponse: StartTransactionResponse; if (this.chargingStation.hasAuthorizedTags()) { const idTag = this.chargingStation.getRandomIdTag(); - if (this.chargingStation.getAutomaticTransactionGeneratorRequireAuthorize()) { + if (this.getRequireAuthorize()) { this.chargingStation.getConnectorStatus(connectorId).authorizeIdTag = idTag; // Authorize idTag const authorizeResponse: AuthorizeResponse = @@ -375,6 +375,12 @@ export default class AutomaticTransactionGenerator { return stopResponse; } + private getRequireAuthorize(): boolean { + return ( + this.chargingStation.stationInfo?.AutomaticTransactionGenerator?.requireAuthorize ?? true + ); + } + private logPrefix(connectorId?: number): string { if (connectorId) { return Utils.logPrefix( diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index fed9f42c..f283c50d 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -131,7 +131,12 @@ export default class ChargingStation { } public logPrefix(): string { - return Utils.logPrefix(` ${this.stationInfo.chargingStationId} |`); + return Utils.logPrefix( + ` ${ + this?.stationInfo?.chargingStationId ?? + ChargingStationUtils.getChargingStationId(this.index, this.getTemplateFromFile()) + } |` + ); } public getBootNotificationRequest(): BootNotificationRequest { @@ -217,7 +222,7 @@ export default class ChargingStation { } public getOcppStrictCompliance(): boolean { - return this.stationInfo.ocppStrictCompliance ?? false; + return this.stationInfo?.ocppStrictCompliance ?? false; } public getVoltageOut(): number | undefined { @@ -267,31 +272,31 @@ export default class ChargingStation { } public getOutOfOrderEndMeterValues(): boolean { - return this.stationInfo.outOfOrderEndMeterValues ?? false; + return this.stationInfo?.outOfOrderEndMeterValues ?? false; } public getBeginEndMeterValues(): boolean { - return this.stationInfo.beginEndMeterValues ?? false; + return this.stationInfo?.beginEndMeterValues ?? false; } public getMeteringPerTransaction(): boolean { - return this.stationInfo.meteringPerTransaction ?? true; + return this.stationInfo?.meteringPerTransaction ?? true; } public getTransactionDataMeterValues(): boolean { - return this.stationInfo.transactionDataMeterValues ?? false; + return this.stationInfo?.transactionDataMeterValues ?? false; } public getMainVoltageMeterValues(): boolean { - return this.stationInfo.mainVoltageMeterValues ?? true; + return this.stationInfo?.mainVoltageMeterValues ?? true; } public getPhaseLineToLineVoltageMeterValues(): boolean { - return this.stationInfo.phaseLineToLineVoltageMeterValues ?? false; + return this.stationInfo?.phaseLineToLineVoltageMeterValues ?? false; } public getCustomValueLimitationMeterValues(): boolean { - return this.stationInfo.customValueLimitationMeterValues ?? true; + return this.stationInfo?.customValueLimitationMeterValues ?? true; } public getConnectorIdByTransactionId(transactionId: number): number | undefined { @@ -341,10 +346,6 @@ export default class ChargingStation { return localAuthListEnabled ? Utils.convertToBoolean(localAuthListEnabled.value) : false; } - public getAutomaticTransactionGeneratorRequireAuthorize(): boolean { - return this.stationInfo.AutomaticTransactionGenerator.requireAuthorize ?? true; - } - public startHeartbeat(): void { if ( this.getHeartbeatInterval() && @@ -709,9 +710,7 @@ export default class ChargingStation { try { const measureId = `${FileType.ChargingStationTemplate} read`; const beginId = PerformanceStatistics.beginMeasure(measureId); - template = - (JSON.parse(fs.readFileSync(this.templateFile, 'utf8')) as ChargingStationTemplate) ?? - ({} as ChargingStationTemplate); + template = JSON.parse(fs.readFileSync(this.templateFile, 'utf8')) as ChargingStationTemplate; PerformanceStatistics.endMeasure(measureId, beginId); template.templateHash = crypto .createHash(Constants.DEFAULT_HASH_ALGORITHM) @@ -731,16 +730,14 @@ export default class ChargingStation { private getStationInfoFromTemplate(): ChargingStationInfo { const stationInfo: ChargingStationInfo = this.getTemplateFromFile(); if (Utils.isNullOrUndefined(stationInfo)) { - const logMsg = 'Failed to read charging station template file'; - logger.error(`${this.logPrefix()} ${logMsg}`); - throw new BaseError(logMsg); + const errorMsg = 'Failed to read charging station template file'; + logger.error(`${this.logPrefix()} ${errorMsg}`); + throw new BaseError(errorMsg); } if (Utils.isEmptyObject(stationInfo)) { - logger.warn( - `${this.logPrefix()} Empty charging station information from template file ${ - this.templateFile - }` - ); + const errorMsg = `Empty charging station information from template file ${this.templateFile}`; + logger.error(`${this.logPrefix()} ${errorMsg}`); + throw new BaseError(errorMsg); } const chargingStationId = ChargingStationUtils.getChargingStationId(this.index, stationInfo); // Deprecation template keys section @@ -748,7 +745,7 @@ export default class ChargingStation { stationInfo, 'supervisionUrl', this.templateFile, - Utils.logPrefix(` ${chargingStationId} |`), + this.logPrefix(), "Use 'supervisionUrls' instead" ); ChargingStationUtils.convertDeprecatedTemplateKey( @@ -756,7 +753,6 @@ export default class ChargingStation { 'supervisionUrl', 'supervisionUrls' ); - stationInfo.wsOptions = stationInfo?.wsOptions ?? {}; if (!Utils.isEmptyArray(stationInfo.power)) { stationInfo.power = stationInfo.power as number[]; const powerArrayRandomIndex = Math.floor(Utils.secureRandom() * stationInfo.power.length); @@ -780,9 +776,14 @@ export default class ChargingStation { return stationInfo; } - private getStationInfoFromFile(): ChargingStationInfo { - let stationInfo = this.getConfigurationFromFile()?.stationInfo ?? ({} as ChargingStationInfo); - stationInfo = ChargingStationUtils.createStationInfoHash(stationInfo); + private getStationInfoFromFile(): ChargingStationInfo | null { + let stationInfo: ChargingStationInfo = null; + if (this.getStationInfoPersistentConfiguration()) { + stationInfo = this.getConfigurationFromFile()?.stationInfo ?? null; + } + if (stationInfo) { + stationInfo = ChargingStationUtils.createStationInfoHash(stationInfo); + } return stationInfo; } @@ -808,7 +809,9 @@ export default class ChargingStation { } private saveStationInfo(): void { - this.saveConfiguration(Section.stationInfo); + if (this.getStationInfoPersistentConfiguration()) { + this.saveConfiguration(Section.stationInfo); + } } private getOcppVersion(): OCPPVersion { @@ -816,7 +819,11 @@ export default class ChargingStation { } private getOcppPersistentConfiguration(): boolean { - return this.stationInfo.ocppPersistentConfiguration ?? true; + return this.stationInfo?.ocppPersistentConfiguration ?? true; + } + + private getStationInfoPersistentConfiguration(): boolean { + return this.stationInfo?.stationInfoPersistentConfiguration ?? true; } private handleUnsupportedVersion(version: OCPPVersion) { @@ -846,7 +853,7 @@ export default class ChargingStation { if ( maxConnectors > (this.stationInfo?.Connectors[0] ? templateMaxConnectors - 1 : templateMaxConnectors) && - !this.stationInfo.randomConnectors + !this.stationInfo?.randomConnectors ) { logger.warn( `${this.logPrefix()} Number of connectors exceeds the number of connector configurations in template ${ @@ -857,7 +864,9 @@ export default class ChargingStation { } this.initializeConnectors(this.stationInfo, maxConnectors, templateMaxConnectors); this.stationInfo.maximumAmperage = this.getMaximumAmperage(); - this.stationInfo = ChargingStationUtils.createStationInfoHash(this.stationInfo); + if (this.stationInfo) { + this.stationInfo = ChargingStationUtils.createStationInfoHash(this.stationInfo); + } this.saveStationInfo(); // Avoid duplication of connectors related information in RAM this.stationInfo?.Connectors && delete this.stationInfo.Connectors; @@ -1105,7 +1114,7 @@ export default class ChargingStation { // Generate all connectors if ((stationInfo?.Connectors[0] ? templateMaxConnectors - 1 : templateMaxConnectors) > 0) { for (let index = 1; index <= maxConnectors; index++) { - const randConnectorId = stationInfo.randomConnectors + const randConnectorId = stationInfo?.randomConnectors ? Utils.getRandomInteger(Utils.convertToInt(lastConnector), 1) : index; this.connectors.set( @@ -1185,11 +1194,11 @@ export default class ChargingStation { private saveConfiguration(section?: Section): void { if (this.configurationFile) { try { - const configurationData: ChargingStationConfiguration = - this.getConfigurationFromFile() ?? {}; if (!fs.existsSync(path.dirname(this.configurationFile))) { fs.mkdirSync(path.dirname(this.configurationFile), { recursive: true }); } + const configurationData: ChargingStationConfiguration = + this.getConfigurationFromFile() ?? {}; switch (section) { case Section.ocppConfiguration: configurationData.configurationKey = this.ocppConfiguration.configurationKey; @@ -1233,8 +1242,8 @@ export default class ChargingStation { } } - private getOcppConfigurationFromTemplate(): ChargingStationOcppConfiguration { - return this.getTemplateFromFile().Configuration ?? ({} as ChargingStationOcppConfiguration); + private getOcppConfigurationFromTemplate(): ChargingStationOcppConfiguration | null { + return this.getTemplateFromFile()?.Configuration ?? null; } private getOcppConfigurationFromFile(): ChargingStationOcppConfiguration | null { @@ -1247,7 +1256,7 @@ export default class ChargingStation { return configuration; } - private getOcppConfiguration(): ChargingStationOcppConfiguration { + private getOcppConfiguration(): ChargingStationOcppConfiguration | null { let ocppConfiguration: ChargingStationOcppConfiguration = this.getOcppConfigurationFromFile(); if (!ocppConfiguration) { ocppConfiguration = this.getOcppConfigurationFromTemplate(); @@ -1911,7 +1920,7 @@ export default class ChargingStation { } private openWSConnection( - options: WsOptions = this.stationInfo.wsOptions, + options: WsOptions = this.stationInfo?.wsOptions ?? {}, forceCloseOpened = false ): void { options.handshakeTimeout = options?.handshakeTimeout ?? this.getConnectionTimeout() * 1000; @@ -1986,7 +1995,7 @@ export default class ChargingStation { this.autoReconnectRetryCount.toString() ); this.openWSConnection( - { ...this.stationInfo.wsOptions, handshakeTimeout: reconnectTimeout }, + { ...(this.stationInfo?.wsOptions ?? {}), handshakeTimeout: reconnectTimeout }, true ); this.wsConnectionRestarted = true; diff --git a/src/charging-station/ChargingStationUtils.ts b/src/charging-station/ChargingStationUtils.ts index 3e30fabc..afe9a52f 100644 --- a/src/charging-station/ChargingStationUtils.ts +++ b/src/charging-station/ChargingStationUtils.ts @@ -31,7 +31,7 @@ export class ChargingStationUtils { const instanceIndex = process.env.CF_INSTANCE_INDEX ?? 0; const idSuffix = stationTemplate.nameSuffix ?? ''; const idStr = '000000000' + index.toString(); - return stationTemplate.fixedName + return stationTemplate?.fixedName ? stationTemplate.baseName : stationTemplate.baseName + '-' + @@ -158,28 +158,26 @@ export class ChargingStationUtils { } public static createStationInfoHash(stationInfo: ChargingStationInfo): ChargingStationInfo { - if (!Utils.isEmptyObject(stationInfo)) { - const previousInfoHash = stationInfo?.infoHash ?? ''; - delete stationInfo.infoHash; - const currentInfoHash = crypto - .createHash(Constants.DEFAULT_HASH_ALGORITHM) - .update(JSON.stringify(stationInfo)) - .digest('hex'); - if ( - Utils.isEmptyString(previousInfoHash) || - (!Utils.isEmptyString(previousInfoHash) && currentInfoHash !== previousInfoHash) - ) { - stationInfo.infoHash = currentInfoHash; - } else { - stationInfo.infoHash = previousInfoHash; - } + const previousInfoHash = stationInfo?.infoHash ?? ''; + delete stationInfo.infoHash; + const currentInfoHash = crypto + .createHash(Constants.DEFAULT_HASH_ALGORITHM) + .update(JSON.stringify(stationInfo)) + .digest('hex'); + if ( + Utils.isEmptyString(previousInfoHash) || + (!Utils.isEmptyString(previousInfoHash) && currentInfoHash !== previousInfoHash) + ) { + stationInfo.infoHash = currentInfoHash; + } else { + stationInfo.infoHash = previousInfoHash; } return stationInfo; } public static createSerialNumber( stationInfo: ChargingStationInfo, - existingStationInfo?: ChargingStationInfo, + existingStationInfo?: ChargingStationInfo | null, params: { randomSerialNumberUpperCase?: boolean; randomSerialNumber?: boolean } = { randomSerialNumberUpperCase: true, randomSerialNumber: true, @@ -188,7 +186,7 @@ export class ChargingStationUtils { params = params ?? {}; params.randomSerialNumberUpperCase = params?.randomSerialNumberUpperCase ?? true; params.randomSerialNumber = params?.randomSerialNumber ?? true; - if (!Utils.isEmptyObject(existingStationInfo)) { + if (existingStationInfo) { existingStationInfo?.chargePointSerialNumber && (stationInfo.chargePointSerialNumber = existingStationInfo.chargePointSerialNumber); existingStationInfo?.chargeBoxSerialNumber && diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index f51cc655..1e66f4af 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -511,7 +511,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer clearCurrentCP = true; } if (clearCurrentCP) { - connectorStatus.chargingProfiles[index] = {} as OCPP16ChargingProfile; + connectorStatus.chargingProfiles.splice(index, 1); logger.debug( `${chargingStation.logPrefix()} Matching charging profile(s) cleared on connector id ${ commandPayload.connectorId diff --git a/src/types/ChargingStationTemplate.ts b/src/types/ChargingStationTemplate.ts index 789ce248..212cb64e 100644 --- a/src/types/ChargingStationTemplate.ts +++ b/src/types/ChargingStationTemplate.ts @@ -54,6 +54,7 @@ export default interface ChargingStationTemplate { ocppProtocol?: OCPPProtocol; ocppStrictCompliance?: boolean; ocppPersistentConfiguration?: boolean; + stationInfoPersistentConfiguration?: boolean; wsOptions?: WsOptions; authorizationFile?: string; baseName: string; -- 2.34.1