fix: fix ATG refresh at template changes
authorJérôme Benoit <jerome.benoit@sap.com>
Sun, 30 Apr 2023 15:03:05 +0000 (17:03 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sun, 30 Apr 2023 15:03:05 +0000 (17:03 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
package.json
pnpm-lock.yaml
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/ChargingStationUtils.ts
src/charging-station/MessageChannelUtils.ts
src/charging-station/SharedLRUCache.ts
src/types/index.ts
ui/web/pnpm-lock.yaml

index 2cef1aea2ab9b2f6355e454e8f571aa8ab093508..f6c55269fb3511779f04676951424de319a6dee9 100644 (file)
     "mocha": "^10.2.0",
     "mochawesome": "^7.1.3",
     "prettier": "^2.8.8",
-    "release-it": "^15.10.1",
+    "release-it": "^15.10.2",
     "rimraf": "^5.0.0",
     "robohydra": "^0.6.9",
-    "rollup": "^3.21.1",
+    "rollup": "^3.21.2",
     "rollup-plugin-analyzer": "^4.0.0",
     "rollup-plugin-copy": "^3.4.0",
     "rollup-plugin-delete": "^2.0.0",
index 02d13c0663f8105e298a180c2de2e3e302bfecb1..dcd22637ea6a9bd4e0228e5f01a72c1b23eece10 100644 (file)
@@ -91,16 +91,16 @@ devDependencies:
     version: 5.7.3(@mikro-orm/mariadb@5.7.3)(@mikro-orm/sqlite@5.7.3)
   '@release-it/bumper':
     specifier: ^4.0.2
-    version: 4.0.2(release-it@15.10.1)
+    version: 4.0.2(release-it@15.10.2)
   '@rollup/plugin-json':
     specifier: ^6.0.0
-    version: 6.0.0(rollup@3.21.1)
+    version: 6.0.0(rollup@3.21.2)
   '@rollup/plugin-terser':
     specifier: ^0.4.1
-    version: 0.4.1(rollup@3.21.1)
+    version: 0.4.1(rollup@3.21.2)
   '@rollup/plugin-typescript':
     specifier: ^11.1.0
-    version: 11.1.0(rollup@3.21.1)(tslib@2.5.0)(typescript@5.0.4)
+    version: 11.1.0(rollup@3.21.2)(tslib@2.5.0)(typescript@5.0.4)
   '@types/mocha':
     specifier: ^10.0.1
     version: 10.0.1
@@ -183,8 +183,8 @@ devDependencies:
     specifier: ^2.8.8
     version: 2.8.8
   release-it:
-    specifier: ^15.10.1
-    version: 15.10.1
+    specifier: ^15.10.2
+    version: 15.10.2
   rimraf:
     specifier: ^5.0.0
     version: 5.0.0
@@ -192,8 +192,8 @@ devDependencies:
     specifier: ^0.6.9
     version: 0.6.9(bufferutil@4.0.7)(utf-8-validate@6.0.3)
   rollup:
-    specifier: ^3.21.1
-    version: 3.21.1
+    specifier: ^3.21.2
+    version: 3.21.2
   rollup-plugin-analyzer:
     specifier: ^4.0.0
     version: 4.0.0
@@ -623,8 +623,8 @@ packages:
       eslint-visitor-keys: 3.4.0
     dev: true
 
-  /@eslint-community/regexpp@4.5.0:
-    resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==}
+  /@eslint-community/regexpp@4.5.1:
+    resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
     dev: true
 
@@ -1216,7 +1216,7 @@ packages:
       config-chain: 1.1.13
     dev: true
 
-  /@release-it/bumper@4.0.2(release-it@15.10.1):
+  /@release-it/bumper@4.0.2(release-it@15.10.2):
     resolution: {integrity: sha512-HjiFIBNvb67cLTbzdm6EqiSRwpB4MJY4TGJFY/ac5qnIxERWK5gx1zBnwbJZffDSoS46hJMugoXrDbITEfX4gA==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -1230,11 +1230,11 @@ packages:
       lodash.castarray: 4.4.0
       lodash.get: 4.4.2
       lodash.set: 4.3.2
-      release-it: 15.10.1
+      release-it: 15.10.2
       semver: 7.5.0
     dev: true
 
-  /@rollup/plugin-json@6.0.0(rollup@3.21.1):
+  /@rollup/plugin-json@6.0.0(rollup@3.21.2):
     resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1243,11 +1243,11 @@ packages:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.2(rollup@3.21.1)
-      rollup: 3.21.1
+      '@rollup/pluginutils': 5.0.2(rollup@3.21.2)
+      rollup: 3.21.2
     dev: true
 
-  /@rollup/plugin-terser@0.4.1(rollup@3.21.1):
+  /@rollup/plugin-terser@0.4.1(rollup@3.21.2):
     resolution: {integrity: sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1256,13 +1256,13 @@ packages:
       rollup:
         optional: true
     dependencies:
-      rollup: 3.21.1
+      rollup: 3.21.2
       serialize-javascript: 6.0.1
       smob: 0.0.6
       terser: 5.17.1
     dev: true
 
-  /@rollup/plugin-typescript@11.1.0(rollup@3.21.1)(tslib@2.5.0)(typescript@5.0.4):
+  /@rollup/plugin-typescript@11.1.0(rollup@3.21.2)(tslib@2.5.0)(typescript@5.0.4):
     resolution: {integrity: sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1275,14 +1275,14 @@ packages:
       tslib:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.2(rollup@3.21.1)
+      '@rollup/pluginutils': 5.0.2(rollup@3.21.2)
       resolve: 1.22.2
-      rollup: 3.21.1
+      rollup: 3.21.2
       tslib: 2.5.0
       typescript: 5.0.4
     dev: true
 
-  /@rollup/pluginutils@5.0.2(rollup@3.21.1):
+  /@rollup/pluginutils@5.0.2(rollup@3.21.2):
     resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1294,7 +1294,7 @@ packages:
       '@types/estree': 1.0.1
       estree-walker: 2.0.2
       picomatch: 2.3.1
-      rollup: 3.21.1
+      rollup: 3.21.2
     dev: true
 
   /@sinclair/typebox@0.25.24:
@@ -1592,7 +1592,7 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@eslint-community/regexpp': 4.5.0
+      '@eslint-community/regexpp': 4.5.1
       '@typescript-eslint/parser': 5.59.1(eslint@8.39.0)(typescript@5.0.4)
       '@typescript-eslint/scope-manager': 5.59.1
       '@typescript-eslint/type-utils': 5.59.1(eslint@8.39.0)(typescript@5.0.4)
@@ -4170,7 +4170,7 @@ packages:
     hasBin: true
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.39.0)
-      '@eslint-community/regexpp': 4.5.0
+      '@eslint-community/regexpp': 4.5.1
       '@eslint/eslintrc': 2.0.2
       '@eslint/js': 8.39.0
       '@humanwhocodes/config-array': 0.11.8
@@ -4932,17 +4932,6 @@ packages:
       merge2: 1.4.1
       slash: 3.0.0
 
-  /globby@13.1.3:
-    resolution: {integrity: sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-    dependencies:
-      dir-glob: 3.0.1
-      fast-glob: 3.2.12
-      ignore: 5.2.4
-      merge2: 1.4.1
-      slash: 4.0.0
-    dev: true
-
   /globby@13.1.4:
     resolution: {integrity: sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -5399,8 +5388,8 @@ packages:
       through: 2.3.8
     dev: true
 
-  /inquirer@9.1.5:
-    resolution: {integrity: sha512-3ygAIh8gcZavV9bj6MTdYddG2zPSYswP808fKS46NOwlF0zZljVpnLCHODDqItWJDbDpLb3aouAxGaJbkxoppA==}
+  /inquirer@9.2.0:
+    resolution: {integrity: sha512-WWERbVqjsTXjXub1ZW0ZHDit1dyHqy0T9XIkky9TnmKAPrjU9Jkd59nZPK0dUuM3s73GZAZu2Jo4iFU3XSPVLA==}
     engines: {node: '>=14.18.0'}
     dependencies:
       ansi-escapes: 6.2.0
@@ -8272,8 +8261,8 @@ packages:
     resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==}
     dev: true
 
-  /release-it@15.10.1:
-    resolution: {integrity: sha512-Wkk4aFHSo27vQwHIlcEy77lJwnQlh4UDQckc53gh5tKo7F22mAUEAe8SYQZJcFh7icdkf0OV70onhB1dDmeClA==}
+  /release-it@15.10.2:
+    resolution: {integrity: sha512-fm1MtEG6IFxMMmOhUzpw9FTx8k9Ln5iiM+bikjrg3oZ5JLJO1uR1yxloPqc4A2gIXUq+bQp8/g4wipOwgDmEcw==}
     engines: {node: '>=14.9'}
     hasBin: true
     dependencies:
@@ -8284,9 +8273,9 @@ packages:
       cosmiconfig: 8.1.3
       execa: 7.1.1
       git-url-parse: 13.1.0
-      globby: 13.1.3
+      globby: 13.1.4
       got: 12.6.0
-      inquirer: 9.1.5
+      inquirer: 9.2.0
       is-ci: 3.0.1
       issue-parser: 6.0.0
       lodash: 4.17.21
@@ -8298,7 +8287,7 @@ packages:
       os-name: 5.1.0
       promise.allsettled: 1.0.6
       proxy-agent: 5.0.0
-      semver: 7.3.8
+      semver: 7.5.0
       shelljs: 0.8.5
       update-notifier: 6.0.2
       url-join: 5.0.0
@@ -8505,8 +8494,8 @@ packages:
       del: 5.1.0
     dev: true
 
-  /rollup@3.21.1:
-    resolution: {integrity: sha512-GpUgqWCw56OSiBKf7lcAITstYiBV1/EKaKYPl9r8HgAxc6/qYAVw1PaHWnvHWFziRaf4HsVCDLq/IGtBi1K/Zw==}
+  /rollup@3.21.2:
+    resolution: {integrity: sha512-c4vC+JZ3bbF4Kqq2TtM7zSKtSyMybFOjqmomFax3xpfYaPZDZ4iz8NMIuBRMjnXOcKYozw7bC6vhJjiWD6JpzQ==}
     engines: {node: '>=14.18.0', npm: '>=8.0.0'}
     hasBin: true
     optionalDependencies:
index d928a623d27c3567b28c1b392cd49520caefa436..8b9ae7cee30e1110badce18017d87f9fa8a1ca69 100644 (file)
@@ -10,7 +10,6 @@ import {
   AuthorizationStatus,
   type AuthorizeRequest,
   type AuthorizeResponse,
-  type AutomaticTransactionGeneratorConfiguration,
   ConnectorStatusEnum,
   RequestCommand,
   type StartTransactionRequest,
@@ -30,33 +29,24 @@ export class AutomaticTransactionGenerator extends AsyncResource {
   >();
 
   public readonly connectorsStatus: Map<number, Status>;
-  public readonly configuration: AutomaticTransactionGeneratorConfiguration;
   public started: boolean;
   private readonly chargingStation: ChargingStation;
 
-  private constructor(
-    automaticTransactionGeneratorConfiguration: AutomaticTransactionGeneratorConfiguration,
-    chargingStation: ChargingStation
-  ) {
+  private constructor(chargingStation: ChargingStation) {
     super(moduleName);
     this.started = false;
-    this.configuration = automaticTransactionGeneratorConfiguration;
     this.chargingStation = chargingStation;
     this.connectorsStatus = new Map<number, Status>();
     this.initializeConnectorsStatus();
   }
 
   public static getInstance(
-    automaticTransactionGeneratorConfiguration: AutomaticTransactionGeneratorConfiguration,
     chargingStation: ChargingStation
   ): AutomaticTransactionGenerator | undefined {
     if (AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo.hashId) === false) {
       AutomaticTransactionGenerator.instances.set(
         chargingStation.stationInfo.hashId,
-        new AutomaticTransactionGenerator(
-          automaticTransactionGeneratorConfiguration,
-          chargingStation
-        )
+        new AutomaticTransactionGenerator(chargingStation)
       );
     }
     return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo.hashId);
@@ -233,23 +223,30 @@ export class AutomaticTransactionGenerator extends AsyncResource {
       }
       const wait =
         Utils.getRandomInteger(
-          this.configuration.maxDelayBetweenTwoTransactions,
-          this.configuration.minDelayBetweenTwoTransactions
+          this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
+            .maxDelayBetweenTwoTransactions,
+          this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
+            .minDelayBetweenTwoTransactions
         ) * 1000;
       logger.info(
         `${this.logPrefix(connectorId)} waiting for ${Utils.formatDurationMilliSeconds(wait)}`
       );
       await Utils.sleep(wait);
       const start = Utils.secureRandom();
-      if (start < this.configuration.probabilityOfStart) {
+      if (
+        start <
+        this.chargingStation.getAutomaticTransactionGeneratorConfiguration().probabilityOfStart
+      ) {
         this.connectorsStatus.get(connectorId).skippedConsecutiveTransactions = 0;
         // Start transaction
         const startResponse = await this.startTransaction(connectorId);
         if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
           // Wait until end of transaction
           const waitTrxEnd =
-            Utils.getRandomInteger(this.configuration.maxDuration, this.configuration.minDuration) *
-            1000;
+            Utils.getRandomInteger(
+              this.chargingStation.getAutomaticTransactionGeneratorConfiguration().maxDuration,
+              this.chargingStation.getAutomaticTransactionGeneratorConfiguration().minDuration
+            ) * 1000;
           logger.info(
             `${this.logPrefix(connectorId)} transaction started with id ${this.chargingStation
               .getConnectorStatus(connectorId)
@@ -305,7 +302,7 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     this.connectorsStatus.get(connectorId).startDate = new Date();
     this.connectorsStatus.get(connectorId).stopDate = new Date(
       this.connectorsStatus.get(connectorId).startDate.getTime() +
-        (this.configuration.stopAfterHours ??
+        (this.chargingStation.getAutomaticTransactionGeneratorConfiguration().stopAfterHours ??
           Constants.CHARGING_STATION_ATG_DEFAULT_STOP_AFTER_HOURS) *
           3600 *
           1000 -
@@ -366,7 +363,7 @@ export class AutomaticTransactionGenerator extends AsyncResource {
     let startResponse: StartTransactionResponse;
     if (this.chargingStation.hasIdTags()) {
       const idTag = IdTagsCache.getInstance().getIdTag(
-        this.configuration?.idTagDistribution,
+        this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.idTagDistribution,
         this.chargingStation,
         connectorId
       );
@@ -454,7 +451,9 @@ export class AutomaticTransactionGenerator extends AsyncResource {
   }
 
   private getRequireAuthorize(): boolean {
-    return this.configuration?.requireAuthorize ?? true;
+    return (
+      this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.requireAuthorize ?? true
+    );
   }
 
   private logPrefix = (connectorId?: number): string => {
index 2456d0d6965175a2a1ce366e4cbb7b25a6c90e28..56ce26a19e55fd6e5478636264ca832c8c3d3ace 100644 (file)
@@ -42,6 +42,7 @@ import {
   type BootNotificationRequest,
   type BootNotificationResponse,
   type CachedRequest,
+  type ChargingStationAutomaticTransactionGeneratorConfiguration,
   type ChargingStationConfiguration,
   type ChargingStationInfo,
   type ChargingStationOcppConfiguration,
@@ -316,10 +317,7 @@ export class ChargingStation {
       this.logPrefix(),
       this.templateFile
     );
-    const localStationInfo: ChargingStationInfo = stationInfo ?? this.stationInfo;
-    return !Utils.isUndefined(localStationInfo.voltageOut)
-      ? localStationInfo.voltageOut
-      : defaultVoltageOut;
+    return (stationInfo ?? this.stationInfo).voltageOut ?? defaultVoltageOut;
   }
 
   public getMaximumPower(stationInfo?: ChargingStationInfo): number {
@@ -658,9 +656,7 @@ export class ChargingStation {
                 this.initialize();
                 // Restart the ATG
                 this.stopAutomaticTransactionGenerator();
-                if (
-                  this.getAutomaticTransactionGeneratorConfigurationFromTemplate()?.enable === true
-                ) {
+                if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
                   this.startAutomaticTransactionGenerator();
                 }
                 if (this.getEnableStatistics() === true) {
@@ -703,6 +699,7 @@ export class ChargingStation {
         this.sharedLRUCache.deleteChargingStationTemplate(this.templateFileHash);
         delete this.bootNotificationResponse;
         this.started = false;
+        this.saveConfiguration();
         parentPort?.postMessage(MessageChannelUtils.buildStoppedMessage(this));
         this.stopping = false;
       } else {
@@ -812,15 +809,19 @@ export class ChargingStation {
     }
   }
 
-  public startAutomaticTransactionGenerator(
-    connectorIds?: number[],
-    automaticTransactionGeneratorConfiguration?: AutomaticTransactionGeneratorConfiguration
-  ): void {
-    this.automaticTransactionGenerator = AutomaticTransactionGenerator.getInstance(
-      automaticTransactionGeneratorConfiguration ??
-        this.getAutomaticTransactionGeneratorConfigurationFromTemplate(),
-      this
-    );
+  public getAutomaticTransactionGeneratorConfiguration():
+    | AutomaticTransactionGeneratorConfiguration
+    | undefined {
+    const automaticTransactionGeneratorConfigurationFromFile =
+      this.getConfigurationFromFile()?.automaticTransactionGenerator;
+    if (automaticTransactionGeneratorConfigurationFromFile) {
+      return automaticTransactionGeneratorConfigurationFromFile;
+    }
+    return this.getTemplateFromFile()?.AutomaticTransactionGenerator;
+  }
+
+  public startAutomaticTransactionGenerator(connectorIds?: number[]): void {
+    this.automaticTransactionGenerator = AutomaticTransactionGenerator.getInstance(this);
     if (Utils.isNotEmptyArray(connectorIds)) {
       for (const connectorId of connectorIds) {
         this.automaticTransactionGenerator?.startConnector(connectorId);
@@ -828,6 +829,7 @@ export class ChargingStation {
     } else {
       this.automaticTransactionGenerator?.start();
     }
+    this.saveChargingStationAutomaticTransactionGeneratorConfiguration();
     parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
   }
 
@@ -839,6 +841,7 @@ export class ChargingStation {
     } else {
       this.automaticTransactionGenerator?.stop();
     }
+    this.saveChargingStationAutomaticTransactionGeneratorConfiguration();
     parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
   }
 
@@ -1523,6 +1526,20 @@ export class ChargingStation {
     return configuration;
   }
 
+  private saveChargingStationAutomaticTransactionGeneratorConfiguration(
+    stationTemplate?: ChargingStationTemplate
+  ): void {
+    this.saveConfiguration({
+      automaticTransactionGenerator: (stationTemplate ?? this.getTemplateFromFile())
+        .AutomaticTransactionGenerator,
+      ...(!Utils.isNullOrUndefined(this.automaticTransactionGenerator?.connectorsStatus) && {
+        automaticTransactionGeneratorStatuses: [
+          ...this.automaticTransactionGenerator.connectorsStatus.values(),
+        ],
+      }),
+    });
+  }
+
   private saveConnectorsStatus() {
     this.saveConfiguration();
   }
@@ -1531,13 +1548,15 @@ export class ChargingStation {
     this.saveConfiguration();
   }
 
-  private saveConfiguration(): void {
+  private saveConfiguration(
+    chargingStationAutomaticTransactionGeneratorConfiguration?: ChargingStationAutomaticTransactionGeneratorConfiguration
+  ): void {
     if (this.configurationFile) {
       try {
         if (!fs.existsSync(path.dirname(this.configurationFile))) {
           fs.mkdirSync(path.dirname(this.configurationFile), { recursive: true });
         }
-        const configurationData: ChargingStationConfiguration =
+        let configurationData: ChargingStationConfiguration =
           Utils.cloneObject(this.getConfigurationFromFile()) ?? {};
         if (this.getStationInfoPersistentConfiguration() && this.stationInfo) {
           configurationData.stationInfo = this.stationInfo;
@@ -1545,6 +1564,12 @@ export class ChargingStation {
         if (this.getOcppPersistentConfiguration() && this.ocppConfiguration?.configurationKey) {
           configurationData.configurationKey = this.ocppConfiguration.configurationKey;
         }
+        if (chargingStationAutomaticTransactionGeneratorConfiguration) {
+          configurationData = merge<ChargingStationConfiguration>(
+            configurationData,
+            chargingStationAutomaticTransactionGeneratorConfiguration
+          );
+        }
         if (this.connectors.size > 0) {
           configurationData.connectorsStatus = [...this.connectors.values()].map(
             // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -1616,6 +1641,8 @@ export class ChargingStation {
       delete configuration.stationInfo;
       delete configuration.connectorsStatus;
       delete configuration.evsesStatus;
+      delete configuration.automaticTransactionGenerator;
+      delete configuration.automaticTransactionGeneratorStatuses;
       delete configuration.configurationHash;
     }
     return configuration;
@@ -2037,7 +2064,7 @@ export class ChargingStation {
     }
 
     // Start the ATG
-    if (this.getAutomaticTransactionGeneratorConfigurationFromTemplate()?.enable === true) {
+    if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
       this.startAutomaticTransactionGenerator();
     }
     this.wsConnectionRestarted === true && this.flushMessageBuffer();
@@ -2191,7 +2218,7 @@ export class ChargingStation {
     // Stop heartbeat
     this.stopHeartbeat();
     // Stop the ATG if needed
-    if (this.automaticTransactionGenerator?.configuration?.stopOnConnectionFailure === true) {
+    if (this.getAutomaticTransactionGeneratorConfiguration().stopOnConnectionFailure === true) {
       this.stopAutomaticTransactionGenerator();
     }
     if (
@@ -2233,10 +2260,4 @@ export class ChargingStation {
       );
     }
   }
-
-  private getAutomaticTransactionGeneratorConfigurationFromTemplate():
-    | AutomaticTransactionGeneratorConfiguration
-    | undefined {
-    return this.getTemplateFromFile()?.AutomaticTransactionGenerator;
-  }
 }
index dbfbe41fdfd2981bb35ab238e8d4e10c614bb035..4084a484864006c46d964c6e895751a2da57cb97 100644 (file)
@@ -168,6 +168,21 @@ export class ChargingStationUtils {
       logger.error(`${logPrefix} ${errorMsg}`);
       throw new BaseError(errorMsg);
     }
+    if (Utils.isEmptyObject(stationTemplate.AutomaticTransactionGenerator)) {
+      stationTemplate.AutomaticTransactionGenerator = {
+        enable: false,
+        minDuration: 60,
+        maxDuration: 120,
+        minDelayBetweenTwoTransactions: 15,
+        maxDelayBetweenTwoTransactions: 30,
+        probabilityOfStart: 1,
+        stopAfterHours: 0.3,
+        stopOnConnectionFailure: true,
+      };
+      logger.warn(
+        `${logPrefix} Empty automatic transaction generator configuration from template file ${templateFile}, set to default values`
+      );
+    }
   }
 
   public static checkConnectorsConfiguration(
index 28bfa8c6b89cf9fe1382594cf2bcbf07b85867bd..11ecd3ca5644662db9cd45c351c8cbd087ed4615 100644 (file)
@@ -72,7 +72,7 @@ export class MessageChannelUtils {
       ...(chargingStation.automaticTransactionGenerator && {
         automaticTransactionGenerator: {
           automaticTransactionGenerator:
-            chargingStation.automaticTransactionGenerator.configuration,
+            chargingStation.getAutomaticTransactionGeneratorConfiguration(),
           automaticTransactionGeneratorStatuses: [
             ...chargingStation.automaticTransactionGenerator.connectorsStatus.values(),
           ],
index bb1c0c07e3749e99b6ee76a4d8e3486696f6eac4..1243d6aebe4409d40dda5439bf01ced413ab594c 100644 (file)
@@ -111,9 +111,12 @@ export class SharedLRUCache {
     return (
       Utils.isNullOrUndefined(chargingStationConfiguration?.configurationKey) === false &&
       Utils.isNullOrUndefined(chargingStationConfiguration?.stationInfo) === false &&
+      Utils.isNullOrUndefined(chargingStationConfiguration?.automaticTransactionGenerator) ===
+        false &&
       Utils.isNullOrUndefined(chargingStationConfiguration?.configurationHash) === false &&
       Utils.isNotEmptyArray(chargingStationConfiguration?.configurationKey) === true &&
       Utils.isEmptyObject(chargingStationConfiguration?.stationInfo) === false &&
+      Utils.isEmptyObject(chargingStationConfiguration?.automaticTransactionGenerator) === false &&
       Utils.isNotEmptyString(chargingStationConfiguration?.configurationHash) === true
     );
   }
index b750cf35c1798445fc2877b65b46d1d9c2a4fd15..0b54ba11ea0ccd54823608eb3f089d19c9251c36 100644 (file)
@@ -27,6 +27,7 @@ export {
   ChargingProfileStatus,
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
+  type ChargingStationAutomaticTransactionGeneratorConfiguration,
   type ChargingStationConfiguration,
   type ChargingStationData,
   type ChargingStationInfo,
index 4f392a0b9dae909f8e1243b7bb80be6e76f3354b..b9e13d3f6591820b600c3a6cb6a0af484ae1abd5 100644 (file)
@@ -587,8 +587,8 @@ packages:
       eslint-visitor-keys: 3.4.0
     dev: true
 
-  /@eslint-community/regexpp@4.5.0:
-    resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==}
+  /@eslint-community/regexpp@4.5.1:
+    resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
     dev: true
 
@@ -750,7 +750,7 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@eslint-community/regexpp': 4.5.0
+      '@eslint-community/regexpp': 4.5.1
       '@typescript-eslint/parser': 5.59.1(eslint@8.39.0)(typescript@5.0.4)
       '@typescript-eslint/scope-manager': 5.59.1
       '@typescript-eslint/type-utils': 5.59.1(eslint@8.39.0)(typescript@5.0.4)
@@ -1626,7 +1626,7 @@ packages:
     hasBin: true
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.39.0)
-      '@eslint-community/regexpp': 4.5.0
+      '@eslint-community/regexpp': 4.5.1
       '@eslint/eslintrc': 2.0.2
       '@eslint/js': 8.39.0
       '@humanwhocodes/config-array': 0.11.8
@@ -2592,8 +2592,8 @@ packages:
       glob: 10.2.2
     dev: true
 
-  /rollup@3.21.1:
-    resolution: {integrity: sha512-GpUgqWCw56OSiBKf7lcAITstYiBV1/EKaKYPl9r8HgAxc6/qYAVw1PaHWnvHWFziRaf4HsVCDLq/IGtBi1K/Zw==}
+  /rollup@3.21.2:
+    resolution: {integrity: sha512-c4vC+JZ3bbF4Kqq2TtM7zSKtSyMybFOjqmomFax3xpfYaPZDZ4iz8NMIuBRMjnXOcKYozw7bC6vhJjiWD6JpzQ==}
     engines: {node: '>=14.18.0', npm: '>=8.0.0'}
     hasBin: true
     optionalDependencies:
@@ -2971,7 +2971,7 @@ packages:
       '@types/node': 18.16.3
       esbuild: 0.17.18
       postcss: 8.4.23
-      rollup: 3.21.1
+      rollup: 3.21.2
     optionalDependencies:
       fsevents: 2.3.2
     dev: true