X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Fui-server%2Fui-services%2FAbstractUIService.ts;h=ffdc256583adccd581d72c99496e3bfe726333e2;hb=43c49f23af9869b5a04da7c0e04b11b5243d9e34;hp=de83c6b7e4eb85adaa3e2d5297393482c3d8feb6;hpb=240fa4da80fd262158004eb576410d02afe0001f;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index de83c6b7..ffdc2565 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -2,8 +2,10 @@ import { BaseError, type OCPPError } from '../../../exception/index.js' import { BroadcastChannelProcedureName, type BroadcastChannelRequestPayload, + type ChargingStationInfo, type ChargingStationOptions, ConfigurationSection, + type JsonObject, type JsonType, ProcedureName, type ProtocolRequest, @@ -22,6 +24,12 @@ import type { AbstractUIServer } from '../AbstractUIServer.js' const moduleName = 'AbstractUIService' +interface AddChargingStationsRequestPayload extends RequestPayload { + template: string + numberOfStations: number + options?: ChargingStationOptions +} + export abstract class AbstractUIService { protected static readonly ProcedureNameToBroadCastChannelProcedureNameMapping = new Map< ProcedureName, @@ -66,7 +74,10 @@ export abstract class AbstractUIService { private readonly version: ProtocolVersion private readonly uiServer: AbstractUIServer private readonly uiServiceWorkerBroadcastChannel: UIServiceWorkerBroadcastChannel - private readonly broadcastChannelRequests: Map + private readonly broadcastChannelRequests: Map< + `${string}-${string}-${string}-${string}-${string}`, + number + > constructor (uiServer: AbstractUIServer, version: ProtocolVersion) { this.uiServer = uiServer @@ -81,7 +92,10 @@ export abstract class AbstractUIService { [ProcedureName.STOP_SIMULATOR, this.handleStopSimulator.bind(this)] ]) this.uiServiceWorkerBroadcastChannel = new UIServiceWorkerBroadcastChannel(this) - this.broadcastChannelRequests = new Map() + this.broadcastChannelRequests = new Map< + `${string}-${string}-${string}-${string}-${string}`, + number + >() } public stop (): void { @@ -90,12 +104,12 @@ export abstract class AbstractUIService { } public async requestHandler (request: ProtocolRequest): Promise { - let messageId: string | undefined + let uuid: `${string}-${string}-${string}-${string}-${string}` | undefined let command: ProcedureName | undefined let requestPayload: RequestPayload | undefined let responsePayload: ResponsePayload | undefined try { - [messageId, command, requestPayload] = request + [uuid, command, requestPayload] = request if (!this.requestHandlers.has(command)) { throw new BaseError( @@ -111,7 +125,7 @@ export abstract class AbstractUIService { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const requestHandler = this.requestHandlers.get(command)! if (isAsyncFunction(requestHandler)) { - responsePayload = await requestHandler(messageId, command, requestPayload) + responsePayload = await requestHandler(uuid, command, requestPayload) } else { responsePayload = ( requestHandler as ( @@ -119,7 +133,7 @@ export abstract class AbstractUIService { procedureName?: ProcedureName, payload?: RequestPayload ) => undefined | ResponsePayload - )(messageId, command, requestPayload) + )(uuid, command, requestPayload) } } catch (error) { // Log @@ -137,23 +151,26 @@ export abstract class AbstractUIService { } if (responsePayload != null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return this.uiServer.buildProtocolResponse(messageId!, responsePayload) + return this.uiServer.buildProtocolResponse(uuid!, responsePayload) } } // public sendRequest ( - // messageId: string, + // uuid: `${string}-${string}-${string}-${string}-${string}`, // procedureName: ProcedureName, // requestPayload: RequestPayload // ): void { // this.uiServer.sendRequest( - // this.uiServer.buildProtocolRequest(messageId, procedureName, requestPayload) + // this.uiServer.buildProtocolRequest(uuid, procedureName, requestPayload) // ) // } - public sendResponse (messageId: string, responsePayload: ResponsePayload): void { - if (this.uiServer.hasResponseHandler(messageId)) { - this.uiServer.sendResponse(this.uiServer.buildProtocolResponse(messageId, responsePayload)) + public sendResponse ( + uuid: `${string}-${string}-${string}-${string}-${string}`, + responsePayload: ResponsePayload + ): void { + if (this.uiServer.hasResponseHandler(uuid)) { + this.uiServer.sendResponse(this.uiServer.buildProtocolResponse(uuid, responsePayload)) } } @@ -161,17 +178,21 @@ export abstract class AbstractUIService { return this.uiServer.logPrefix(modName, methodName, this.version) } - public deleteBroadcastChannelRequest (uuid: string): void { + public deleteBroadcastChannelRequest ( + uuid: `${string}-${string}-${string}-${string}-${string}` + ): void { this.broadcastChannelRequests.delete(uuid) } - public getBroadcastChannelExpectedResponses (uuid: string): number { + public getBroadcastChannelExpectedResponses ( + uuid: `${string}-${string}-${string}-${string}-${string}` + ): number { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return this.broadcastChannelRequests.get(uuid)! } protected handleProtocolRequest ( - uuid: string, + uuid: `${string}-${string}-${string}-${string}-${string}`, procedureName: ProcedureName, payload: RequestPayload ): void { @@ -184,7 +205,7 @@ export abstract class AbstractUIService { } private sendBroadcastChannelRequest ( - uuid: string, + uuid: `${string}-${string}-${string}-${string}-${string}`, procedureName: BroadcastChannelProcedureName, payload: BroadcastChannelRequestPayload ): void { @@ -233,14 +254,24 @@ export abstract class AbstractUIService { } private async handleAddChargingStations ( - _messageId?: string, + _uuid?: `${string}-${string}-${string}-${string}-${string}`, _procedureName?: ProcedureName, requestPayload?: RequestPayload ): Promise { - const { template, numberOfStations, options } = requestPayload as { - template: string - numberOfStations: number - options?: ChargingStationOptions + const { template, numberOfStations, options } = + requestPayload as AddChargingStationsRequestPayload + if (!Bootstrap.getInstance().getState().started) { + return { + status: ResponseStatus.FAILURE, + errorMessage: + 'Cannot add charging station(s) while the charging stations simulator is not started' + } satisfies ResponsePayload + } + if (typeof template !== 'string' || typeof numberOfStations !== 'number') { + return { + status: ResponseStatus.FAILURE, + errorMessage: 'Invalid request payload' + } satisfies ResponsePayload } if (!this.uiServer.chargingStationTemplates.has(template)) { return { @@ -248,24 +279,37 @@ export abstract class AbstractUIService { errorMessage: `Template '${template}' not found` } satisfies ResponsePayload } + const succeededStationInfos: ChargingStationInfo[] = [] + const failedStationInfos: ChargingStationInfo[] = [] + let err: Error | undefined for (let i = 0; i < numberOfStations; i++) { + let stationInfo: ChargingStationInfo | undefined try { - await Bootstrap.getInstance().addChargingStation( + stationInfo = await Bootstrap.getInstance().addChargingStation( Bootstrap.getInstance().getLastIndex(template) + 1, `${template}.json`, options ) + if (stationInfo != null) { + succeededStationInfos.push(stationInfo) + } } catch (error) { - return { - status: ResponseStatus.FAILURE, - errorMessage: (error as Error).message, - errorStack: (error as Error).stack - } satisfies ResponsePayload + err = error as Error + if (stationInfo != null) { + failedStationInfos.push(stationInfo) + } } } return { - status: ResponseStatus.SUCCESS - } + status: err != null ? ResponseStatus.FAILURE : ResponseStatus.SUCCESS, + ...(succeededStationInfos.length > 0 && { + hashIdsSucceeded: succeededStationInfos.map(stationInfo => stationInfo.hashId) + }), + ...(failedStationInfos.length > 0 && { + hashIdsFailed: failedStationInfos.map(stationInfo => stationInfo.hashId) + }), + ...(err != null && { errorMessage: err.message, errorStack: err.stack }) + } satisfies ResponsePayload } private handlePerformanceStatistics (): ResponsePayload { @@ -286,7 +330,7 @@ export abstract class AbstractUIService { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ...Bootstrap.getInstance().getPerformanceStatistics()! ] as JsonType[] - } + } satisfies ResponsePayload } catch (error) { return { status: ResponseStatus.FAILURE, @@ -300,7 +344,7 @@ export abstract class AbstractUIService { try { return { status: ResponseStatus.SUCCESS, - state: Bootstrap.getInstance().getState() + state: Bootstrap.getInstance().getState() as unknown as JsonObject } satisfies ResponsePayload } catch (error) { return {