Moved ui folder
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStation.ts
index 418035a798685c6d82981320ea1ddf4574766b44..457369ff1ad029f30046e47432cb40c3546cc551 100644 (file)
@@ -5,9 +5,12 @@ import {
   AvailabilityType,
   BootNotificationRequest,
   CachedRequest,
+  HeartbeatRequest,
   IncomingRequest,
   IncomingRequestCommand,
+  MeterValuesRequest,
   RequestCommand,
+  StatusNotificationRequest,
 } from '../types/ocpp/Requests';
 import {
   BootNotificationResponse,
@@ -39,7 +42,11 @@ import {
   VendorDefaultParametersKey,
 } from '../types/ocpp/Configuration';
 import { MeterValue, MeterValueMeasurand, MeterValuePhase } from '../types/ocpp/MeterValues';
-import { StopTransactionReason, StopTransactionResponse } from '../types/ocpp/Transaction';
+import {
+  StopTransactionReason,
+  StopTransactionRequest,
+  StopTransactionResponse,
+} from '../types/ocpp/Transaction';
 import { WSError, WebSocketCloseEventStatusCode } from '../types/WebSocket';
 import WebSocket, { Data, OPEN, RawData } from 'ws';
 
@@ -362,7 +369,7 @@ export default class ChargingStation {
     }
     if (
       measurand !== MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER &&
-      !this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData).value.includes(
+      !this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData)?.value.includes(
         measurand
       )
     ) {
@@ -393,7 +400,7 @@ export default class ChargingStation {
         phase &&
         sampledValueTemplates[index]?.phase === phase &&
         sampledValueTemplates[index]?.measurand === measurand &&
-        this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData).value.includes(
+        this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData)?.value.includes(
           measurand
         )
       ) {
@@ -402,7 +409,7 @@ export default class ChargingStation {
         !phase &&
         !sampledValueTemplates[index].phase &&
         sampledValueTemplates[index]?.measurand === measurand &&
-        this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData).value.includes(
+        this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData)?.value.includes(
           measurand
         )
       ) {
@@ -437,7 +444,7 @@ export default class ChargingStation {
     ) {
       // eslint-disable-next-line @typescript-eslint/no-misused-promises
       this.heartbeatSetInterval = setInterval(async (): Promise<void> => {
-        await this.ocppRequestService.sendMessageHandler<HeartbeatResponse>(
+        await this.ocppRequestService.sendMessageHandler<HeartbeatRequest, HeartbeatResponse>(
           RequestCommand.HEARTBEAT
         );
       }, this.getHeartbeatInterval());
@@ -509,7 +516,7 @@ export default class ChargingStation {
             this.getConnectorStatus(connectorId).transactionId,
             interval
           );
-          await this.ocppRequestService.sendMessageHandler<MeterValuesResponse>(
+          await this.ocppRequestService.sendMessageHandler<MeterValuesRequest, MeterValuesResponse>(
             RequestCommand.METER_VALUES,
             {
               connectorId,
@@ -614,14 +621,14 @@ export default class ChargingStation {
     await this.stopMessageSequence(reason);
     for (const connectorId of this.connectors.keys()) {
       if (connectorId > 0) {
-        await this.ocppRequestService.sendMessageHandler<StatusNotificationResponse>(
-          RequestCommand.STATUS_NOTIFICATION,
-          {
-            connectorId,
-            status: ChargePointStatus.UNAVAILABLE,
-            errorCode: ChargePointErrorCode.NO_ERROR,
-          }
-        );
+        await this.ocppRequestService.sendMessageHandler<
+          StatusNotificationRequest,
+          StatusNotificationResponse
+        >(RequestCommand.STATUS_NOTIFICATION, {
+          connectorId,
+          status: ChargePointStatus.UNAVAILABLE,
+          errorCode: ChargePointErrorCode.NO_ERROR,
+        });
         this.getConnectorStatus(connectorId).status = ChargePointStatus.UNAVAILABLE;
       }
     }
@@ -830,6 +837,12 @@ export default class ChargingStation {
     this.stopMeterValues(connectorId);
   }
 
+  public hasFeatureProfile(featureProfile: SupportedFeatureProfiles) {
+    return this.getConfigurationKey(StandardParametersKey.SupportedFeatureProfiles)?.value.includes(
+      featureProfile
+    );
+  }
+
   public bufferMessage(message: string): void {
     this.messageBuffer.add(message);
   }
@@ -913,6 +926,8 @@ export default class ChargingStation {
         (stationInfo.chargePointSerialNumber = existingStationInfo.chargePointSerialNumber);
       existingStationInfo?.chargeBoxSerialNumber &&
         (stationInfo.chargeBoxSerialNumber = existingStationInfo.chargeBoxSerialNumber);
+      existingStationInfo?.meterSerialNumber &&
+        (stationInfo.meterSerialNumber = existingStationInfo.meterSerialNumber);
     } else {
       const serialNumberSuffix = params?.randomSerialNumber
         ? this.getRandomSerialNumberSuffix({ upperCase: params.randomSerialNumberUpperCase })
@@ -923,6 +938,9 @@ export default class ChargingStation {
       stationInfo.chargeBoxSerialNumber =
         stationInfo?.chargeBoxSerialNumberPrefix &&
         stationInfo.chargeBoxSerialNumberPrefix + serialNumberSuffix;
+      stationInfo.meterSerialNumber =
+        stationInfo?.meterSerialNumberPrefix &&
+        stationInfo.meterSerialNumberPrefix + serialNumberSuffix;
     }
   }
 
@@ -1046,8 +1064,8 @@ export default class ChargingStation {
       }),
       ...(!Utils.isUndefined(stationInfo.iccid) && { iccid: stationInfo.iccid }),
       ...(!Utils.isUndefined(stationInfo.imsi) && { imsi: stationInfo.imsi }),
-      ...(!Utils.isUndefined(stationInfo.meterSerialNumber) && {
-        meterSerialNumber: stationInfo.meterSerialNumber,
+      ...(!Utils.isUndefined(stationInfo.meterSerialNumberPrefix) && {
+        meterSerialNumber: stationInfo.meterSerialNumberPrefix,
       }),
       ...(!Utils.isUndefined(stationInfo.meterType) && {
         meterType: stationInfo.meterType,
@@ -1223,7 +1241,7 @@ export default class ChargingStation {
     if (!this.getConfigurationKey(StandardParametersKey.SupportedFeatureProfiles)) {
       this.addConfigurationKey(
         StandardParametersKey.SupportedFeatureProfiles,
-        `${SupportedFeatureProfiles.Core},${SupportedFeatureProfiles.Local_Auth_List_Management},${SupportedFeatureProfiles.Smart_Charging}`
+        `${SupportedFeatureProfiles.Core},${SupportedFeatureProfiles.FirmwareManagement},${SupportedFeatureProfiles.LocalAuthListManagement},${SupportedFeatureProfiles.SmartCharging},${SupportedFeatureProfiles.RemoteTrigger}`
       );
     }
     this.addConfigurationKey(
@@ -1263,8 +1281,8 @@ export default class ChargingStation {
     }
     if (
       !this.getConfigurationKey(StandardParametersKey.LocalAuthListEnabled) &&
-      this.getConfigurationKey(StandardParametersKey.SupportedFeatureProfiles).value.includes(
-        SupportedFeatureProfiles.Local_Auth_List_Management
+      this.getConfigurationKey(StandardParametersKey.SupportedFeatureProfiles)?.value.includes(
+        SupportedFeatureProfiles.LocalAuthListManagement
       )
     ) {
       this.addConfigurationKey(StandardParametersKey.LocalAuthListEnabled, 'false');
@@ -1379,22 +1397,24 @@ export default class ChargingStation {
       // Send BootNotification
       let registrationRetryCount = 0;
       do {
-        this.bootNotificationResponse =
-          await this.ocppRequestService.sendMessageHandler<BootNotificationResponse>(
-            RequestCommand.BOOT_NOTIFICATION,
-            {
-              chargePointModel: this.bootNotificationRequest.chargePointModel,
-              chargePointVendor: this.bootNotificationRequest.chargePointVendor,
-              chargeBoxSerialNumber: this.bootNotificationRequest.chargeBoxSerialNumber,
-              firmwareVersion: this.bootNotificationRequest.firmwareVersion,
-              chargePointSerialNumber: this.bootNotificationRequest.chargePointSerialNumber,
-              iccid: this.bootNotificationRequest.iccid,
-              imsi: this.bootNotificationRequest.imsi,
-              meterSerialNumber: this.bootNotificationRequest.meterSerialNumber,
-              meterType: this.bootNotificationRequest.meterType,
-            },
-            { skipBufferingOnError: true }
-          );
+        this.bootNotificationResponse = await this.ocppRequestService.sendMessageHandler<
+          BootNotificationRequest,
+          BootNotificationResponse
+        >(
+          RequestCommand.BOOT_NOTIFICATION,
+          {
+            chargePointModel: this.bootNotificationRequest.chargePointModel,
+            chargePointVendor: this.bootNotificationRequest.chargePointVendor,
+            chargeBoxSerialNumber: this.bootNotificationRequest.chargeBoxSerialNumber,
+            firmwareVersion: this.bootNotificationRequest.firmwareVersion,
+            chargePointSerialNumber: this.bootNotificationRequest.chargePointSerialNumber,
+            iccid: this.bootNotificationRequest.iccid,
+            imsi: this.bootNotificationRequest.imsi,
+            meterSerialNumber: this.bootNotificationRequest.meterSerialNumber,
+            meterType: this.bootNotificationRequest.meterType,
+          },
+          { skipBufferingOnError: true }
+        );
         if (!this.isInAcceptedState()) {
           this.getRegistrationMaxRetries() !== -1 && registrationRetryCount++;
           await Utils.sleep(
@@ -1724,7 +1744,10 @@ export default class ChargingStation {
 
   private async startMessageSequence(): Promise<void> {
     if (this.stationInfo.autoRegister) {
-      await this.ocppRequestService.sendMessageHandler<BootNotificationResponse>(
+      await this.ocppRequestService.sendMessageHandler<
+        BootNotificationRequest,
+        BootNotificationResponse
+      >(
         RequestCommand.BOOT_NOTIFICATION,
         {
           chargePointModel: this.bootNotificationRequest.chargePointModel,
@@ -1754,14 +1777,14 @@ export default class ChargingStation {
         this.getConnectorStatus(connectorId)?.bootStatus
       ) {
         // Send status in template at startup
-        await this.ocppRequestService.sendMessageHandler<StatusNotificationResponse>(
-          RequestCommand.STATUS_NOTIFICATION,
-          {
-            connectorId,
-            status: this.getConnectorStatus(connectorId).bootStatus,
-            errorCode: ChargePointErrorCode.NO_ERROR,
-          }
-        );
+        await this.ocppRequestService.sendMessageHandler<
+          StatusNotificationRequest,
+          StatusNotificationResponse
+        >(RequestCommand.STATUS_NOTIFICATION, {
+          connectorId,
+          status: this.getConnectorStatus(connectorId).bootStatus,
+          errorCode: ChargePointErrorCode.NO_ERROR,
+        });
         this.getConnectorStatus(connectorId).status =
           this.getConnectorStatus(connectorId).bootStatus;
       } else if (
@@ -1770,36 +1793,36 @@ export default class ChargingStation {
         this.getConnectorStatus(connectorId)?.bootStatus
       ) {
         // Send status in template after reset
-        await this.ocppRequestService.sendMessageHandler<StatusNotificationResponse>(
-          RequestCommand.STATUS_NOTIFICATION,
-          {
-            connectorId,
-            status: this.getConnectorStatus(connectorId).bootStatus,
-            errorCode: ChargePointErrorCode.NO_ERROR,
-          }
-        );
+        await this.ocppRequestService.sendMessageHandler<
+          StatusNotificationRequest,
+          StatusNotificationResponse
+        >(RequestCommand.STATUS_NOTIFICATION, {
+          connectorId,
+          status: this.getConnectorStatus(connectorId).bootStatus,
+          errorCode: ChargePointErrorCode.NO_ERROR,
+        });
         this.getConnectorStatus(connectorId).status =
           this.getConnectorStatus(connectorId).bootStatus;
       } else if (!this.stopped && this.getConnectorStatus(connectorId)?.status) {
         // Send previous status at template reload
-        await this.ocppRequestService.sendMessageHandler<StatusNotificationResponse>(
-          RequestCommand.STATUS_NOTIFICATION,
-          {
-            connectorId,
-            status: this.getConnectorStatus(connectorId).status,
-            errorCode: ChargePointErrorCode.NO_ERROR,
-          }
-        );
+        await this.ocppRequestService.sendMessageHandler<
+          StatusNotificationRequest,
+          StatusNotificationResponse
+        >(RequestCommand.STATUS_NOTIFICATION, {
+          connectorId,
+          status: this.getConnectorStatus(connectorId).status,
+          errorCode: ChargePointErrorCode.NO_ERROR,
+        });
       } else {
         // Send default status
-        await this.ocppRequestService.sendMessageHandler<StatusNotificationResponse>(
-          RequestCommand.STATUS_NOTIFICATION,
-          {
-            connectorId,
-            status: ChargePointStatus.AVAILABLE,
-            errorCode: ChargePointErrorCode.NO_ERROR,
-          }
-        );
+        await this.ocppRequestService.sendMessageHandler<
+          StatusNotificationRequest,
+          StatusNotificationResponse
+        >(RequestCommand.STATUS_NOTIFICATION, {
+          connectorId,
+          status: ChargePointStatus.AVAILABLE,
+          errorCode: ChargePointErrorCode.NO_ERROR,
+        });
         this.getConnectorStatus(connectorId).status = ChargePointStatus.AVAILABLE;
       }
     }
@@ -1846,24 +1869,24 @@ export default class ChargingStation {
               connectorId,
               this.getEnergyActiveImportRegisterByTransactionId(transactionId)
             );
-            await this.ocppRequestService.sendMessageHandler<MeterValuesResponse>(
-              RequestCommand.METER_VALUES,
-              {
-                connectorId,
-                transactionId,
-                meterValue: transactionEndMeterValue,
-              }
-            );
-          }
-          await this.ocppRequestService.sendMessageHandler<StopTransactionResponse>(
-            RequestCommand.STOP_TRANSACTION,
-            {
+            await this.ocppRequestService.sendMessageHandler<
+              MeterValuesRequest,
+              MeterValuesResponse
+            >(RequestCommand.METER_VALUES, {
+              connectorId,
               transactionId,
-              meterStop: this.getEnergyActiveImportRegisterByTransactionId(transactionId),
-              idTag: this.getTransactionIdTag(transactionId),
-              reason,
-            }
-          );
+              meterValue: transactionEndMeterValue,
+            });
+          }
+          await this.ocppRequestService.sendMessageHandler<
+            StopTransactionRequest,
+            StopTransactionResponse
+          >(RequestCommand.STOP_TRANSACTION, {
+            transactionId,
+            meterStop: this.getEnergyActiveImportRegisterByTransactionId(transactionId),
+            idTag: this.getTransactionIdTag(transactionId),
+            reason,
+          });
         }
       }
     }