Fix deprecated configuration key detection in a section
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16IncomingRequestService.ts
index 0e5918db515068f4dee02a9a1e98f952b6de11f1..bd9985048c3f9fdfa0679b96c677df0e8d674249 100644 (file)
@@ -9,6 +9,7 @@ import {
   MessageTrigger,
   OCPP16AvailabilityType,
   OCPP16IncomingRequestCommand,
+  OCPP16RequestCommand,
   OCPP16TriggerMessageRequest,
   RemoteStartTransactionRequest,
   RemoteStopTransactionRequest,
@@ -33,7 +34,10 @@ import {
 import { Client, FTPResponse } from 'basic-ftp';
 import {
   OCPP16AuthorizationStatus,
+  OCPP16AuthorizeResponse,
+  OCPP16StartTransactionResponse,
   OCPP16StopTransactionReason,
+  OCPP16StopTransactionResponse,
 } from '../../../types/ocpp/1.6/Transaction';
 
 import type ChargingStation from '../../ChargingStation';
@@ -42,8 +46,10 @@ import { DefaultResponse } from '../../../types/ocpp/Responses';
 import { ErrorType } from '../../../types/ocpp/ErrorType';
 import { IncomingRequestHandler } from '../../../types/ocpp/Requests';
 import { JsonType } from '../../../types/JsonType';
+import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointErrorCode';
 import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
 import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus';
+import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
 import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration';
 import { OCPPConfigurationKey } from '../../../types/ocpp/Configuration';
 import OCPPError from '../../../exception/OCPPError';
@@ -200,20 +206,48 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
     }
     if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
       const transactionId = this.chargingStation.getConnectorStatus(connectorId).transactionId;
-      const stopResponse = await this.chargingStation.ocppRequestService.sendStopTransaction(
-        transactionId,
-        this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
-        this.chargingStation.getTransactionIdTag(transactionId),
-        OCPP16StopTransactionReason.UNLOCK_COMMAND
-      );
+      if (
+        this.chargingStation.getBeginEndMeterValues() &&
+        this.chargingStation.getOcppStrictCompliance() &&
+        !this.chargingStation.getOutOfOrderEndMeterValues()
+      ) {
+        // FIXME: Implement OCPP version agnostic helpers
+        const transactionEndMeterValue = OCPP16ServiceUtils.buildTransactionEndMeterValue(
+          this.chargingStation,
+          connectorId,
+          this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
+        );
+        await this.chargingStation.ocppRequestService.sendMessageHandler(
+          OCPP16RequestCommand.METER_VALUES,
+          {
+            connectorId,
+            transactionId,
+            meterValue: transactionEndMeterValue,
+          }
+        );
+      }
+      const stopResponse = (await this.chargingStation.ocppRequestService.sendMessageHandler(
+        OCPP16RequestCommand.STOP_TRANSACTION,
+        {
+          transactionId,
+          meterStop:
+            this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
+          idTag: this.chargingStation.getTransactionIdTag(transactionId),
+          reason: OCPP16StopTransactionReason.UNLOCK_COMMAND,
+        }
+      )) as OCPP16StopTransactionResponse;
       if (stopResponse.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
         return Constants.OCPP_RESPONSE_UNLOCKED;
       }
       return Constants.OCPP_RESPONSE_UNLOCK_FAILED;
     }
-    await this.chargingStation.ocppRequestService.sendStatusNotification(
-      connectorId,
-      OCPP16ChargePointStatus.AVAILABLE
+    await this.chargingStation.ocppRequestService.sendMessageHandler(
+      OCPP16RequestCommand.STATUS_NOTIFICATION,
+      {
+        connectorId,
+        status: OCPP16ChargePointStatus.AVAILABLE,
+        errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+      }
     );
     this.chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE;
     return Constants.OCPP_RESPONSE_UNLOCKED;
@@ -461,9 +495,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         }
         this.chargingStation.getConnectorStatus(id).availability = commandPayload.type;
         if (response === Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED) {
-          await this.chargingStation.ocppRequestService.sendStatusNotification(
-            id,
-            chargePointStatus
+          await this.chargingStation.ocppRequestService.sendMessageHandler(
+            OCPP16RequestCommand.STATUS_NOTIFICATION,
+            {
+              connectorId: id,
+              status: chargePointStatus,
+              errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+            }
           );
           this.chargingStation.getConnectorStatus(id).status = chargePointStatus;
         }
@@ -482,9 +520,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         return Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
       }
       this.chargingStation.getConnectorStatus(connectorId).availability = commandPayload.type;
