Ensure 1:1 mapping between charging station instance and its OCPP services
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStation.ts
index 8d2efa755324f07e7a51064eb5651eb9107ae70b..028de5918c9f38cc7d9dd4281b589611d19b19a4 100644 (file)
@@ -42,6 +42,7 @@ import { parentPort } from 'worker_threads';
 import path from 'path';
 
 export default class ChargingStation {
+  public readonly id: string;
   public readonly stationTemplateFile: string;
   public authorizedTags: string[];
   public stationInfo!: ChargingStationInfo;
@@ -66,18 +67,16 @@ export default class ChargingStation {
   private webSocketPingSetInterval!: NodeJS.Timeout;
 
   constructor(index: number, stationTemplateFile: string) {
+    this.id = Utils.generateUUID();
     this.index = index;
     this.stationTemplateFile = stationTemplateFile;
-    this.connectors = new Map<number, ConnectorStatus>();
-    this.initialize();
-
     this.stopped = false;
     this.wsConnectionRestarted = false;
     this.autoReconnectRetryCount = 0;
-
+    this.connectors = new Map<number, ConnectorStatus>();
     this.requests = new Map<string, CachedRequest>();
     this.messageBuffer = new Set<string>();
-
+    this.initialize();
     this.authorizedTags = this.getAuthorizedTags();
   }
 
@@ -152,7 +151,7 @@ export default class ChargingStation {
   }
 
   public isConnectorAvailable(id: number): boolean {
-    return this.getConnectorStatus(id).availability === AvailabilityType.OPERATIVE;
+    return id > 0 && this.getConnectorStatus(id).availability === AvailabilityType.OPERATIVE;
   }
 
   public getNumberOfConnectors(): number {
@@ -589,8 +588,8 @@ export default class ChargingStation {
     this.wsConfiguredConnectionUrl = new URL(this.getConfiguredSupervisionUrl().href + '/' + this.stationInfo.chargingStationId);
     switch (this.getOcppVersion()) {
       case OCPPVersion.VERSION_16:
-        this.ocppIncomingRequestService = new OCPP16IncomingRequestService(this);
-        this.ocppRequestService = new OCPP16RequestService(this, new OCPP16ResponseService(this));
+        this.ocppIncomingRequestService = OCPP16IncomingRequestService.getInstance<OCPP16IncomingRequestService>(this);
+        this.ocppRequestService = OCPP16RequestService.getInstance<OCPP16RequestService>(this, OCPP16ResponseService.getInstance<OCPP16ResponseService>(this));
         break;
       default:
         this.handleUnsupportedVersion(this.getOcppVersion());
@@ -607,7 +606,7 @@ export default class ChargingStation {
     }
     this.stationInfo.powerDivider = this.getPowerDivider();
     if (this.getEnableStatistics()) {
-      this.performanceStatistics = new PerformanceStatistics(this.stationInfo.chargingStationId, this.wsConnectionUrl);
+      this.performanceStatistics = PerformanceStatistics.getInstance(this.id, this.stationInfo.chargingStationId, this.wsConnectionUrl);
     }
   }
 
@@ -665,10 +664,6 @@ export default class ChargingStation {
         }
       } while (!this.isInAcceptedState() && (registrationRetryCount <= this.getRegistrationMaxRetries() || this.getRegistrationMaxRetries() === -1));
     }
-    if (this.isInAcceptedState() && this.stationInfo.autoRegister) {
-      await this.ocppRequestService.sendBootNotification(this.bootNotificationRequest.chargePointModel,
-        this.bootNotificationRequest.chargePointVendor, this.bootNotificationRequest.chargeBoxSerialNumber, this.bootNotificationRequest.firmwareVersion);
-    }
     if (this.isInAcceptedState()) {
       await this.startMessageSequence();
       this.stopped && (this.stopped = false);
@@ -878,6 +873,10 @@ export default class ChargingStation {
   }
 
   private async startMessageSequence(): Promise<void> {
+    if (this.stationInfo.autoRegister) {
+      await this.ocppRequestService.sendBootNotification(this.bootNotificationRequest.chargePointModel,
+        this.bootNotificationRequest.chargePointVendor, this.bootNotificationRequest.chargeBoxSerialNumber, this.bootNotificationRequest.firmwareVersion);
+    }
     // Start WebSocket ping
     this.startWebSocketPing();
     // Start heartbeat
@@ -925,8 +924,7 @@ export default class ChargingStation {
     this.stopHeartbeat();
     // Stop the ATG
     if (this.stationInfo.AutomaticTransactionGenerator.enable &&
-      this.automaticTransactionGenerator &&
-      this.automaticTransactionGenerator.started) {
+      this.automaticTransactionGenerator?.started) {
       this.automaticTransactionGenerator.stop();
     } else {
       for (const connectorId of this.connectors.keys()) {
@@ -1117,8 +1115,7 @@ export default class ChargingStation {
     // Stop the ATG if needed
     if (this.stationInfo.AutomaticTransactionGenerator.enable &&
       this.stationInfo.AutomaticTransactionGenerator.stopOnConnectionFailure &&
-      this.automaticTransactionGenerator &&
-      this.automaticTransactionGenerator.started) {
+      this.automaticTransactionGenerator?.started) {
       this.automaticTransactionGenerator.stop();
     }
     if (this.autoReconnectRetryCount < this.getAutoReconnectMaxRetries() || this.getAutoReconnectMaxRetries() === -1) {