]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
chore: improve debug level logging in OCPP stack feat/request-stop-transaction
authorJérôme Benoit <jerome.benoit@sap.com>
Sun, 9 Nov 2025 16:30:23 +0000 (17:30 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sun, 9 Nov 2025 16:30:23 +0000 (17:30 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ocpp/1.6/OCPP16RequestService.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20RequestService.ts
src/charging-station/ocpp/2.0/OCPP20ResponseService.ts

index 1b6ed2906cbead1ddbc8d6368f7c7051438af6f7..10505ff0c3a6634858c53eeb40d04a1efc11ddd3 100644 (file)
@@ -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<ResponseType> {
+    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<RequestType>(
+          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<RequestType>(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)
+      }
     }
   }
 }
index b2813fd82505cbf05cd9d473b9798dedb8661737..8eb3388486d17785be74ac16c0334616c29f7dd6 100644 (file)
@@ -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`
index 0cdfae66d22f5ad753adecefb568f2c13d247adc..d6330deac51aded0d045d0cf61e00e8796c817d5 100644 (file)
@@ -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,
index a72b3a019be21114704b6258d299e9c61d234826..7d323cd7f254fb122b8c7f25f9a3f3e1a5f753c8 100644 (file)
@@ -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<ResponseType> {
+    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<RequestType>(chargingStation, commandName, commandParams),
-        commandName,
-        params
-      )) as ResponseType
+      try {
+        logger.debug(
+          `${chargingStation.logPrefix()} ${moduleName}.requestHandler: Building request payload for '${commandName}'`
+        )
+        const requestPayload = this.buildRequestPayload<RequestType>(
+          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)
+      }
     }
   }
 }
index b74628ff00642930546513664a56d626d44ffd58..a0c7c6590255c8820f9a93332140ca78c8aeeae9 100644 (file)
@@ -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<OCPP20RequestCommand, ValidateFunction<JsonType>>([
       [
@@ -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`