Fix ATG run duration computation
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 21 Sep 2021 20:36:42 +0000 (22:36 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 21 Sep 2021 20:36:42 +0000 (22:36 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
package-lock.json
package.json
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/performance/storage/StorageFactory.ts
src/worker/WorkerDynamicPool.ts
src/worker/WorkerFactory.ts
src/worker/WorkerSet.ts
src/worker/WorkerStaticPool.ts

index 1128785a3983ea518c2105ea069a854cb8ca1f8a..057a7295552f47edad17b26eb63ea563f4343ef3 100644 (file)
       }
     },
     "@types/node": {
-      "version": "14.17.17",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.17.tgz",
-      "integrity": "sha512-niAjcewgEYvSPCZm3OaM9y6YQrL2SEPH9PymtE6fuZAvFiP6ereCcvApGl2jKTq7copTIguX3PBvfP08LN4LvQ=="
+      "version": "14.17.18",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.18.tgz",
+      "integrity": "sha512-haYyibw4pbteEhkSg0xdDLAI3679L75EJ799ymVrPxOA922bPx3ML59SoDsQ//rHlvqpu+e36kcbR3XRQtFblA=="
     },
     "@types/object-path": {
       "version": "0.11.1",
index 23a18facc3647a2c58d5541b7479b2cde6d0ae59..c56260f9f7e9544f2ccbecc99ce14c499fde0827 100644 (file)
@@ -94,7 +94,7 @@
     "@rollup/plugin-json": "^4.1.0",
     "@types/mocha": "^9.0.0",
     "@types/mochawesome": "^6.2.1",
-    "@types/node": "^14.17.17",
+    "@types/node": "^14.17.18",
     "@types/proper-lockfile": "^4.1.2",
     "@types/tar": "^4.0.5",
     "@types/uuid": "^8.3.1",
index 2315b5cb509d8b8b56e364786916920b9d385580..de11a76f5f2efa9dbae1577a4c658d6ae1af2cd7 100644 (file)
@@ -21,11 +21,12 @@ export default class AutomaticTransactionGenerator {
   }
 
   public start(): void {
+    const previousRunDuration = (this?.startDate && this?.lastRunDate) ? (this.lastRunDate.getTime() - this.startDate.getTime()) : 0;
     this.startDate = new Date();
-    this.lastRunDate = this?.lastRunDate ?? this.startDate;
+    this.lastRunDate = this.startDate;
     this.stopDate = new Date(this.startDate.getTime()
       + (this.chargingStation.stationInfo?.AutomaticTransactionGenerator?.stopAfterHours ?? Constants.CHARGING_STATION_ATG_DEFAULT_STOP_AFTER_HOURS) * 3600 * 1000
-      - (this.lastRunDate.getTime() - this.startDate.getTime()));
+      - previousRunDuration);
     this.started = true;
     for (const connector in this.chargingStation.connectors) {
       if (Utils.convertToInt(connector) > 0) {
@@ -38,21 +39,13 @@ export default class AutomaticTransactionGenerator {
     logger.info(this.logPrefix() + ' started and will run for ' + Utils.formatDurationMilliSeconds(this.stopDate.getTime() - this.startDate.getTime()));
   }
 
-  public async stop(reason: StopTransactionReason = StopTransactionReason.NONE): Promise<void> {
+  public stop(): void {
     if (!this.started) {
       logger.error(`${this.logPrefix()} trying to stop while not started`);
       return;
     }
-    logger.info(`${this.logPrefix()} over and lasted for ${Utils.formatDurationMilliSeconds(this.lastRunDate.getTime() - this.startDate.getTime())}. Stopping all transactions`);
-    for (const connector in this.chargingStation.connectors) {
-      const transactionId = this.chargingStation.getConnector(Utils.convertToInt(connector)).transactionId;
-      if (this.chargingStation.getConnector(Utils.convertToInt(connector)).transactionStarted) {
-        logger.info(this.logPrefix(Utils.convertToInt(connector)) + ' over. Stop transaction ' + transactionId.toString());
-        await this.chargingStation.ocppRequestService.sendStopTransaction(transactionId, this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
-          this.chargingStation.getTransactionIdTag(transactionId), reason);
-      }
-    }
     this.started = false;
+    logger.info(`${this.logPrefix()} over and lasted for ${Utils.formatDurationMilliSeconds(this.lastRunDate.getTime() - this.startDate.getTime())}. Stopping all transactions`);
   }
 
   private async startOnConnector(connectorId: number): Promise<void> {
@@ -61,7 +54,7 @@ export default class AutomaticTransactionGenerator {
     let skippedTransactionsTotal = 0;
     while (this.started) {
       if ((new Date()) > this.stopDate) {
-        await this.stop();
+        this.stop();
         break;
       }
       if (!this.chargingStation.isRegistered()) {
@@ -70,7 +63,7 @@ export default class AutomaticTransactionGenerator {
       }
       if (!this.chargingStation.isChargingStationAvailable()) {
         logger.info(this.logPrefix(connectorId) + ' Entered in transaction loop while the charging station is unavailable');
-        await this.stop();
+        this.stop();
         break;
       }
       if (!this.chargingStation.isConnectorAvailable(connectorId)) {
@@ -114,6 +107,7 @@ export default class AutomaticTransactionGenerator {
       }
       this.lastRunDate = new Date();
     }
+    await this.stopTransaction(connectorId);
     logger.info(this.logPrefix(connectorId) + ' stopped on connector');
   }
 
@@ -148,12 +142,19 @@ export default class AutomaticTransactionGenerator {
     return startResponse;
   }
 
-  private async stopTransaction(connectorId: number): Promise<StopTransactionResponse> {
+  private async stopTransaction(connectorId: number, reason: StopTransactionReason = StopTransactionReason.NONE): Promise<StopTransactionResponse> {
     const measureId = 'StopTransaction with ATG';
     const beginId = PerformanceStatistics.beginMeasure(measureId);
     const transactionId = this.chargingStation.getConnector(connectorId).transactionId;
-    const stopResponse = this.chargingStation.ocppRequestService.sendStopTransaction(transactionId,
-      this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId), this.chargingStation.getTransactionIdTag(transactionId));
+    let stopResponse: StopTransactionResponse;
+    if (this.chargingStation.getConnector(connectorId)?.transactionStarted) {
+      stopResponse = await this.chargingStation.ocppRequestService.sendStopTransaction(transactionId,
+        this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
+        this.chargingStation.getTransactionIdTag(transactionId),
+        reason);
+    } else {
+      logger.warn(`${this.logPrefix(connectorId)} trying to stop a not started transaction ${transactionId}`);
+    }
     PerformanceStatistics.endMeasure(measureId, beginId);
     return stopResponse;
   }
index 79336707c621f0785e14baa78f860f4bbb260a9a..38b89249e86f7da308b6334465a418def18332a6 100644 (file)
@@ -880,7 +880,7 @@ export default class ChargingStation {
     if (this.stationInfo.AutomaticTransactionGenerator.enable &&
       this.automaticTransactionGenerator &&
       this.automaticTransactionGenerator.started) {
-      await this.automaticTransactionGenerator.stop(reason);
+      this.automaticTransactionGenerator.stop();
     } else {
       for (const connector in this.connectors) {
         if (Utils.convertToInt(connector) > 0 && this.getConnector(Utils.convertToInt(connector)).transactionStarted) {
@@ -1012,7 +1012,7 @@ export default class ChargingStation {
             // Restart the ATG
             if (!this.stationInfo.AutomaticTransactionGenerator.enable &&
                 this.automaticTransactionGenerator) {
-              await this.automaticTransactionGenerator.stop();
+              this.automaticTransactionGenerator.stop();
             }
             this.startAutomaticTransactionGenerator();
             if (this.getEnableStatistics()) {
@@ -1045,7 +1045,7 @@ export default class ChargingStation {
       this.stationInfo.AutomaticTransactionGenerator.stopOnConnectionFailure &&
       this.automaticTransactionGenerator &&
       this.automaticTransactionGenerator.started) {
-      await this.automaticTransactionGenerator.stop();
+      this.automaticTransactionGenerator.stop();
     }
     if (this.autoReconnectRetryCount < this.getAutoReconnectMaxRetries() || this.getAutoReconnectMaxRetries() === -1) {
       this.autoReconnectRetryCount++;
index d17c21d3805945bc94bc93534d4c2eca2a698f33..9220d0cd8ac36cac67034803581c8ff27f9e74a4 100644 (file)
@@ -80,7 +80,6 @@ export default abstract class OCPPRequestService {
         }
         logger.debug(`${self.chargingStation.logPrefix()} Error: %j occurred when calling command %s with parameters: %j`, error, commandName, commandParams);
         // Build Exception
-        // eslint-disable-next-line no-empty-function
         self.chargingStation.requests.set(messageId, [() => { /* This is intentiomal */ }, () => { /* This is intentiomal */ }, {}]);
         // Send error
         reject(error);
index 429f61d53a63b12d4eb71cacd23e2ed815c29bd0..5ed114849638bef2432b3e5c6cc955b1cb6b334e 100644 (file)
@@ -7,7 +7,6 @@ import { Storage } from './Storage';
 import { StorageType } from '../../types/Storage';
 
 export class StorageFactory {
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
   private constructor() {
     // This is intentional
   }
index e5119ff6a0c32020dbabdd4a38ca5ae93a700e0d..f081b3c3018ae0f144001b3138e355fbff52e159 100644 (file)
@@ -37,7 +37,6 @@ export default class WorkerDynamicPool<T> extends WorkerAbstract {
    * @returns
    * @public
    */
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
   public async start(): Promise<void> {
     // This is intentional
   }
index 55cb1da7a55fe2cf50d5b282d1ba703aa8f54c4a..8b979d06ca2d76f8e4d0220132b03dafd8a6bf84 100644 (file)
@@ -9,7 +9,6 @@ import WorkerSet from './WorkerSet';
 import WorkerStaticPool from './WorkerStaticPool';
 
 export default class WorkerFactory {
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
   private constructor() {
     // This is intentional
   }
index b782f3111a382e568b965351d080e204c88b0f4d..f25fd03c4872849fc0863fb9806864e44dc45da1 100644 (file)
@@ -94,7 +94,6 @@ export default class WorkerSet<T> extends WorkerAbstract {
 
   private getLastWorkerSetElement(): WorkerSetElement {
     let workerSetElement: WorkerSetElement;
-    // eslint-disable-next-line no-empty
     for (workerSetElement of this.workerSet) { /* This is intentional */ }
     return workerSetElement;
   }
index e4a8910ba8dc103b8170a21b6a15620e648a435d..cbc62fb63bfe45be928c5810c67c22bb862297de 100644 (file)
@@ -36,7 +36,6 @@ export default class WorkerStaticPool<T> extends WorkerAbstract {
    * @returns
    * @public
    */
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
   public async start(): Promise<void> {
     // This is intentional
   }