X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStationWorkerBroadcastChannel.ts;h=63b261d5db5b7a857686c63ce95f7ed47917f067;hb=edd134392e237a3242dc2093341df70244c51472;hp=154e1afb14bbb8631fdb570c3a95c2888e4516f2;hpb=1984f1944eeb7468c2f3adbf03b83fbc98910dff;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts index 154e1afb..63b261d5 100644 --- a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts @@ -1,31 +1,46 @@ import BaseError from '../exception/BaseError'; import type OCPPError from '../exception/OCPPError'; +import { StandardParametersKey } from '../types/ocpp/Configuration'; import { - HeartbeatRequest, + type BootNotificationRequest, + type DataTransferRequest, + type HeartbeatRequest, + type MeterValuesRequest, RequestCommand, type StatusNotificationRequest, } from '../types/ocpp/Requests'; -import type { HeartbeatResponse, StatusNotificationResponse } from '../types/ocpp/Responses'; +import { + type BootNotificationResponse, + type DataTransferResponse, + DataTransferStatus, + type HeartbeatResponse, + type MeterValuesResponse, + RegistrationStatus, + type StatusNotificationResponse, +} from '../types/ocpp/Responses'; import { AuthorizationStatus, - AuthorizeRequest, - AuthorizeResponse, - StartTransactionRequest, - StartTransactionResponse, - StopTransactionRequest, - StopTransactionResponse, + type AuthorizeRequest, + type AuthorizeResponse, + type StartTransactionRequest, + type StartTransactionResponse, + type StopTransactionRequest, + type StopTransactionResponse, } from '../types/ocpp/Transaction'; +import { ResponseStatus } from '../types/UIProtocol'; import { BroadcastChannelProcedureName, - BroadcastChannelRequest, - BroadcastChannelRequestPayload, - BroadcastChannelResponsePayload, - MessageEvent, + type BroadcastChannelRequest, + type BroadcastChannelRequestPayload, + type BroadcastChannelResponsePayload, + type MessageEvent, } from '../types/WorkerBroadcastChannel'; -import { ResponseStatus } from '../ui/web/src/types/UIProtocol'; +import Constants from '../utils/Constants'; import logger from '../utils/Logger'; import Utils from '../utils/Utils'; import type ChargingStation from './ChargingStation'; +import { ChargingStationConfigurationUtils } from './ChargingStationConfigurationUtils'; +import { OCPP16ServiceUtils } from './ocpp/1.6/OCPP16ServiceUtils'; import WorkerBroadcastChannel from './WorkerBroadcastChannel'; const moduleName = 'ChargingStationWorkerBroadcastChannel'; @@ -34,8 +49,11 @@ type CommandResponse = | StartTransactionResponse | StopTransactionResponse | AuthorizeResponse + | BootNotificationResponse | StatusNotificationResponse - | HeartbeatResponse; + | HeartbeatResponse + | MeterValuesResponse + | DataTransferResponse; type CommandHandler = ( requestPayload?: BroadcastChannelRequestPayload @@ -43,7 +61,6 @@ type CommandHandler = ( export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChannel { private readonly commandHandlers: Map; - private readonly chargingStation: ChargingStation; constructor(chargingStation: ChargingStation) { @@ -62,6 +79,16 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca BroadcastChannelProcedureName.CLOSE_CONNECTION, () => this.chargingStation.closeWSConnection(), ], + [ + BroadcastChannelProcedureName.START_AUTOMATIC_TRANSACTION_GENERATOR, + (requestPayload?: BroadcastChannelRequestPayload) => + this.chargingStation.startAutomaticTransactionGenerator(requestPayload.connectorIds), + ], + [ + BroadcastChannelProcedureName.STOP_AUTOMATIC_TRANSACTION_GENERATOR, + (requestPayload?: BroadcastChannelRequestPayload) => + this.chargingStation.stopAutomaticTransactionGenerator(requestPayload.connectorIds), + ], [ BroadcastChannelProcedureName.START_TRANSACTION, async (requestPayload?: BroadcastChannelRequestPayload) => @@ -77,23 +104,13 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca StopTransactionRequest, StartTransactionResponse >(this.chargingStation, RequestCommand.STOP_TRANSACTION, { - ...requestPayload, meterStop: this.chargingStation.getEnergyActiveImportRegisterByTransactionId( requestPayload.transactionId, true ), + ...requestPayload, }), ], - [ - BroadcastChannelProcedureName.START_AUTOMATIC_TRANSACTION_GENERATOR, - (requestPayload?: BroadcastChannelRequestPayload) => - this.chargingStation.startAutomaticTransactionGenerator(requestPayload.connectorIds), - ], - [ - BroadcastChannelProcedureName.STOP_AUTOMATIC_TRANSACTION_GENERATOR, - (requestPayload?: BroadcastChannelRequestPayload) => - this.chargingStation.stopAutomaticTransactionGenerator(requestPayload.connectorIds), - ], [ BroadcastChannelProcedureName.AUTHORIZE, async (requestPayload?: BroadcastChannelRequestPayload) => @@ -102,6 +119,27 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca AuthorizeResponse >(this.chargingStation, RequestCommand.AUTHORIZE, requestPayload), ], + [ + BroadcastChannelProcedureName.BOOT_NOTIFICATION, + async (requestPayload?: BroadcastChannelRequestPayload) => { + this.chargingStation.bootNotificationResponse = + await this.chargingStation.ocppRequestService.requestHandler< + BootNotificationRequest, + BootNotificationResponse + >( + this.chargingStation, + RequestCommand.BOOT_NOTIFICATION, + { + ...this.chargingStation.bootNotificationRequest, + ...requestPayload, + }, + { + skipBufferingOnError: true, + } + ); + return this.chargingStation.bootNotificationResponse; + }, + ], [ BroadcastChannelProcedureName.STATUS_NOTIFICATION, async (requestPayload?: BroadcastChannelRequestPayload) => @@ -118,6 +156,40 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca HeartbeatResponse >(this.chargingStation, RequestCommand.HEARTBEAT, requestPayload), ], + [ + BroadcastChannelProcedureName.METER_VALUES, + async (requestPayload?: BroadcastChannelRequestPayload) => { + const configuredMeterValueSampleInterval = + ChargingStationConfigurationUtils.getConfigurationKey( + chargingStation, + StandardParametersKey.MeterValueSampleInterval + ); + return this.chargingStation.ocppRequestService.requestHandler< + MeterValuesRequest, + MeterValuesResponse + >(this.chargingStation, RequestCommand.METER_VALUES, { + meterValue: [ + OCPP16ServiceUtils.buildMeterValue( + this.chargingStation, + requestPayload.connectorId, + this.chargingStation.getConnectorStatus(requestPayload.connectorId)?.transactionId, + configuredMeterValueSampleInterval + ? Utils.convertToInt(configuredMeterValueSampleInterval.value) * 1000 + : Constants.DEFAULT_METER_VALUES_INTERVAL + ), + ], + ...requestPayload, + }); + }, + ], + [ + BroadcastChannelProcedureName.DATA_TRANSFER, + async (requestPayload?: BroadcastChannelRequestPayload) => + this.chargingStation.ocppRequestService.requestHandler< + DataTransferRequest, + DataTransferResponse + >(this.chargingStation, RequestCommand.DATA_TRANSFER, requestPayload), + ], ]); this.chargingStation = chargingStation; this.onmessage = this.requestHandler.bind(this) as (message: MessageEvent) => void; @@ -133,7 +205,6 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca return; } const [uuid, command, requestPayload] = validatedMessageEvent.data as BroadcastChannelRequest; - if ( requestPayload?.hashIds !== undefined && requestPayload?.hashIds?.includes(this.chargingStation.stationInfo.hashId) === false @@ -142,11 +213,10 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca } if (requestPayload?.hashId !== undefined) { logger.error( - `${this.chargingStation.logPrefix()} ${moduleName}.requestHandler: 'hashId' field usage in PDU is deprecated, use 'hashIds' instead` + `${this.chargingStation.logPrefix()} ${moduleName}.requestHandler: 'hashId' field usage in PDU is deprecated, use 'hashIds' array instead` ); return; } - let responsePayload: BroadcastChannelResponsePayload; let commandResponse: CommandResponse | void; try { @@ -157,24 +227,11 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca status: ResponseStatus.SUCCESS, }; } else { - const responseStatus = this.commandResponseToResponseStatus( + responsePayload = this.commandResponseToResponsePayload( command, + requestPayload, commandResponse as CommandResponse ); - if (responseStatus === ResponseStatus.SUCCESS) { - responsePayload = { - hashId: this.chargingStation.stationInfo.hashId, - status: responseStatus, - }; - } else { - responsePayload = { - hashId: this.chargingStation.stationInfo.hashId, - status: responseStatus, - command, - requestPayload, - commandResponse: commandResponse as CommandResponse, - }; - } } } catch (error) { logger.error( @@ -191,14 +248,15 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca errorStack: (error as Error).stack, errorDetails: (error as OCPPError).details, }; + } finally { + this.sendResponse([uuid, responsePayload]); } - this.sendResponse([uuid, responsePayload]); } private messageErrorHandler(messageEvent: MessageEvent): void { logger.error( `${this.chargingStation.logPrefix()} ${moduleName}.messageErrorHandler: Error at handling message:`, - { messageEvent } + messageEvent ); } @@ -225,6 +283,27 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca ].includes(command) === false && delete requestPayload.connectorIds; } + private commandResponseToResponsePayload( + command: BroadcastChannelProcedureName, + requestPayload: BroadcastChannelRequestPayload, + commandResponse: CommandResponse + ): BroadcastChannelResponsePayload { + const responseStatus = this.commandResponseToResponseStatus(command, commandResponse); + if (responseStatus === ResponseStatus.SUCCESS) { + return { + hashId: this.chargingStation.stationInfo.hashId, + status: responseStatus, + }; + } + return { + hashId: this.chargingStation.stationInfo.hashId, + status: responseStatus, + command, + requestPayload, + commandResponse, + }; + } + private commandResponseToResponseStatus( command: BroadcastChannelProcedureName, commandResponse: CommandResponse @@ -244,7 +323,18 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca return ResponseStatus.SUCCESS; } return ResponseStatus.FAILURE; + case BroadcastChannelProcedureName.BOOT_NOTIFICATION: + if (commandResponse?.status === RegistrationStatus.ACCEPTED) { + return ResponseStatus.SUCCESS; + } + return ResponseStatus.FAILURE; + case BroadcastChannelProcedureName.DATA_TRANSFER: + if (commandResponse?.status === DataTransferStatus.ACCEPTED) { + return ResponseStatus.SUCCESS; + } + return ResponseStatus.FAILURE; case BroadcastChannelProcedureName.STATUS_NOTIFICATION: + case BroadcastChannelProcedureName.METER_VALUES: if (Utils.isEmptyObject(commandResponse) === true) { return ResponseStatus.SUCCESS; }