X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStation.ts;h=ecd858c9a78e676b2aa0e9990d9359d593144899;hb=a9671b9e315a2807c2659fdda962203229d35c0a;hp=3c596bb9a1642bb34a2e627110c9f97a197bcc78;hpb=52c58949d4e4ba9d0346de01f129d86e0a446bdd;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 3c596bb9..ecd858c9 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -1,66 +1,16 @@ // Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved. -import { createHash } from 'node:crypto' +import { createHash, randomInt } from 'node:crypto' import { EventEmitter } from 'node:events' -import { type FSWatcher, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' -import { dirname, join, parse } from 'node:path' +import { existsSync, type FSWatcher, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { dirname, join } from 'node:path' import { URL } from 'node:url' import { parentPort } from 'node:worker_threads' import { millisecondsToSeconds, secondsToMilliseconds } from 'date-fns' -import merge from 'just-merge' +import { mergeDeepRight, once } from 'rambda' import { type RawData, WebSocket } from 'ws' -import { AutomaticTransactionGenerator } from './AutomaticTransactionGenerator.js' -import { ChargingStationWorkerBroadcastChannel } from './broadcast-channel/ChargingStationWorkerBroadcastChannel.js' -import { - addConfigurationKey, - deleteConfigurationKey, - getConfigurationKey, - setConfigurationKeyValue -} from './ConfigurationKeyUtils.js' -import { - buildConnectorsMap, - checkChargingStation, - checkConfiguration, - checkConnectorsConfiguration, - checkStationInfoConnectorStatus, - checkTemplate, - createBootNotificationRequest, - createSerialNumber, - getAmperageLimitationUnitDivider, - getBootConnectorStatus, - getChargingStationConnectorChargingProfilesPowerLimit, - getChargingStationId, - getDefaultVoltageOut, - getHashId, - getIdTagsFile, - getMaxNumberOfEvses, - getNumberOfReservableConnectors, - getPhaseRotationValue, - hasFeatureProfile, - hasReservationExpired, - initializeConnectorsMapStatus, - propagateSerialNumber, - stationTemplateToStationInfo, - warnTemplateKeysDeprecation -} from './Helpers.js' -import { IdTagsCache } from './IdTagsCache.js' -import { - OCPP16IncomingRequestService, - OCPP16RequestService, - OCPP16ResponseService, - OCPP20IncomingRequestService, - OCPP20RequestService, - OCPP20ResponseService, - type OCPPIncomingRequestService, - type OCPPRequestService, - buildMeterValue, - buildTransactionEndMeterValue, - getMessageTypeString, - sendAndSetConnectorStatus -} from './ocpp/index.js' -import { SharedLRUCache } from './SharedLRUCache.js' import { BaseError, OCPPError } from '../exception/index.js' import { PerformanceStatistics } from '../performance/index.js' import { @@ -87,7 +37,6 @@ import { FirmwareStatus, type FirmwareStatusNotificationRequest, type FirmwareStatusNotificationResponse, - type FirmwareUpgrade, type HeartbeatRequest, type HeartbeatResponse, type IncomingRequest, @@ -113,45 +62,96 @@ import { SupervisionUrlDistribution, SupportedFeatureProfiles, type Voltage, - type WSError, WebSocketCloseEventStatusCode, + type WSError, type WsOptions } from '../types/index.js' import { ACElectricUtils, AsyncLock, AsyncLockType, - Configuration, - Constants, - DCElectricUtils, buildAddedMessage, buildChargingStationAutomaticTransactionGeneratorConfiguration, buildConnectorsStatus, + buildDeletedMessage, buildEvsesStatus, buildStartedMessage, buildStoppedMessage, buildUpdatedMessage, clone, + Configuration, + Constants, convertToBoolean, convertToDate, convertToInt, + DCElectricUtils, exponentialDelay, formatDurationMilliSeconds, formatDurationSeconds, - getRandomInteger, getWebSocketCloseEventStatusString, handleFileException, isNotEmptyArray, isNotEmptyString, - logPrefix, logger, + logPrefix, min, - once, roundTo, secureRandom, sleep, watchJsonFile } from '../utils/index.js' +import { AutomaticTransactionGenerator } from './AutomaticTransactionGenerator.js' +import { ChargingStationWorkerBroadcastChannel } from './broadcast-channel/ChargingStationWorkerBroadcastChannel.js' +import { + addConfigurationKey, + deleteConfigurationKey, + getConfigurationKey, + setConfigurationKeyValue +} from './ConfigurationKeyUtils.js' +import { + buildConnectorsMap, + buildTemplateName, + checkChargingStation, + checkConfiguration, + checkConnectorsConfiguration, + checkStationInfoConnectorStatus, + checkTemplate, + createBootNotificationRequest, + createSerialNumber, + getAmperageLimitationUnitDivider, + getBootConnectorStatus, + getChargingStationConnectorChargingProfilesPowerLimit, + getChargingStationId, + getDefaultVoltageOut, + getHashId, + getIdTagsFile, + getMaxNumberOfEvses, + getNumberOfReservableConnectors, + getPhaseRotationValue, + hasFeatureProfile, + hasReservationExpired, + initializeConnectorsMapStatus, + propagateSerialNumber, + setChargingStationOptions, + stationTemplateToStationInfo, + warnTemplateKeysDeprecation +} from './Helpers.js' +import { IdTagsCache } from './IdTagsCache.js' +import { + buildMeterValue, + buildTransactionEndMeterValue, + getMessageTypeString, + OCPP16IncomingRequestService, + OCPP16RequestService, + OCPP16ResponseService, + OCPP20IncomingRequestService, + OCPP20RequestService, + OCPP20ResponseService, + type OCPPIncomingRequestService, + type OCPPRequestService, + sendAndSetConnectorStatus +} from './ocpp/index.js' +import { SharedLRUCache } from './SharedLRUCache.js' export class ChargingStation extends EventEmitter { public readonly index: number @@ -160,13 +160,13 @@ export class ChargingStation extends EventEmitter { public started: boolean public starting: boolean public idTagsCache: IdTagsCache - public automaticTransactionGenerator!: AutomaticTransactionGenerator | undefined - public ocppConfiguration!: ChargingStationOcppConfiguration | undefined + public automaticTransactionGenerator?: AutomaticTransactionGenerator + public ocppConfiguration?: ChargingStationOcppConfiguration public wsConnection: WebSocket | null public readonly connectors: Map public readonly evses: Map public readonly requests: Map - public performanceStatistics!: PerformanceStatistics | undefined + public performanceStatistics?: PerformanceStatistics public heartbeatSetInterval?: NodeJS.Timeout public ocppRequestService!: OCPPRequestService public bootNotificationRequest?: BootNotificationRequest @@ -183,7 +183,7 @@ export class ChargingStation extends EventEmitter { private configuredSupervisionUrl!: URL private wsConnectionRetried: boolean private wsConnectionRetryCount: number - private templateFileWatcher!: FSWatcher | undefined + private templateFileWatcher?: FSWatcher private templateFileHash!: string private readonly sharedLRUCache: SharedLRUCache private wsPingSetInterval?: NodeJS.Timeout @@ -211,6 +211,9 @@ export class ChargingStation extends EventEmitter { this.on(ChargingStationEvents.added, () => { parentPort?.postMessage(buildAddedMessage(this)) }) + this.on(ChargingStationEvents.deleted, () => { + parentPort?.postMessage(buildDeletedMessage(this)) + }) this.on(ChargingStationEvents.started, () => { parentPort?.postMessage(buildStartedMessage(this)) }) @@ -225,7 +228,7 @@ export class ChargingStation extends EventEmitter { this.wsConnectionRetried ? true : this.getAutomaticTransactionGeneratorConfiguration()?.stopAbsoluteDuration - ).catch(error => { + ).catch((error: unknown) => { logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error) }) this.wsConnectionRetried = false @@ -248,11 +251,6 @@ export class ChargingStation extends EventEmitter { this.add() - if (options?.autoStart != null) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.stationInfo!.autoStart = options.autoStart - } - if (this.stationInfo?.autoStart === true) { this.start() } @@ -288,7 +286,7 @@ export class ChargingStation extends EventEmitter { readFileSync(this.templateFile, 'utf8') ) as ChargingStationTemplate } catch { - stationTemplate = undefined + // Ignore } return logPrefix(` ${getChargingStationId(this.index, stationTemplate)} |`) } @@ -544,8 +542,8 @@ export class ChargingStation extends EventEmitter { } else { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.stationInfo!.supervisionUrls = url - this.saveStationInfo() this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl() + this.saveStationInfo() } } @@ -554,7 +552,7 @@ export class ChargingStation extends EventEmitter { this.heartbeatSetInterval = setInterval(() => { this.ocppRequestService .requestHandler(this, RequestCommand.HEARTBEAT) - .catch(error => { + .catch((error: unknown) => { logger.error( `${this.logPrefix()} Error while sending '${RequestCommand.HEARTBEAT}':`, error @@ -639,7 +637,7 @@ export class ChargingStation extends EventEmitter { meterValue: [meterValue] } ) - .catch(error => { + .catch((error: unknown) => { logger.error( `${this.logPrefix()} Error while sending '${RequestCommand.METER_VALUES}':`, error @@ -666,6 +664,24 @@ export class ChargingStation extends EventEmitter { this.emit(ChargingStationEvents.added) } + public async delete (deleteConfiguration = true): Promise { + if (this.started) { + await this.stop() + } + AutomaticTransactionGenerator.deleteInstance(this) + PerformanceStatistics.deleteInstance(this.stationInfo?.hashId) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo!)!) + this.requests.clear() + this.connectors.clear() + this.evses.clear() + this.templateFileWatcher?.unref() + deleteConfiguration && rmSync(this.configurationFile, { force: true }) + this.chargingStationWorkerBroadcastChannel.unref() + this.emit(ChargingStationEvents.deleted) + this.removeAllListeners() + } + public start (): void { if (!this.started) { if (!this.starting) { @@ -689,10 +705,10 @@ export class ChargingStation extends EventEmitter { } file have changed, reload` ) this.sharedLRUCache.deleteChargingStationTemplate(this.templateFileHash) - // Initialize - this.initialize() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo!)!) + // Initialize + this.initialize() // Restart the ATG const ATGStarted = this.automaticTransactionGenerator?.started if (ATGStarted === true) { @@ -743,12 +759,11 @@ export class ChargingStation extends EventEmitter { if (this.stationInfo?.enableStatistics === true) { this.performanceStatistics?.stop() } - this.sharedLRUCache.deleteChargingStationConfiguration(this.configurationFileHash) this.templateFileWatcher?.close() - this.sharedLRUCache.deleteChargingStationTemplate(this.templateFileHash) delete this.bootNotificationResponse this.started = false this.saveConfiguration() + this.sharedLRUCache.deleteChargingStationConfiguration(this.configurationFileHash) this.emit(ChargingStationEvents.stopped) this.stopping = false } else { @@ -826,7 +841,7 @@ export class ChargingStation extends EventEmitter { this.wsConnection.on('close', this.onClose.bind(this)) // Handle WebSocket open this.wsConnection.on('open', () => { - this.onOpen().catch(error => + this.onOpen().catch((error: unknown) => logger.error(`${this.logPrefix()} Error while opening WebSocket connection:`, error) ) }) @@ -1016,15 +1031,14 @@ export class ChargingStation extends EventEmitter { connectorId?: number ): boolean { const reservation = this.getReservationBy('reservationId', reservationId) - const reservationExists = reservation !== undefined && !hasReservationExpired(reservation) + const reservationExists = reservation != null && !hasReservationExpired(reservation) if (arguments.length === 1) { return !reservationExists } else if (arguments.length > 1) { - const userReservation = - idTag !== undefined ? this.getReservationBy('idTag', idTag) : undefined + const userReservation = idTag != null ? this.getReservationBy('idTag', idTag) : undefined const userReservationExists = - userReservation !== undefined && !hasReservationExpired(userReservation) - const notConnectorZero = connectorId === undefined ? true : connectorId > 0 + userReservation != null && !hasReservationExpired(userReservation) + const notConnectorZero = connectorId == null ? true : connectorId > 0 const freeConnectorsAvailable = this.getNumberOfReservableConnectors() > 0 return ( !reservationExists && !userReservationExists && notConnectorZero && freeConnectorsAvailable @@ -1140,17 +1154,16 @@ export class ChargingStation extends EventEmitter { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const stationTemplate = this.getTemplateFromFile()! checkTemplate(stationTemplate, this.logPrefix(), this.templateFile) - const warnTemplateKeysDeprecationOnce = once(warnTemplateKeysDeprecation, this) + const warnTemplateKeysDeprecationOnce = once(warnTemplateKeysDeprecation) warnTemplateKeysDeprecationOnce(stationTemplate, this.logPrefix(), this.templateFile) if (stationTemplate.Connectors != null) { checkConnectorsConfiguration(stationTemplate, this.logPrefix(), this.templateFile) } const stationInfo = stationTemplateToStationInfo(stationTemplate) stationInfo.hashId = getHashId(this.index, stationTemplate) - stationInfo.autoStart = stationTemplate.autoStart ?? true - stationInfo.templateName = parse(this.templateFile).name + stationInfo.templateIndex = this.index + stationInfo.templateName = buildTemplateName(this.templateFile) stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate) - stationInfo.ocppVersion = stationTemplate.ocppVersion ?? OCPPVersion.VERSION_16 createSerialNumber(stationTemplate, stationInfo) stationInfo.voltageOut = this.getVoltageOut(stationInfo) if (isNotEmptyArray(stationTemplate.power)) { @@ -1167,9 +1180,8 @@ export class ChargingStation extends EventEmitter { : stationTemplate.power } stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo) - stationInfo.firmwareVersionPattern = - stationTemplate.firmwareVersionPattern ?? Constants.SEMVER_PATTERN if ( + isNotEmptyString(stationInfo.firmwareVersionPattern) && isNotEmptyString(stationInfo.firmwareVersion) && !new RegExp(stationInfo.firmwareVersionPattern).test(stationInfo.firmwareVersion) ) { @@ -1179,50 +1191,43 @@ export class ChargingStation extends EventEmitter { } does not match firmware version pattern '${stationInfo.firmwareVersionPattern}'` ) } - stationInfo.firmwareUpgrade = merge( - { - versionUpgrade: { - step: 1 - }, - reset: true - }, - stationTemplate.firmwareUpgrade ?? {} - ) - stationInfo.resetTime = - stationTemplate.resetTime != null - ? secondsToMilliseconds(stationTemplate.resetTime) - : Constants.DEFAULT_CHARGING_STATION_RESET_TIME + if (stationTemplate.resetTime != null) { + stationInfo.resetTime = secondsToMilliseconds(stationTemplate.resetTime) + } return stationInfo } private getStationInfoFromFile ( - stationInfoPersistentConfiguration?: boolean + stationInfoPersistentConfiguration: boolean | undefined = Constants.DEFAULT_STATION_INFO + .stationInfoPersistentConfiguration ): ChargingStationInfo | undefined { let stationInfo: ChargingStationInfo | undefined if (stationInfoPersistentConfiguration === true) { stationInfo = this.getConfigurationFromFile()?.stationInfo if (stationInfo != null) { delete stationInfo.infoHash + delete (stationInfo as ChargingStationTemplate).numberOfConnectors // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (stationInfo.templateName == null) { - stationInfo.templateName = parse(this.templateFile).name + if (stationInfo.templateIndex == null) { + stationInfo.templateIndex = this.index } - if (stationInfo.autoStart == null) { - stationInfo.autoStart = true + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (stationInfo.templateName == null) { + stationInfo.templateName = buildTemplateName(this.templateFile) } } } return stationInfo } - private getStationInfo (stationInfoPersistentConfiguration?: boolean): ChargingStationInfo { + private getStationInfo (options?: ChargingStationOptions): ChargingStationInfo { const stationInfoFromTemplate = this.getStationInfoFromTemplate() - stationInfoPersistentConfiguration != null && - (stationInfoFromTemplate.stationInfoPersistentConfiguration = - stationInfoPersistentConfiguration) + options?.persistentConfiguration != null && + (stationInfoFromTemplate.stationInfoPersistentConfiguration = options.persistentConfiguration) const stationInfoFromFile = this.getStationInfoFromFile( stationInfoFromTemplate.stationInfoPersistentConfiguration ) + let stationInfo: ChargingStationInfo // Priority: // 1. charging station info from template // 2. charging station info from configuration file @@ -1230,15 +1235,16 @@ export class ChargingStation extends EventEmitter { stationInfoFromFile != null && stationInfoFromFile.templateHash === stationInfoFromTemplate.templateHash ) { - return { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromFile } + stationInfo = stationInfoFromFile + } else { + stationInfo = stationInfoFromTemplate + stationInfoFromFile != null && + propagateSerialNumber(this.getTemplateFromFile(), stationInfoFromFile, stationInfo) } - stationInfoFromFile != null && - propagateSerialNumber( - this.getTemplateFromFile(), - stationInfoFromFile, - stationInfoFromTemplate - ) - return { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromTemplate } + return setChargingStationOptions( + mergeDeepRight(Constants.DEFAULT_STATION_INFO, stationInfo), + options + ) } private saveStationInfo (): void { @@ -1271,21 +1277,11 @@ export class ChargingStation extends EventEmitter { } else { this.initializeConnectorsOrEvsesFromTemplate(stationTemplate) } - this.stationInfo = this.getStationInfo(options?.persistentConfiguration) - if (options?.persistentConfiguration != null) { - this.stationInfo.ocppPersistentConfiguration = options.persistentConfiguration - } - if (options?.persistentConfiguration != null) { - this.stationInfo.automaticTransactionGeneratorPersistentConfiguration = - options.persistentConfiguration - } - if (options?.autoRegister != null) { - this.stationInfo.autoRegister = options.autoRegister - } + this.stationInfo = this.getStationInfo(options) if ( this.stationInfo.firmwareStatus === FirmwareStatus.Installing && - isNotEmptyString(this.stationInfo.firmwareVersion) && - isNotEmptyString(this.stationInfo.firmwareVersionPattern) + isNotEmptyString(this.stationInfo.firmwareVersionPattern) && + isNotEmptyString(this.stationInfo.firmwareVersion) ) { const patternGroup = this.stationInfo.firmwareUpgrade?.versionUpgrade?.patternGroup ?? @@ -1544,7 +1540,7 @@ export class ChargingStation extends EventEmitter { } const templateConnectorId = connectorId > 0 && stationTemplate.randomConnectors === true - ? getRandomInteger(templateMaxAvailableConnectors, 1) + ? randomInt(1, templateMaxAvailableConnectors) : connectorId const connectorStatus = stationTemplate.Connectors[templateConnectorId] checkStationInfoConnectorStatus( @@ -1712,14 +1708,11 @@ export class ChargingStation extends EventEmitter { } else { delete configurationData.configurationKey } - configurationData = merge( + configurationData = mergeDeepRight( configurationData, buildChargingStationAutomaticTransactionGeneratorConfiguration(this) ) - if ( - this.stationInfo?.automaticTransactionGeneratorPersistentConfiguration !== true || - this.getAutomaticTransactionGeneratorConfiguration() == null - ) { + if (this.stationInfo?.automaticTransactionGeneratorPersistentConfiguration !== true) { delete configurationData.automaticTransactionGenerator } if (this.connectors.size > 0) { @@ -1760,7 +1753,7 @@ export class ChargingStation extends EventEmitter { this.sharedLRUCache.deleteChargingStationConfiguration(this.configurationFileHash) this.sharedLRUCache.setChargingStationConfiguration(configurationData) this.configurationFileHash = configurationHash - }).catch(error => { + }).catch((error: unknown) => { handleFileException( this.configurationFile, FileType.ChargingStationConfiguration, @@ -1817,6 +1810,7 @@ export class ChargingStation extends EventEmitter { private async onOpen (): Promise { if (this.isWebSocketConnectionOpened()) { + this.emit(ChargingStationEvents.updated) logger.info( `${this.logPrefix()} Connection to OCPP server through ${this.wsConnectionUrl.href} succeeded` ) @@ -1879,6 +1873,7 @@ export class ChargingStation extends EventEmitter { private onClose (code: WebSocketCloseEventStatusCode, reason: Buffer): void { this.emit(ChargingStationEvents.disconnected) + this.emit(ChargingStationEvents.updated) switch (code) { // Normal close case WebSocketCloseEventStatusCode.CLOSE_NORMAL: @@ -1898,12 +1893,15 @@ export class ChargingStation extends EventEmitter { )}' and reason '${reason.toString()}'` ) this.started && - this.reconnect().catch(error => - logger.error(`${this.logPrefix()} Error while reconnecting:`, error) - ) + this.reconnect() + .then(() => { + this.emit(ChargingStationEvents.updated) + }) + .catch((error: unknown) => + logger.error(`${this.logPrefix()} Error while reconnecting:`, error) + ) break } - this.emit(ChargingStationEvents.updated) } private getCachedRequest ( @@ -2061,7 +2059,7 @@ export class ChargingStation extends EventEmitter { if (!(error instanceof OCPPError)) { logger.warn( `${this.logPrefix()} Error thrown at incoming OCPP command '${ - commandName ?? requestCommandName ?? Constants.UNKNOWN_COMMAND + commandName ?? requestCommandName ?? Constants.UNKNOWN_OCPP_COMMAND // eslint-disable-next-line @typescript-eslint/no-base-to-string }' message '${data.toString()}' handling is not an OCPPError:`, error @@ -2069,7 +2067,7 @@ export class ChargingStation extends EventEmitter { } logger.error( `${this.logPrefix()} Incoming OCPP command '${ - commandName ?? requestCommandName ?? Constants.UNKNOWN_COMMAND + commandName ?? requestCommandName ?? Constants.UNKNOWN_OCPP_COMMAND // eslint-disable-next-line @typescript-eslint/no-base-to-string }' message '${data.toString()}'${ this.requests.has(messageId) @@ -2117,7 +2115,8 @@ export class ChargingStation extends EventEmitter { } private getUseConnectorId0 (stationTemplate?: ChargingStationTemplate): boolean { - return stationTemplate?.useConnectorId0 ?? true + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return stationTemplate?.useConnectorId0 ?? Constants.DEFAULT_STATION_INFO.useConnectorId0! } private async stopRunningTransactions (reason?: StopTransactionReason): Promise { @@ -2176,8 +2175,12 @@ export class ChargingStation extends EventEmitter { } private getCurrentOutType (stationInfo?: ChargingStationInfo): CurrentType { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return (stationInfo ?? this.stationInfo!).currentOutType ?? CurrentType.AC + return ( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + (stationInfo ?? this.stationInfo!).currentOutType ?? + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + Constants.DEFAULT_STATION_INFO.currentOutType! + ) } private getVoltageOut (stationInfo?: ChargingStationInfo): Voltage { @@ -2218,21 +2221,28 @@ export class ChargingStation extends EventEmitter { for (const [evseId, evseStatus] of this.evses) { if (evseId > 0) { for (const [connectorId, connectorStatus] of evseStatus.connectors) { - const connectorBootStatus = getBootConnectorStatus(this, connectorId, connectorStatus) - await sendAndSetConnectorStatus(this, connectorId, connectorBootStatus, evseId) + await sendAndSetConnectorStatus( + this, + connectorId, + getBootConnectorStatus(this, connectorId, connectorStatus), + evseId + ) } } } } else { for (const connectorId of this.connectors.keys()) { if (connectorId > 0) { - const connectorBootStatus = getBootConnectorStatus( + await sendAndSetConnectorStatus( this, connectorId, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.getConnectorStatus(connectorId)! + getBootConnectorStatus( + this, + connectorId, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.getConnectorStatus(connectorId)! + ) ) - await sendAndSetConnectorStatus(this, connectorId, connectorBootStatus) } } } @@ -2349,11 +2359,11 @@ export class ChargingStation extends EventEmitter { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion Configuration.getSupervisionUrlDistribution()! ) && - logger.error( + logger.warn( // eslint-disable-next-line @typescript-eslint/no-base-to-string - `${this.logPrefix()} Unknown supervision url distribution '${Configuration.getSupervisionUrlDistribution()}' from values '${SupervisionUrlDistribution.toString()}', defaulting to ${ + `${this.logPrefix()} Unknown supervision url distribution '${Configuration.getSupervisionUrlDistribution()}' in configuration from values '${SupervisionUrlDistribution.toString()}', defaulting to '${ SupervisionUrlDistribution.CHARGING_STATION_AFFINITY - }` + }'` ) configuredSupervisionUrlIndex = (this.index - 1) % supervisionUrls.length break