From f49df9875a0bb7f8c378fac6f5360d407db0979a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 9 Nov 2025 17:30:23 +0100 Subject: [PATCH] chore: improve debug level logging in OCPP stack MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../ocpp/1.6/OCPP16RequestService.ts | 128 +++++++++++++----- .../ocpp/1.6/OCPP16ResponseService.ts | 38 +++++- .../ocpp/2.0/OCPP20IncomingRequestService.ts | 21 ++- .../ocpp/2.0/OCPP20RequestService.ts | 78 ++++++++--- .../ocpp/2.0/OCPP20ResponseService.ts | 78 ++++++++++- 5 files changed, 272 insertions(+), 71 deletions(-) diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 1b6ed290..10505ff0 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -17,6 +17,7 @@ import { type OCPP16DiagnosticsStatusNotificationRequest, type OCPP16FirmwareStatusNotificationRequest, type OCPP16HeartbeatRequest, + type OCPP16MeterValue, type OCPP16MeterValuesRequest, OCPP16RequestCommand, type OCPP16StartTransactionRequest, @@ -25,7 +26,7 @@ import { OCPPVersion, type RequestParams, } from '../../../types/index.js' -import { Constants, generateUUID } from '../../../utils/index.js' +import { Constants, generateUUID, logger } from '../../../utils/index.js' import { OCPPRequestService } from '../OCPPRequestService.js' import { OCPP16Constants } from './OCPP16Constants.js' import { OCPP16ServiceUtils } from './OCPP16ServiceUtils.js' @@ -152,33 +153,57 @@ export class OCPP16RequestService extends OCPPRequestService { commandParams?: RequestType, params?: RequestParams ): Promise { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Processing '${commandName}' request` + ) // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc. if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) { - // Pre request actions hook - switch (commandName) { - case OCPP16RequestCommand.START_TRANSACTION: - await OCPP16ServiceUtils.sendAndSetConnectorStatus( - chargingStation, - (commandParams as OCPP16StartTransactionRequest).connectorId, - OCPP16ChargePointStatus.Preparing - ) - break + try { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Building request payload for '${commandName}'` + ) + const requestPayload = this.buildRequestPayload( + chargingStation, + commandName, + commandParams + ) + const messageId = generateUUID() + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Sending '${commandName}' request with message ID '${messageId}'` + ) + // Pre request actions hook + switch (commandName) { + case OCPP16RequestCommand.START_TRANSACTION: + await OCPP16ServiceUtils.sendAndSetConnectorStatus( + chargingStation, + (commandParams as OCPP16StartTransactionRequest).connectorId, + OCPP16ChargePointStatus.Preparing + ) + break + } + const response = (await this.sendMessage( + chargingStation, + messageId, + requestPayload, + commandName, + params + )) as ResponseType + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: '${commandName}' request completed successfully` + ) + return response + } catch (error) { + logger.error( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Error processing '${commandName}' request:`, + error + ) + throw error } - return (await this.sendMessage( - chargingStation, - generateUUID(), - this.buildRequestPayload(chargingStation, commandName, commandParams), - commandName, - params - )) as ResponseType } // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). - throw new OCPPError( - ErrorType.NOT_SUPPORTED, - `Unsupported OCPP command ${commandName}`, - commandName, - commandParams - ) + const errorMsg = `Unsupported OCPP command ${commandName}` + logger.error(`${chargingStation.logPrefix()} ${moduleName}.requestHandler: ${errorMsg}`) + throw new OCPPError(ErrorType.NOT_SUPPORTED, errorMsg, commandName, commandParams) } // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters @@ -192,20 +217,47 @@ export class OCPP16RequestService extends OCPPRequestService { commandParams = commandParams as JsonObject switch (commandName) { case OCPP16RequestCommand.AUTHORIZE: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.AUTHORIZE} payload with default idTag` + ) return { idTag: Constants.DEFAULT_IDTAG, ...commandParams, } as unknown as Request case OCPP16RequestCommand.BOOT_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.BOOT_NOTIFICATION} payload` + ) + return commandParams as unknown as Request case OCPP16RequestCommand.DATA_TRANSFER: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.DATA_TRANSFER} payload` + ) + return commandParams as unknown as Request case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION} payload` + ) + return commandParams as unknown as Request case OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION: - case OCPP16RequestCommand.METER_VALUES: - case OCPP16RequestCommand.STATUS_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION} payload` + ) return commandParams as unknown as Request case OCPP16RequestCommand.HEARTBEAT: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.HEARTBEAT} payload (empty)` + ) return OCPP16Constants.OCPP_REQUEST_EMPTY as unknown as Request + case OCPP16RequestCommand.METER_VALUES: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.METER_VALUES} payload` + ) + return commandParams as unknown as Request case OCPP16RequestCommand.START_TRANSACTION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.START_TRANSACTION} payload with meter start and timestamp` + ) return { idTag: Constants.DEFAULT_IDTAG, meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId( @@ -228,7 +280,15 @@ export class OCPP16RequestService extends OCPPRequestService { }), ...commandParams, } as unknown as Request + case OCPP16RequestCommand.STATUS_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.STATUS_NOTIFICATION} payload` + ) + return commandParams as unknown as Request case OCPP16RequestCommand.STOP_TRANSACTION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP16RequestCommand.STOP_TRANSACTION} payload with meter stop and timestamp` + ) chargingStation.stationInfo?.transactionDataMeterValues === true && (connectorId = chargingStation.getConnectorIdByTransactionId( commandParams.transactionId as number @@ -244,26 +304,26 @@ export class OCPP16RequestService extends OCPPRequestService { ...(chargingStation.stationInfo?.transactionDataMeterValues === true && { transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingStation.getConnectorStatus(connectorId!)!.transactionBeginMeterValue!, + chargingStation.getConnectorStatus(connectorId!)! + .transactionBeginMeterValue! as OCPP16MeterValue, OCPP16ServiceUtils.buildTransactionEndMeterValue( chargingStation, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion connectorId!, energyActiveImportRegister - ) + ) as OCPP16MeterValue ), }), ...commandParams, } as unknown as Request - default: + default: { // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). - throw new OCPPError( - ErrorType.NOT_SUPPORTED, - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - `Unsupported OCPP command ${commandName}`, - commandName, - commandParams + const errorMsg = `Unsupported OCPP command ${commandName as string} for payload building` + logger.error( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: ${errorMsg}` ) + throw new OCPPError(ErrorType.NOT_SUPPORTED, errorMsg, commandName, commandParams) + } } } } diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index b2813fd8..8eb33884 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -33,6 +33,7 @@ import { type OCPP16GetCompositeScheduleResponse, type OCPP16HeartbeatResponse, OCPP16IncomingRequestCommand, + type OCPP16MeterValue, type OCPP16MeterValuesRequest, type OCPP16MeterValuesResponse, OCPP16RequestCommand, @@ -399,6 +400,9 @@ export class OCPP16ResponseService extends OCPPResponseService { ) { try { this.validatePayload(chargingStation, commandName, payload) + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handling '${commandName}' response` + ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const responseHandler = this.responseHandlers.get(commandName)! if (isAsyncFunction(responseHandler)) { @@ -412,9 +416,12 @@ export class OCPP16ResponseService extends OCPPResponseService { ) => void )(chargingStation, payload, requestPayload) } + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: '${commandName}' response processed successfully` + ) } catch (error) { logger.error( - `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`, + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle '${commandName}' response error:`, error ) throw error @@ -510,6 +517,9 @@ export class OCPP16ResponseService extends OCPPResponseService { chargingStation.bootNotificationResponse = payload // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (payload.interval != null) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Setting HeartbeatInterval to ${payload.interval.toString()}s` + ) addConfigurationKey( chargingStation, OCPP16StandardParametersKey.HeartbeatInterval, @@ -526,10 +536,19 @@ export class OCPP16ResponseService extends OCPPResponseService { ) } if (chargingStation.inAcceptedState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.ACCEPTED}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.accepted) } else if (chargingStation.inPendingState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.REJECTED}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.pending) } else if (chargingStation.inRejectedState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.ACCEPTED}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.rejected) } const logMsg = `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Charging station in '${ @@ -787,7 +806,7 @@ export class OCPP16ResponseService extends OCPPResponseService { chargingStation, transactionConnectorId, requestPayload.meterStop - ), + ) as OCPP16MeterValue, ], transactionId: requestPayload.transactionId, })) @@ -844,7 +863,20 @@ export class OCPP16ResponseService extends OCPPResponseService { payload: JsonType ): boolean { if (this.payloadValidateFunctions.has(commandName)) { - return this.validateResponsePayload(chargingStation, commandName, payload) + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: Validating '${commandName}' response payload` + ) + const isValid = this.validateResponsePayload(chargingStation, commandName, payload) + if (!isValid) { + logger.warn( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: '${commandName}' response payload validation failed` + ) + } else { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: '${commandName}' response payload validation successful` + ) + } + return isValid } logger.warn( `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema validation function found for command '${commandName}' PDU validation` diff --git a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts index 0cdfae66..d6330dea 100644 --- a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts @@ -903,7 +903,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { // Validate that EVSE ID is provided if (evseId == null) { const errorMsg = 'EVSE ID is required for RequestStartTransaction' - logger.error( + logger.warn( `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: ${errorMsg}` ) throw new OCPPError( @@ -918,7 +918,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { const evse = chargingStation.evses.get(evseId) if (evse == null) { const errorMsg = `EVSE ${evseId.toString()} does not exist on charging station` - logger.error( + logger.warn( `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: ${errorMsg}` ) throw new OCPPError( @@ -934,7 +934,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { if (connectorStatus == null || connectorId == null) { const errorMsg = `Connector ${connectorId?.toString() ?? 'undefined'} status is undefined` - logger.error( + logger.warn( `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: ${errorMsg}` ) throw new OCPPError( @@ -1039,14 +1039,23 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { try { // Set connector transaction state + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: Setting transaction state for connector ${connectorId.toString()}, transaction ID: ${transactionId}` + ) connectorStatus.transactionStarted = true connectorStatus.transactionId = transactionId connectorStatus.transactionIdTag = idToken.idToken connectorStatus.transactionStart = new Date() connectorStatus.transactionEnergyActiveImportRegisterValue = 0 connectorStatus.remoteStartId = remoteStartId + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: Transaction state set successfully for connector ${connectorId.toString()}` + ) // Update connector status to Occupied + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: Updating connector ${connectorId.toString()} status to Occupied` + ) await sendAndSetConnectorStatus( chargingStation, connectorId, @@ -1065,7 +1074,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { } logger.info( - `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: Remote start transaction accepted on EVSE ${evseId.toString()}, connector ${connectorId.toString()} with transaction ID ${transactionId} for idToken ${idToken.idToken}` + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStartTransaction: Remote start transaction ACCEPTED on #${connectorId.toString()} for idToken '${idToken.idToken}'` ) return { @@ -1122,7 +1131,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { if (stopResponse.status === GenericStatus.Accepted) { logger.info( - `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStopTransaction: Remote stop transaction accepted for transaction ID ${transactionId} on connector ${connectorId.toString()}` + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStopTransaction: Remote stop transaction ACCEPTED for transactionId '${transactionId}'` ) return { status: RequestStartStopStatusEnumType.Accepted, @@ -1130,7 +1139,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { } logger.warn( - `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStopTransaction: Remote stop transaction rejected for transaction ID ${transactionId} on connector ${connectorId.toString()}` + `${chargingStation.logPrefix()} ${moduleName}.handleRequestRequestStopTransaction: Remote stop transaction REJECTED for transactionId '${transactionId}'` ) return { status: RequestStartStopStatusEnumType.Rejected, diff --git a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts index a72b3a01..7d323cd7 100644 --- a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts @@ -18,7 +18,7 @@ import { OCPPVersion, type RequestParams, } from '../../../types/index.js' -import { generateUUID } from '../../../utils/index.js' +import { generateUUID, logger } from '../../../utils/index.js' import { OCPPRequestService } from '../OCPPRequestService.js' import { OCPP20Constants } from './OCPP20Constants.js' import { OCPP20ServiceUtils } from './OCPP20ServiceUtils.js' @@ -85,24 +85,48 @@ export class OCPP20RequestService extends OCPPRequestService { commandParams?: RequestType, params?: RequestParams ): Promise { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Processing '${commandName}' request` + ) // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc. if (OCPP20ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) { - // TODO: pre request actions hook - return (await this.sendMessage( - chargingStation, - generateUUID(), - this.buildRequestPayload(chargingStation, commandName, commandParams), - commandName, - params - )) as ResponseType + try { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Building request payload for '${commandName}'` + ) + const requestPayload = this.buildRequestPayload( + chargingStation, + commandName, + commandParams + ) + const messageId = generateUUID() + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Sending '${commandName}' request with message ID '${messageId}'` + ) + // TODO: pre request actions hook + const response = (await this.sendMessage( + chargingStation, + messageId, + requestPayload, + commandName, + params + )) as ResponseType + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: '${commandName}' request completed successfully` + ) + return response + } catch (error) { + logger.error( + `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Error processing '${commandName}' request:`, + error + ) + throw error + } } // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). - throw new OCPPError( - ErrorType.NOT_SUPPORTED, - `Unsupported OCPP command ${commandName}`, - commandName, - commandParams - ) + const errorMsg = `Unsupported OCPP command ${commandName}` + logger.error(`${chargingStation.logPrefix()} ${moduleName}.requestHandler: ${errorMsg}`) + throw new OCPPError(ErrorType.NOT_SUPPORTED, errorMsg, commandName, commandParams) } // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters @@ -114,26 +138,38 @@ export class OCPP20RequestService extends OCPPRequestService { commandParams = commandParams as JsonObject switch (commandName) { case OCPP20RequestCommand.BOOT_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP20RequestCommand.BOOT_NOTIFICATION} payload` + ) return commandParams as unknown as Request case OCPP20RequestCommand.HEARTBEAT: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP20RequestCommand.HEARTBEAT} payload (empty)` + ) return OCPP20Constants.OCPP_RESPONSE_EMPTY as unknown as Request case OCPP20RequestCommand.NOTIFY_REPORT: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP20RequestCommand.NOTIFY_REPORT} payload` + ) return { ...commandParams, } as unknown as Request case OCPP20RequestCommand.STATUS_NOTIFICATION: + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: Building ${OCPP20RequestCommand.STATUS_NOTIFICATION} payload with timestamp` + ) return { timestamp: new Date(), ...commandParams, } as unknown as Request - default: + default: { // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). - throw new OCPPError( - ErrorType.NOT_SUPPORTED, - `Unsupported OCPP command ${commandName}`, - commandName, - commandParams + const errorMsg = `Unsupported OCPP command ${commandName} for payload building` + logger.error( + `${chargingStation.logPrefix()} ${moduleName}.buildRequestPayload: ${errorMsg}` ) + throw new OCPPError(ErrorType.NOT_SUPPORTED, errorMsg, commandName, commandParams) + } } } } diff --git a/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts b/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts index b74628ff..a0c7c659 100644 --- a/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts @@ -48,9 +48,15 @@ export class OCPP20ResponseService extends OCPPResponseService { OCPP20RequestCommand.BOOT_NOTIFICATION, this.handleResponseBootNotification.bind(this) as ResponseHandler, ], - [OCPP20RequestCommand.HEARTBEAT, this.emptyResponseHandler], - [OCPP20RequestCommand.NOTIFY_REPORT, this.emptyResponseHandler], - [OCPP20RequestCommand.STATUS_NOTIFICATION, this.emptyResponseHandler], + [OCPP20RequestCommand.HEARTBEAT, this.handleResponseHeartbeat.bind(this) as ResponseHandler], + [ + OCPP20RequestCommand.NOTIFY_REPORT, + this.handleResponseNotifyReport.bind(this) as ResponseHandler, + ], + [ + OCPP20RequestCommand.STATUS_NOTIFICATION, + this.handleResponseStatusNotification.bind(this) as ResponseHandler, + ], ]) this.payloadValidateFunctions = new Map>([ [ @@ -162,6 +168,9 @@ export class OCPP20ResponseService extends OCPPResponseService { ) { try { this.validatePayload(chargingStation, commandName, payload) + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handling '${commandName}' response` + ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const responseHandler = this.responseHandlers.get(commandName)! if (isAsyncFunction(responseHandler)) { @@ -175,9 +184,12 @@ export class OCPP20ResponseService extends OCPPResponseService { ) => void )(chargingStation, payload, requestPayload) } + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: '${commandName}' response processed successfully` + ) } catch (error) { logger.error( - `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`, + `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle '${commandName}' response error:`, error ) throw error @@ -217,6 +229,9 @@ export class OCPP20ResponseService extends OCPPResponseService { chargingStation.bootNotificationResponse = payload // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (payload.interval != null) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Setting HeartbeatInterval to ${payload.interval.toString()}s` + ) addConfigurationKey( chargingStation, OCPP20OptionalVariableName.HeartbeatInterval, @@ -226,13 +241,22 @@ export class OCPP20ResponseService extends OCPPResponseService { ) } if (chargingStation.inAcceptedState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.ACCEPTED}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.accepted) } else if (chargingStation.inPendingState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.PENDING}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.pending) } else if (chargingStation.inRejectedState()) { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Emitting '${RegistrationStatusEnumType.REJECTED}' event` + ) chargingStation.emitChargingStationEvent(ChargingStationEvents.rejected) } - const logMsg = `${chargingStation.logPrefix()} Charging station in '${ + const logMsg = `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Charging station in '${ payload.status }' state on the central server` payload.status === RegistrationStatusEnumType.REJECTED @@ -241,19 +265,59 @@ export class OCPP20ResponseService extends OCPPResponseService { } else { delete chargingStation.bootNotificationResponse logger.error( - `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`, + `${chargingStation.logPrefix()} ${moduleName}.handleResponseBootNotification: Charging station boot notification response received: %j with undefined registration status`, payload ) } } + private handleResponseHeartbeat ( + chargingStation: ChargingStation, + payload: OCPP20HeartbeatResponse + ): void { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseHeartbeat: Heartbeat response received at ${payload.currentTime.toISOString()}` + ) + } + + private handleResponseNotifyReport ( + chargingStation: ChargingStation, + payload: OCPP20NotifyReportResponse + ): void { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseNotifyReport: NotifyReport response received successfully` + ) + } + + private handleResponseStatusNotification ( + chargingStation: ChargingStation, + payload: OCPP20StatusNotificationResponse + ): void { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.handleResponseStatusNotification: StatusNotification response received successfully` + ) + } + private validatePayload ( chargingStation: ChargingStation, commandName: OCPP20RequestCommand, payload: JsonType ): boolean { if (this.payloadValidateFunctions.has(commandName)) { - return this.validateResponsePayload(chargingStation, commandName, payload) + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: Validating '${commandName}' response payload` + ) + const isValid = this.validateResponsePayload(chargingStation, commandName, payload) + if (!isValid) { + logger.warn( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: '${commandName}' response payload validation failed` + ) + } else { + logger.debug( + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: '${commandName}' response payload validation successful` + ) + } + return isValid } logger.warn( `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema validation function found for command '${commandName}' PDU validation` -- 2.43.0