-      await this.chargingStation.ocppRequestService.sendStatusNotification(
-        connectorId,
-        chargePointStatus
+      await this.chargingStation.ocppRequestService.sendMessageHandler(
+        OCPP16RequestCommand.STATUS_NOTIFICATION,
+        { connectorId, status: chargePointStatus, errorCode: OCPP16ChargePointErrorCode.NO_ERROR }
       );
       this.chargingStation.getConnectorStatus(connectorId).status = chargePointStatus;
       return Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED;
@@ -497,9 +535,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
   ): Promise<DefaultResponse> {
     const transactionConnectorId: number = commandPayload.connectorId;
     if (transactionConnectorId) {
-      await this.chargingStation.ocppRequestService.sendStatusNotification(
-        transactionConnectorId,
-        OCPP16ChargePointStatus.PREPARING
+      await this.chargingStation.ocppRequestService.sendMessageHandler(
+        OCPP16RequestCommand.STATUS_NOTIFICATION,
+        {
+          connectorId: transactionConnectorId,
+          status: OCPP16ChargePointStatus.PREPARING,
+          errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+        }
       );
       this.chargingStation.getConnectorStatus(transactionConnectorId).status =
         OCPP16ChargePointStatus.PREPARING;
@@ -521,10 +563,15 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
               true;
             authorized = true;
           } else if (this.chargingStation.getMayAuthorizeAtRemoteStart()) {
-            const authorizeResponse = await this.chargingStation.ocppRequestService.sendAuthorize(
-              transactionConnectorId,
-              commandPayload.idTag
-            );
+            this.chargingStation.getConnectorStatus(transactionConnectorId).authorizeIdTag =
+              commandPayload.idTag;
+            const authorizeResponse: OCPP16AuthorizeResponse =
+              (await this.chargingStation.ocppRequestService.sendMessageHandler(
+                OCPP16RequestCommand.AUTHORIZE,
+                {
+                  idTag: commandPayload.idTag,
+                }
+              )) as OCPP16AuthorizeResponse;
             if (authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
               authorized = true;
             }
@@ -546,10 +593,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
               ).transactionRemoteStarted = true;
               if (
                 (
-                  await this.chargingStation.ocppRequestService.sendStartTransaction(
-                    transactionConnectorId,
-                    commandPayload.idTag
-                  )
+                  (await this.chargingStation.ocppRequestService.sendMessageHandler(
+                    OCPP16RequestCommand.START_TRANSACTION,
+                    {
+                      connectorId: transactionConnectorId,
+                      idTag: commandPayload.idTag,
+                    }
+                  )) as OCPP16StartTransactionResponse
                 ).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
               ) {
                 logger.debug(
@@ -589,10 +639,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
             true;
           if (
             (
-              await this.chargingStation.ocppRequestService.sendStartTransaction(
-                transactionConnectorId,
-                commandPayload.idTag
-              )
+              (await this.chargingStation.ocppRequestService.sendMessageHandler(
+                OCPP16RequestCommand.START_TRANSACTION,
+                {
+                  connectorId: transactionConnectorId,
+                  idTag: commandPayload.idTag,
+                }
+              )) as OCPP16StartTransactionResponse
             ).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
           ) {
             logger.debug(
@@ -632,9 +685,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
       this.chargingStation.getConnectorStatus(connectorId).status !==
       OCPP16ChargePointStatus.AVAILABLE
     ) {
-      await this.chargingStation.ocppRequestService.sendStatusNotification(
-        connectorId,
-        OCPP16ChargePointStatus.AVAILABLE
+      await this.chargingStation.ocppRequestService.sendMessageHandler(
+        OCPP16RequestCommand.STATUS_NOTIFICATION,
+        {
+          connectorId,
+          status: OCPP16ChargePointStatus.AVAILABLE,
+          errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+        }
       );
       this.chargingStation.getConnectorStatus(connectorId).status =
         OCPP16ChargePointStatus.AVAILABLE;
@@ -685,16 +742,44 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         connectorId > 0 &&
         this.chargingStation.getConnectorStatus(connectorId)?.transactionId === transactionId
       ) {
-        await this.chargingStation.ocppRequestService.sendStatusNotification(
-          connectorId,
-          OCPP16ChargePointStatus.FINISHING
+        await this.chargingStation.ocppRequestService.sendMessageHandler(
+          OCPP16RequestCommand.STATUS_NOTIFICATION,
+          {
+            connectorId,
+            status: OCPP16ChargePointStatus.FINISHING,
+            errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+          }
         );
         this.chargingStation.getConnectorStatus(connectorId).status =
           OCPP16ChargePointStatus.FINISHING;
-        await this.chargingStation.ocppRequestService.sendStopTransaction(
-          transactionId,
-          this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
-          this.chargingStation.getTransactionIdTag(transactionId)
+        if (
+          this.chargingStation.getBeginEndMeterValues() &&
+          this.chargingStation.getOcppStrictCompliance() &&
+          !this.chargingStation.getOutOfOrderEndMeterValues()
+        ) {
+          // FIXME: Implement OCPP version agnostic helpers
+          const transactionEndMeterValue = OCPP16ServiceUtils.buildTransactionEndMeterValue(
+            this.chargingStation,
+            connectorId,
+            this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
+          );
+          await this.chargingStation.ocppRequestService.sendMessageHandler(
+            OCPP16RequestCommand.METER_VALUES,
+            {
+              connectorId,
+              transactionId,
+              meterValue: transactionEndMeterValue,
+            }
+          );
+        }
+        await this.chargingStation.ocppRequestService.sendMessageHandler(
+          OCPP16RequestCommand.STOP_TRANSACTION,
+          {
+            transactionId,
+            meterStop:
+              this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
+            idTag: this.chargingStation.getTransactionIdTag(transactionId),
+          }
         );
         return Constants.OCPP_RESPONSE_ACCEPTED;
       }
@@ -744,8 +829,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
                 info.bytes / 1024
               } bytes transferred from diagnostics archive ${info.name}`
             );
-            await this.chargingStation.ocppRequestService.sendDiagnosticsStatusNotification(
-              OCPP16DiagnosticsStatus.Uploading
+            await this.chargingStation.ocppRequestService.sendMessageHandler(
+              OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+              {
+                status: OCPP16DiagnosticsStatus.Uploading,
+              }
             );
           });
           uploadResponse = await ftpClient.uploadFrom(
@@ -753,8 +841,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
             uri.pathname + diagnosticsArchive
           );
           if (uploadResponse.code === 226) {
-            await this.chargingStation.ocppRequestService.sendDiagnosticsStatusNotification(
-              OCPP16DiagnosticsStatus.Uploaded
+            await this.chargingStation.ocppRequestService.sendMessageHandler(
+              OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+              {
+                status: OCPP16DiagnosticsStatus.Uploaded,
+              }
             );
             if (ftpClient) {
               ftpClient.close();
@@ -777,8 +868,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
           OCPP16IncomingRequestCommand.GET_DIAGNOSTICS
         );
       } catch (error) {
-        await this.chargingStation.ocppRequestService.sendDiagnosticsStatusNotification(
-          OCPP16DiagnosticsStatus.UploadFailed
+        await this.chargingStation.ocppRequestService.sendMessageHandler(
+          OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+          {
+            status: OCPP16DiagnosticsStatus.UploadFailed,
+          }
         );
         if (ftpClient) {
           ftpClient.close();
@@ -795,8 +889,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
           uri.protocol
         } to transfer the diagnostic logs archive`
       );
-      await this.chargingStation.ocppRequestService.sendDiagnosticsStatusNotification(
-        OCPP16DiagnosticsStatus.UploadFailed
+      await this.chargingStation.ocppRequestService.sendMessageHandler(
+        OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+        {
+          status: OCPP16DiagnosticsStatus.UploadFailed,
+        }
       );
       return Constants.OCPP_RESPONSE_EMPTY;
     }
@@ -810,17 +907,26 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         case MessageTrigger.BootNotification:
           setTimeout(() => {
             this.chargingStation.ocppRequestService
-              .sendBootNotification(
-                this.chargingStation.getBootNotificationRequest().chargePointModel,
-                this.chargingStation.getBootNotificationRequest().chargePointVendor,
-                this.chargingStation.getBootNotificationRequest().chargeBoxSerialNumber,
-                this.chargingStation.getBootNotificationRequest().firmwareVersion,
-                this.chargingStation.getBootNotificationRequest().chargePointSerialNumber,
-                this.chargingStation.getBootNotificationRequest().iccid,
-                this.chargingStation.getBootNotificationRequest().imsi,
-                this.chargingStation.getBootNotificationRequest().meterSerialNumber,
-                this.chargingStation.getBootNotificationRequest().meterType,
-                { triggerMessage: true }
+              .sendMessageHandler(
+                OCPP16RequestCommand.BOOT_NOTIFICATION,
+                {
+                  chargePointModel:
+                    this.chargingStation.getBootNotificationRequest().chargePointModel,
+                  chargePointVendor:
+                    this.chargingStation.getBootNotificationRequest().chargePointVendor,
+                  chargeBoxSerialNumber:
+                    this.chargingStation.getBootNotificationRequest().chargeBoxSerialNumber,
+                  firmwareVersion:
+                    this.chargingStation.getBootNotificationRequest().firmwareVersion,
+                  chargePointSerialNumber:
+                    this.chargingStation.getBootNotificationRequest().chargePointSerialNumber,
+                  iccid: this.chargingStation.getBootNotificationRequest().iccid,
+                  imsi: this.chargingStation.getBootNotificationRequest().imsi,
+                  meterSerialNumber:
+                    this.chargingStation.getBootNotificationRequest().meterSerialNumber,
+                  meterType: this.chargingStation.getBootNotificationRequest().meterType,
+                },
+                { skipBufferingOnError: true, triggerMessage: true }
               )
               .catch(() => {
                 /* This is intentional */
@@ -830,7 +936,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         case MessageTrigger.Heartbeat:
           setTimeout(() => {
             this.chargingStation.ocppRequestService
-              .sendHeartbeat({ triggerMessage: true })
+              .sendMessageHandler(OCPP16RequestCommand.HEARTBEAT, null, { triggerMessage: true })
               .catch(() => {
                 /* This is intentional */
               });