X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcharging-station%2FChargingStation.ts;h=82fba5adad98c6629a6579b8e7c8516df38bb7bb;hb=d990f4bc8ad5366a200fd3d89be76c084fd71cea;hp=2b5b5f8376fca34c915965ab1b0d46df590ef6ad;hpb=09e5a7a8ed45886b6bf1434c4e49c945ded4c7d8;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 2b5b5f83..82fba5ad 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -8,7 +8,7 @@ import { URL } from 'node:url' import { parentPort } from 'node:worker_threads' import { millisecondsToSeconds, secondsToMilliseconds } from 'date-fns' -import merge from 'just-merge' +import { mergeDeepRight } from 'rambda' import { type RawData, WebSocket } from 'ws' import { AutomaticTransactionGenerator } from './AutomaticTransactionGenerator.js' @@ -42,6 +42,7 @@ import { hasReservationExpired, initializeConnectorsMapStatus, propagateSerialNumber, + setChargingStationOptions, stationTemplateToStationInfo, warnTemplateKeysDeprecation } from './Helpers.js' @@ -87,7 +88,6 @@ import { FirmwareStatus, type FirmwareStatusNotificationRequest, type FirmwareStatusNotificationResponse, - type FirmwareUpgrade, type HeartbeatRequest, type HeartbeatResponse, type IncomingRequest, @@ -161,13 +161,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 @@ -184,7 +184,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 @@ -252,11 +252,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() } @@ -548,8 +543,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() } } @@ -685,6 +680,7 @@ export class ChargingStation extends EventEmitter { deleteConfiguration && rmSync(this.configurationFile, { force: true }) this.chargingStationWorkerBroadcastChannel.unref() this.emit(ChargingStationEvents.deleted) + this.removeAllListeners() } public start (): void { @@ -1036,15 +1032,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 @@ -1167,6 +1162,7 @@ export class ChargingStation extends EventEmitter { } const stationInfo = stationTemplateToStationInfo(stationTemplate) stationInfo.hashId = getHashId(this.index, stationTemplate) + stationInfo.templateIndex = this.index stationInfo.templateName = parse(this.templateFile).name stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate) createSerialNumber(stationTemplate, stationInfo) @@ -1196,7 +1192,7 @@ export class ChargingStation extends EventEmitter { } does not match firmware version pattern '${stationInfo.firmwareVersionPattern}'` ) } - stationInfo.firmwareUpgrade = merge( + stationInfo.firmwareUpgrade = mergeDeepRight( { versionUpgrade: { step: 1 @@ -1220,6 +1216,11 @@ export class ChargingStation extends EventEmitter { 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.templateIndex == null) { + stationInfo.templateIndex = this.index + } // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (stationInfo.templateName == null) { stationInfo.templateName = parse(this.templateFile).name @@ -1229,11 +1230,10 @@ export class ChargingStation extends EventEmitter { 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 ) @@ -1244,7 +1244,10 @@ export class ChargingStation extends EventEmitter { stationInfoFromFile != null && stationInfoFromFile.templateHash === stationInfoFromTemplate.templateHash ) { - return { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromFile } + return setChargingStationOptions( + { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromFile }, + options + ) } stationInfoFromFile != null && propagateSerialNumber( @@ -1252,7 +1255,10 @@ export class ChargingStation extends EventEmitter { stationInfoFromFile, stationInfoFromTemplate ) - return { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromTemplate } + return setChargingStationOptions( + { ...Constants.DEFAULT_STATION_INFO, ...stationInfoFromTemplate }, + options + ) } private saveStationInfo (): void { @@ -1285,24 +1291,7 @@ export class ChargingStation extends EventEmitter { } else { this.initializeConnectorsOrEvsesFromTemplate(stationTemplate) } - this.stationInfo = this.getStationInfo(options?.persistentConfiguration) - if (options?.persistentConfiguration != null) { - this.stationInfo.ocppPersistentConfiguration = options.persistentConfiguration - this.stationInfo.automaticTransactionGeneratorPersistentConfiguration = - options.persistentConfiguration - } - if (options?.autoRegister != null) { - this.stationInfo.autoRegister = options.autoRegister - } - if (options?.enableStatistics != null) { - this.stationInfo.enableStatistics = options.enableStatistics - } - if (options?.ocppStrictCompliance != null) { - this.stationInfo.ocppStrictCompliance = options.ocppStrictCompliance - } - if (options?.stopTransactionsOnStopped != null) { - this.stationInfo.stopTransactionsOnStopped = options.stopTransactionsOnStopped - } + this.stationInfo = this.getStationInfo(options) if ( this.stationInfo.firmwareStatus === FirmwareStatus.Installing && isNotEmptyString(this.stationInfo.firmwareVersionPattern) && @@ -1733,7 +1722,7 @@ export class ChargingStation extends EventEmitter { } else { delete configurationData.configurationKey } - configurationData = merge( + configurationData = mergeDeepRight( configurationData, buildChargingStationAutomaticTransactionGeneratorConfiguration(this) ) @@ -1835,6 +1824,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` ) @@ -1897,6 +1887,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: @@ -1916,12 +1907,13 @@ 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 => logger.error(`${this.logPrefix()} Error while reconnecting:`, error)) break } - this.emit(ChargingStationEvents.updated) } private getCachedRequest (