From: Jérôme Benoit Date: Wed, 24 Jul 2024 23:14:16 +0000 (+0200) Subject: refactor: validate station information at CS init X-Git-Tag: ocpp-server@v1.5.0~3 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=b55f94b6ac5dee58f38d13781b4345c4cc43f349;p=e-mobility-charging-stations-simulator.git refactor: validate station information at CS init Signed-off-by: Jérôme Benoit --- diff --git a/src/charging-station/AutomaticTransactionGenerator.ts b/src/charging-station/AutomaticTransactionGenerator.ts index 58956ec8..3cfe3253 100644 --- a/src/charging-station/AutomaticTransactionGenerator.ts +++ b/src/charging-station/AutomaticTransactionGenerator.ts @@ -28,7 +28,7 @@ import { sleep, } from '../utils/index.js' import type { ChargingStation } from './ChargingStation.js' -import { checkChargingStation } from './Helpers.js' +import { checkChargingStationState } from './Helpers.js' import { IdTagsCache } from './IdTagsCache.js' import { isIdTagAuthorized } from './ocpp/index.js' @@ -74,7 +74,7 @@ export class AutomaticTransactionGenerator { } public start (stopAbsoluteDuration?: boolean): void { - if (!checkChargingStation(this.chargingStation, this.logPrefix())) { + if (!checkChargingStationState(this.chargingStation, this.logPrefix())) { return } if (this.started) { @@ -107,7 +107,7 @@ export class AutomaticTransactionGenerator { } public startConnector (connectorId: number, stopAbsoluteDuration?: boolean): void { - if (!checkChargingStation(this.chargingStation, this.logPrefix(connectorId))) { + if (!checkChargingStationState(this.chargingStation, this.logPrefix(connectorId))) { return } if (!this.connectorsStatus.has(connectorId)) { diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 6af98a50..1f35092c 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -111,7 +111,7 @@ import { import { buildConnectorsMap, buildTemplateName, - checkChargingStation, + checkChargingStationState, checkConfiguration, checkConnectorsConfiguration, checkStationInfoConnectorStatus, @@ -136,6 +136,7 @@ import { propagateSerialNumber, setChargingStationOptions, stationTemplateToStationInfo, + validateStationInfo, warnTemplateKeysDeprecation, } from './Helpers.js' import { IdTagsCache } from './IdTagsCache.js' @@ -827,7 +828,7 @@ export class ChargingStation extends EventEmitter { ...options, } params = { ...{ closeOpened: false, terminateOpened: false }, ...params } - if (!checkChargingStation(this, this.logPrefix())) { + if (!checkChargingStationState(this, this.logPrefix())) { return } if (this.stationInfo?.supervisionUser != null && this.stationInfo.supervisionPassword != null) { @@ -1304,6 +1305,7 @@ export class ChargingStation extends EventEmitter { this.initializeConnectorsOrEvsesFromTemplate(stationTemplate) } this.stationInfo = this.getStationInfo(options) + validateStationInfo(this) if ( this.stationInfo.firmwareStatus === FirmwareStatus.Installing && isNotEmptyString(this.stationInfo.firmwareVersionPattern) && diff --git a/src/charging-station/Helpers.ts b/src/charging-station/Helpers.ts index 315a51b9..656e77be 100644 --- a/src/charging-station/Helpers.ts +++ b/src/charging-station/Helpers.ts @@ -175,7 +175,44 @@ export const getHashId = (index: number, stationTemplate: ChargingStationTemplat .digest('hex') } -export const checkChargingStation = ( +export const validateStationInfo = (chargingStation: ChargingStation): void => { + if (isEmpty(chargingStation.stationInfo)) { + throw new BaseError('Missing charging station information') + } + if (isEmpty(chargingStation.stationInfo?.hashId.trim())) { + throw new BaseError('Missing hashId in stationInfo properties') + } + if (isEmpty(chargingStation.stationInfo?.templateIndex)) { + throw new BaseError('Missing templateIndex in stationInfo properties') + } + if (isEmpty(chargingStation.stationInfo?.templateName.trim())) { + throw new BaseError('Missing templateName in stationInfo properties') + } + if (isEmpty(chargingStation.stationInfo?.chargingStationId?.trim())) { + throw new BaseError('Missing chargingStationId in stationInfo properties') + } + if (isEmpty(chargingStation.stationInfo?.maximumPower)) { + throw new BaseError('Missing maximumPower in stationInfo properties') + } + if (chargingStation.stationInfo?.maximumPower != null && chargingStation.stationInfo.maximumPower <= 0) { + throw new RangeError('Invalid maximumPower value in stationInfo properties') + } + if (isEmpty(chargingStation.stationInfo?.maximumAmperage)) { + throw new BaseError('Missing maximumAmperage in stationInfo properties') + } + if (chargingStation.stationInfo?.maximumAmperage != null && chargingStation.stationInfo.maximumAmperage <= 0) { + throw new RangeError('Invalid maximumAmperage value in stationInfo properties') + } + switch (chargingStation.stationInfo?.ocppVersion) { + case OCPPVersion.VERSION_20: + case OCPPVersion.VERSION_201: + if (chargingStation.evses.size === 0) { + throw new BaseError('OCPP 2.0 or superior requires at least one EVSE defined in the charging station template/configuration') + } + } +} + +export const checkChargingStationState = ( chargingStation: ChargingStation, logPrefix: string ): boolean => { diff --git a/src/charging-station/index.ts b/src/charging-station/index.ts index 9d9d44fa..747e42eb 100644 --- a/src/charging-station/index.ts +++ b/src/charging-station/index.ts @@ -7,7 +7,7 @@ export { } from './ConfigurationKeyUtils.js' export { canProceedChargingProfile, - checkChargingStation, + checkChargingStationState, getConnectorChargingProfiles, getIdTagsFile, hasFeatureProfile, diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index d114fe6c..409fbbab 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -21,7 +21,7 @@ import { create } from 'tar' import { canProceedChargingProfile, type ChargingStation, - checkChargingStation, + checkChargingStationState, getConfigurationKey, getConnectorChargingProfiles, prepareChargingProfileKind, @@ -1353,7 +1353,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { maxDelay = 30, minDelay = 15 ): Promise { - if (!checkChargingStation(chargingStation, chargingStation.logPrefix())) { + if (!checkChargingStationState(chargingStation, chargingStation.logPrefix())) { return } if (chargingStation.hasEvses) { @@ -1464,7 +1464,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { } } while (transactionsStarted) !wasTransactionsStarted && (await sleep(secondsToMilliseconds(randomInt(minDelay, maxDelay)))) - if (!checkChargingStation(chargingStation, chargingStation.logPrefix())) { + if (!checkChargingStationState(chargingStation, chargingStation.logPrefix())) { return } await chargingStation.ocppRequestService.requestHandler<