Add BootNotification and ClearCache OCPP 2.0.1 commands support
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 2.0 / OCPP20ResponseService.ts
index 39baa0e579bb41a7eed3587c9a89c02a3306ca9f..d4636f6f3ca25319ef5ad020bd4b29425733e0d8 100644 (file)
@@ -1,12 +1,18 @@
 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
 
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
 import type { JSONSchemaType } from 'ajv';
 
 import OCPPError from '../../../exception/OCPPError';
 import type { JsonObject, JsonType } from '../../../types/JsonType';
-import type { OCPP20RequestCommand } from '../../../types/ocpp/2.0/Requests';
+import { OCPP20RequestCommand } from '../../../types/ocpp/2.0/Requests';
+import type { OCPP20BootNotificationResponse } from '../../../types/ocpp/2.0/Responses';
 import { ErrorType } from '../../../types/ocpp/ErrorType';
-import type { ResponseHandler } from '../../../types/ocpp/Responses';
+import { OCPPVersion } from '../../../types/ocpp/OCPPVersion';
+import { RegistrationStatusEnumType, ResponseHandler } from '../../../types/ocpp/Responses';
 import logger from '../../../utils/Logger';
 import type ChargingStation from '../../ChargingStation';
 import OCPPResponseService from '../OCPPResponseService';
@@ -22,9 +28,24 @@ export default class OCPP20ResponseService extends OCPPResponseService {
     if (new.target?.name === moduleName) {
       throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
     }
-    super();
-    this.responseHandlers = new Map<OCPP20RequestCommand, ResponseHandler>();
-    this.jsonSchemas = new Map<OCPP20RequestCommand, JSONSchemaType<JsonObject>>();
+    super(OCPPVersion.VERSION_20);
+    this.responseHandlers = new Map<OCPP20RequestCommand, ResponseHandler>([
+      [OCPP20RequestCommand.BOOT_NOTIFICATION, this.handleResponseBootNotification.bind(this)],
+    ]);
+    this.jsonSchemas = new Map<OCPP20RequestCommand, JSONSchemaType<JsonObject>>([
+      [
+        OCPP20RequestCommand.BOOT_NOTIFICATION,
+        JSON.parse(
+          fs.readFileSync(
+            path.resolve(
+              path.dirname(fileURLToPath(import.meta.url)),
+              '../../../assets/json-schemas/ocpp/2.0/BootNotificationResponse.json'
+            ),
+            'utf8'
+          )
+        ) as JSONSchemaType<OCPP20BootNotificationResponse>,
+      ],
+    ]);
     this.validatePayload.bind(this);
   }
 
@@ -35,8 +56,8 @@ export default class OCPP20ResponseService extends OCPPResponseService {
     requestPayload: JsonType
   ): Promise<void> {
     if (
-      chargingStation.isRegistered() === true /* ||
-      commandName === OCPP20RequestCommand.BOOT_NOTIFICATION */
+      chargingStation.isRegistered() === true ||
+      commandName === OCPP20RequestCommand.BOOT_NOTIFICATION
     ) {
       if (
         this.responseHandlers.has(commandName) === true &&
@@ -72,7 +93,7 @@ export default class OCPP20ResponseService extends OCPPResponseService {
           payload,
           null,
           2
-        )} while the charging station is not registered on the central server. `,
+        )} while the charging station is not registered on the central server.`,
         commandName,
         payload
       );
@@ -97,4 +118,43 @@ export default class OCPP20ResponseService extends OCPPResponseService {
     );
     return false;
   }
+
+  private handleResponseBootNotification(
+    chargingStation: ChargingStation,
+    payload: OCPP20BootNotificationResponse
+  ): void {
+    if (payload.status === RegistrationStatusEnumType.ACCEPTED) {
+      // ChargingStationConfigurationUtils.addConfigurationKey(
+      //   chargingStation,
+      //   OCPP16StandardParametersKey.HeartbeatInterval,
+      //   payload.interval.toString(),
+      //   {},
+      //   { overwrite: true, save: true }
+      // );
+      // ChargingStationConfigurationUtils.addConfigurationKey(
+      //   chargingStation,
+      //   OCPP16StandardParametersKey.HeartBeatInterval,
+      //   payload.interval.toString(),
+      //   { visible: false },
+      //   { overwrite: true, save: true }
+      // );
+      chargingStation.heartbeatSetInterval
+        ? chargingStation.restartHeartbeat()
+        : chargingStation.startHeartbeat();
+    }
+    if (Object.values(RegistrationStatusEnumType).includes(payload.status)) {
+      const logMsg = `${chargingStation.logPrefix()} Charging station in '${
+        payload.status
+      }' state on the central server`;
+      payload.status === RegistrationStatusEnumType.REJECTED
+        ? logger.warn(logMsg)
+        : logger.info(logMsg);
+    } else {
+      logger.error(
+        chargingStation.logPrefix() +
+          ' Charging station boot notification response received: %j with undefined registration status',
+        payload
+      );
+    }
+  }
 }