fix: ensure stop transaction is sent at ATG stop
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 7 Nov 2023 16:33:51 +0000 (17:33 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 7 Nov 2023 16:33:51 +0000 (17:33 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts

index 0ff5c888a2536c8ca4332f8cde5190b3721bf731..d893dc918fc9b18daeb90c2dbd14032335ff2269 100644 (file)
@@ -86,7 +86,7 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     this.starting = false;
   }
 
-  public stop(): void {
+  public async stop(): Promise<void> {
     if (this.started === false) {
       logger.warn(`${this.logPrefix()} is already stopped`);
       return;
@@ -96,7 +96,7 @@ export class AutomaticTransactionGenerator extends AsyncResource {
       return;
     }
     this.stopping = true;
-    this.stopConnectors();
+    await this.stopConnectors();
     this.started = false;
     this.stopping = false;
   }
@@ -123,13 +123,14 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     }
   }
 
-  public stopConnector(connectorId: number): void {
+  public async stopConnector(connectorId: number): Promise<void> {
     if (this.connectorsStatus.has(connectorId) === false) {
       logger.error(`${this.logPrefix(connectorId)} stopping on non existing connector`);
       throw new BaseError(`Connector ${connectorId} does not exist`);
     }
     if (this.connectorsStatus.get(connectorId)?.start === true) {
       this.connectorsStatus.get(connectorId)!.start = false;
+      await this.stopTransaction(connectorId);
     } else if (this.connectorsStatus.get(connectorId)?.start === false) {
       logger.warn(`${this.logPrefix(connectorId)} is already stopped on connector`);
     }
@@ -160,19 +161,19 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     }
   }
 
-  private stopConnectors(): void {
+  private async stopConnectors(): Promise<void> {
     if (this.chargingStation.hasEvses) {
       for (const [evseId, evseStatus] of this.chargingStation.evses) {
         if (evseId > 0) {
           for (const connectorId of evseStatus.connectors.keys()) {
-            this.stopConnector(connectorId);
+            await this.stopConnector(connectorId);
           }
         }
       }
     } else {
       for (const connectorId of this.chargingStation.connectors.keys()) {
         if (connectorId > 0) {
-          this.stopConnector(connectorId);
+          await this.stopConnector(connectorId);
         }
       }
     }
@@ -190,7 +191,7 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     );
     while (this.connectorsStatus.get(connectorId)?.start === true) {
       if (!this.canStartConnector(connectorId)) {
-        this.stopConnector(connectorId);
+        await this.stopConnector(connectorId);
         break;
       }
       if (!this.chargingStation?.ocppRequestService) {
@@ -236,13 +237,6 @@ export class AutomaticTransactionGenerator extends AsyncResource {
               ?.transactionId} and will stop in ${formatDurationMilliSeconds(waitTrxEnd)}`,
           );
           await sleep(waitTrxEnd);
-          // Stop transaction
-          logger.info(
-            `${this.logPrefix(
-              connectorId,
-            )} stop transaction with id ${this.chargingStation.getConnectorStatus(connectorId)
-              ?.transactionId}`,
-          );
           await this.stopTransaction(connectorId);
         }
       } else {
@@ -451,6 +445,12 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     const beginId = PerformanceStatistics.beginMeasure(measureId);
     let stopResponse: StopTransactionResponse | undefined;
     if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
+      logger.info(
+        `${this.logPrefix(
+          connectorId,
+        )} stop transaction with id ${this.chargingStation.getConnectorStatus(connectorId)
+          ?.transactionId}`,
+      );
       stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason);
       ++this.connectorsStatus.get(connectorId)!.stopTransactionRequests!;
       if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
index c6a5278edccc1b5f9e324fff5584f32c3e042fde..996b9cf9fb6a83694c8b1fbf1eea80f7d9aed7b4 100644 (file)
@@ -682,7 +682,7 @@ export class ChargingStation {
                 this.initialize();
                 this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo)!);
                 // Restart the ATG
-                this.stopAutomaticTransactionGenerator();
+                this.stopAutomaticTransactionGenerator().catch(() => {});
                 delete this.automaticTransactionGeneratorConfiguration;
                 if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
                   this.startAutomaticTransactionGenerator();
@@ -873,13 +873,13 @@ export class ChargingStation {
     parentPort?.postMessage(buildUpdatedMessage(this));
   }
 
-  public stopAutomaticTransactionGenerator(connectorIds?: number[]): void {
+  public async stopAutomaticTransactionGenerator(connectorIds?: number[]): Promise<void> {
     if (isNotEmptyArray(connectorIds)) {
       for (const connectorId of connectorIds!) {
-        this.automaticTransactionGenerator?.stopConnector(connectorId);
+        await this.automaticTransactionGenerator?.stopConnector(connectorId);
       }
     } else {
-      this.automaticTransactionGenerator?.stop();
+      await this.automaticTransactionGenerator?.stop();
     }
     this.saveAutomaticTransactionGeneratorConfiguration();
     parentPort?.postMessage(buildUpdatedMessage(this));
@@ -2171,7 +2171,7 @@ export class ChargingStation {
     this.stopHeartbeat();
     // Stop ongoing transactions
     if (this.automaticTransactionGenerator?.started === true) {
-      this.stopAutomaticTransactionGenerator();
+      await this.stopAutomaticTransactionGenerator();
     } else {
       await this.stopRunningTransactions(reason);
     }
@@ -2318,7 +2318,7 @@ export class ChargingStation {
     this.stopHeartbeat();
     // Stop the ATG if needed
     if (this.getAutomaticTransactionGeneratorConfiguration().stopOnConnectionFailure === true) {
-      this.stopAutomaticTransactionGenerator();
+      await this.stopAutomaticTransactionGenerator();
     }
     if (
       this.autoReconnectRetryCount < this.getAutoReconnectMaxRetries()! ||
index fff823c09b22989f441c6b88968018a6acc933a6..ee423e1e1a8b06037bd9b59c6697218b77edf96e 100644 (file)
@@ -87,8 +87,10 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne
       ],
       [
         BroadcastChannelProcedureName.STOP_AUTOMATIC_TRANSACTION_GENERATOR,
-        (requestPayload?: BroadcastChannelRequestPayload) =>
-          this.chargingStation.stopAutomaticTransactionGenerator(requestPayload?.connectorIds),
+        async (requestPayload?: BroadcastChannelRequestPayload) =>
+          await this.chargingStation.stopAutomaticTransactionGenerator(
+            requestPayload?.connectorIds,
+          ),
       ],
       [
         BroadcastChannelProcedureName.SET_SUPERVISION_URL,