Track ATG status on a per connector basis.
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 25 Sep 2021 16:16:43 +0000 (18:16 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 25 Sep 2021 16:16:43 +0000 (18:16 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
docker/Dockerfile
docker/docker-compose.yml
manifest-cf-template.yml
package-lock.json
package.json
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16RequestService.ts
src/utils/Utils.ts

index c132990575bf3be3ca891b1a23730fb4ba794e22..c8a684fa30c56de9e76a513c10fc34d4d9d4ecfb 100644 (file)
@@ -13,11 +13,12 @@ RUN npm run build
 
 FROM node:lts-alpine
 
+ARG STACK_TRACE_LIMIT
 ARG MAX_OLD_SPACE_SIZE
 
 WORKDIR /usr/app
 
-ENV NODE_OPTIONS=--max-old-space-size=${MAX_OLD_SPACE_SIZE}
+ENV NODE_OPTIONS="--stack-trace-limit=${STACK_TRACE_LIMIT} --max-old-space-size=${MAX_OLD_SPACE_SIZE}"
 
 COPY --from=builder /usr/builder/node_modules ./node_modules
 COPY --from=builder /usr/builder/dist ./dist
index ebc8d8b9f8d6e1e57c93bbdfa116e043690df780..55c0526e5fa681753549fa60ce0e34c8f8bb4afc 100644 (file)
@@ -8,6 +8,7 @@ services:
       context: ..
       dockerfile: docker/Dockerfile
       args:
+        STACK_TRACE_LIMIT: 1024
         MAX_OLD_SPACE_SIZE: 1024
     networks:
       - ev_network
index b4bcbc0b6a866b4e75216e9da2abd3ecb2ef2418..42c8b2996a1ab78da5ebfdfa7e86ab96f6180201 100644 (file)
@@ -11,4 +11,4 @@ applications:
   command: node -r source-map-support/register dist/start.js
   env:
     # OPTIMIZE_MEMORY: true
-    NODE_OPTIONS: --max-old-space-size=512
+    NODE_OPTIONS: --stack-trace-limit=1024 --max-old-space-size=512
index bdf8bca96d3eaf679f08b97216366adfd7add894..8097dc2dbdcc55df34cf74682f7ba61c757a3551 100644 (file)
       }
     },
     "@types/node": {
-      "version": "14.17.18",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.18.tgz",
-      "integrity": "sha512-haYyibw4pbteEhkSg0xdDLAI3679L75EJ799ymVrPxOA922bPx3ML59SoDsQ//rHlvqpu+e36kcbR3XRQtFblA=="
+      "version": "14.17.19",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.19.tgz",
+      "integrity": "sha512-jjYI6NkyfXykucU6ELEoT64QyKOdvaA6enOqKtP4xUsGY0X0ZUZz29fUmrTRo+7v7c6TgDu82q3GHHaCEkqZwA=="
     },
     "@types/object-path": {
       "version": "0.11.1",
       }
     },
     "expect": {
-      "version": "27.2.1",
-      "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.1.tgz",
-      "integrity": "sha512-ekOA2mBtT2phxcoPVHCXIzbJxCvRXhx2fr7m28IgGdZxUOh8UvxvoRz1FcPlfgZMpE92biHB6woIcAKXqR28hA==",
+      "version": "27.2.2",
+      "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.2.tgz",
+      "integrity": "sha512-sjHBeEk47/eshN9oLbvPJZMgHQihOXXQzSMPCJ4MqKShbU9HOVFSNHEEU4dp4ujzxFSiNvPFzB2AMOFmkizhvA==",
       "dev": true,
       "requires": {
         "@jest/types": "^27.1.1",
         "ansi-styles": "^5.0.0",
         "jest-get-type": "^27.0.6",
-        "jest-matcher-utils": "^27.2.0",
-        "jest-message-util": "^27.2.0",
+        "jest-matcher-utils": "^27.2.2",
+        "jest-message-util": "^27.2.2",
         "jest-regex-util": "^27.0.6"
       },
       "dependencies": {
       }
     },
     "jest-diff": {
-      "version": "27.2.0",
-      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.0.tgz",
-      "integrity": "sha512-QSO9WC6btFYWtRJ3Hac0sRrkspf7B01mGrrQEiCW6TobtViJ9RWL0EmOs/WnBsZDsI/Y2IoSHZA2x6offu0sYw==",
+      "version": "27.2.2",
+      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.2.tgz",
+      "integrity": "sha512-o3LaDbQDSaMJif4yztJAULI4xVatxbBasbKLbEw3K8CiRdDdbxMrLArS9EKDHQFYh6Tgfrm1PC2mIYR1xhu0hQ==",
       "dev": true,
       "requires": {
         "chalk": "^4.0.0",
         "diff-sequences": "^27.0.6",
         "jest-get-type": "^27.0.6",
-        "pretty-format": "^27.2.0"
+        "pretty-format": "^27.2.2"
       }
     },
     "jest-get-type": {
       "dev": true
     },
     "jest-matcher-utils": {
-      "version": "27.2.0",
-      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.0.tgz",
-      "integrity": "sha512-F+LG3iTwJ0gPjxBX6HCyrARFXq6jjiqhwBQeskkJQgSLeF1j6ui1RTV08SR7O51XTUhtc8zqpDj8iCG4RGmdKw==",
+      "version": "27.2.2",
+      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.2.tgz",
+      "integrity": "sha512-xN3wT4p2i9DGB6zmL3XxYp5lJmq9Q6ff8XKlMtVVBS2SAshmgsPBALJFQ8dWRd2G/xf5q/N0SD0Mipt8QBA26A==",
       "dev": true,
       "requires": {
         "chalk": "^4.0.0",
-        "jest-diff": "^27.2.0",
+        "jest-diff": "^27.2.2",
         "jest-get-type": "^27.0.6",
-        "pretty-format": "^27.2.0"
+        "pretty-format": "^27.2.2"
       }
     },
     "jest-message-util": {
-      "version": "27.2.0",
-      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.0.tgz",
-      "integrity": "sha512-y+sfT/94CiP8rKXgwCOzO1mUazIEdEhrLjuiu+RKmCP+8O/TJTSne9dqQRbFIHBtlR2+q7cddJlWGir8UATu5w==",
+      "version": "27.2.2",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.2.tgz",
+      "integrity": "sha512-/iS5/m2FSF7Nn6APFoxFymJpyhB/gPf0CJa7uFSkbYaWvrADUfQ9NTsuyjpszKErOS2/huFs44ysWhlQTKvL8Q==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.12.13",
         "chalk": "^4.0.0",
         "graceful-fs": "^4.2.4",
         "micromatch": "^4.0.4",
-        "pretty-format": "^27.2.0",
+        "pretty-format": "^27.2.2",
         "slash": "^3.0.0",
         "stack-utils": "^2.0.3"
       },
       "dev": true
     },
     "mocha": {
-      "version": "9.1.1",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz",
-      "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==",
+      "version": "9.1.2",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.2.tgz",
+      "integrity": "sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w==",
       "dev": true,
       "requires": {
         "@ungap/promise-all-settled": "1.1.2",
         "ansi-colors": "4.1.1",
         "browser-stdout": "1.3.1",
         "chokidar": "3.5.2",
-        "debug": "4.3.1",
+        "debug": "4.3.2",
         "diff": "5.0.0",
         "escape-string-regexp": "4.0.0",
         "find-up": "5.0.0",
         "log-symbols": "4.1.0",
         "minimatch": "3.0.4",
         "ms": "2.1.3",
-        "nanoid": "3.1.23",
+        "nanoid": "3.1.25",
         "serialize-javascript": "6.0.0",
         "strip-json-comments": "3.1.1",
         "supports-color": "8.1.1",
         "which": "2.0.2",
-        "wide-align": "1.1.3",
         "workerpool": "6.1.5",
         "yargs": "16.2.0",
         "yargs-parser": "20.2.4",
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
-          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
           "dev": true
         },
         "ansi-styles": {
           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
+        "debug": {
+          "version": "4.3.2",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "dev": true,
+          "requires": {
+            "ms": "2.1.2"
+          },
+          "dependencies": {
+            "ms": {
+              "version": "2.1.2",
+              "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+              "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+              "dev": true
+            }
+          }
+        },
         "emoji-regex": {
           "version": "8.0.0",
           "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
           "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
           "dev": true
         },
+        "nanoid": {
+          "version": "3.1.25",
+          "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
+          "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
+          "dev": true
+        },
         "p-limit": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
           }
         },
         "string-width": {
-          "version": "4.2.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
-          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.0"
+            "strip-ansi": "^6.0.1"
           }
         },
         "strip-ansi": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
-          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.0"
+            "ansi-regex": "^5.0.1"
           }
         },
         "strip-json-comments": {
       "dev": true
     },
     "pretty-format": {
-      "version": "27.2.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.0.tgz",
-      "integrity": "sha512-KyJdmgBkMscLqo8A7K77omgLx5PWPiXJswtTtFV7XgVZv2+qPk6UivpXXO+5k6ZEbWIbLoKdx1pZ6ldINzbwTA==",
+      "version": "27.2.2",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.2.tgz",
+      "integrity": "sha512-+DdLh+rtaElc2SQOE/YPH8k2g3Rf2OXWEpy06p8Szs3hdVSYD87QOOlYRHWAeb/59XTmeVmRKvDD0svHqf6ycA==",
       "dev": true,
       "requires": {
         "@jest/types": "^27.1.1",
-        "ansi-regex": "^5.0.0",
+        "ansi-regex": "^5.0.1",
         "ansi-styles": "^5.0.0",
         "react-is": "^17.0.1"
       },
index cbdb973bb286cc1374be51cf862cf8e203aa7a37..ddb241db6e33ed2c812c1c9231cd7e26bcc4c892 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.18",
+    "@types/node": "^14.17.19",
     "@types/proper-lockfile": "^4.1.2",
     "@types/tar": "^4.0.5",
     "@types/uuid": "^8.3.1",
     "eslint-plugin-import": "^2.24.2",
     "eslint-plugin-jsdoc": "^36.1.0",
     "eslint-plugin-node": "^11.1.0",
-    "expect": "^27.2.1",
-    "mocha": "^9.1.1",
+    "expect": "^27.2.2",
+    "mocha": "^9.1.2",
     "mochawesome": "^6.2.2",
     "npm-check": "^5.9.2",
     "nyc": "^15.1.0",
index 3646b89178ac1158da841dbd9073255862d61691..5a5ca993513ef561d944a4f2eaa28265acdf4b10 100644 (file)
@@ -10,13 +10,16 @@ import logger from '../utils/Logger';
 
 export default class AutomaticTransactionGenerator {
   public started: boolean;
+  private chargingStation: ChargingStation;
+  private connectorsStartStatus: Record<number, boolean>;
   private startDate!: Date;
   private lastRunDate!: Date;
   private stopDate!: Date;
-  private chargingStation: ChargingStation;
 
   constructor(chargingStation: ChargingStation) {
     this.chargingStation = chargingStation;
+    this.connectorsStartStatus = {} as Record<number, boolean>;
+    this.stopConnectors();
     this.started = false;
   }
 
@@ -31,15 +34,8 @@ export default class AutomaticTransactionGenerator {
     this.stopDate = new Date(this.startDate.getTime()
       + (this.chargingStation.stationInfo?.AutomaticTransactionGenerator?.stopAfterHours ?? Constants.CHARGING_STATION_ATG_DEFAULT_STOP_AFTER_HOURS) * 3600 * 1000
       - previousRunDuration);
+    this.startConnectors();
     this.started = true;
-    for (const connector in this.chargingStation.connectors) {
-      if (Utils.convertToInt(connector) > 0) {
-        // Avoid hogging the event loop with a busy loop
-        setImmediate(() => {
-          this.startOnConnector(Utils.convertToInt(connector)).catch(() => { /* This is intentional */ });
-        });
-      }
-    }
     logger.info(this.logPrefix() + ' started and will run for ' + Utils.formatDurationMilliSeconds(this.stopDate.getTime() - this.startDate.getTime()));
   }
 
@@ -48,15 +44,38 @@ export default class AutomaticTransactionGenerator {
       logger.error(`${this.logPrefix()} trying to stop while not started`);
       return;
     }
+    this.stopConnectors();
     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> {
+  private startConnectors(): void {
+    for (const connector in this.chargingStation.connectors) {
+      const connectorId = Utils.convertToInt(connector);
+      if (connectorId > 0) {
+        // Avoid hogging the event loop with a busy loop
+        setImmediate(() => {
+          this.startConnector(connectorId).catch(() => { /* This is intentional */ });
+        });
+      }
+    }
+  }
+
+  private stopConnectors(): void {
+    for (const connector in this.chargingStation.connectors) {
+      const connectorId = Utils.convertToInt(connector);
+      if (connectorId > 0) {
+        this.stopConnector(connectorId);
+      }
+    }
+  }
+
+  private async startConnector(connectorId: number): Promise<void> {
     logger.info(this.logPrefix(connectorId) + ' started on connector');
     let skippedTransactions = 0;
     let skippedTransactionsTotal = 0;
-    while (this.started) {
+    this.connectorsStartStatus[connectorId] = true;
+    while (this.connectorsStartStatus[connectorId]) {
       if ((new Date()) > this.stopDate) {
         this.stop();
         break;
@@ -80,7 +99,7 @@ export default class AutomaticTransactionGenerator {
           await Utils.sleep(Constants.CHARGING_STATION_ATG_INITIALIZATION_TIME);
         } while (!this.chargingStation?.ocppRequestService);
       }
-      const wait = Utils.getRandomInt(this.chargingStation.stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransactions,
+      const wait = Utils.getRandomInteger(this.chargingStation.stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransactions,
         this.chargingStation.stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransactions) * 1000;
       logger.info(this.logPrefix(connectorId) + ' waiting for ' + Utils.formatDurationMilliSeconds(wait));
       await Utils.sleep(wait);
@@ -94,7 +113,7 @@ export default class AutomaticTransactionGenerator {
           await Utils.sleep(Constants.CHARGING_STATION_ATG_WAIT_TIME);
         } else {
           // Wait until end of transaction
-          const waitTrxEnd = Utils.getRandomInt(this.chargingStation.stationInfo.AutomaticTransactionGenerator.maxDuration,
+          const waitTrxEnd = Utils.getRandomInteger(this.chargingStation.stationInfo.AutomaticTransactionGenerator.maxDuration,
             this.chargingStation.stationInfo.AutomaticTransactionGenerator.minDuration) * 1000;
           logger.info(this.logPrefix(connectorId) + ' transaction ' + this.chargingStation.getConnector(connectorId).transactionId.toString() + ' will stop in ' + Utils.formatDurationMilliSeconds(waitTrxEnd));
           await Utils.sleep(waitTrxEnd);
@@ -113,6 +132,10 @@ export default class AutomaticTransactionGenerator {
     logger.info(this.logPrefix(connectorId) + ' stopped on connector');
   }
 
+  private stopConnector(connectorId: number): void {
+    this.connectorsStartStatus[connectorId] = false;
+  }
+
   private async startTransaction(connectorId: number): Promise<StartTransactionResponse | AuthorizeResponse> {
     const measureId = 'StartTransaction with ATG';
     const beginId = PerformanceStatistics.beginMeasure(measureId);
index 14710b6542727a5dbd3d43b4d26ed9e404947990..5b5ac56e4d79e8ced4d3e15758f7b554f331550e 100644 (file)
@@ -525,7 +525,7 @@ export default class ChargingStation {
       // Generate all connectors
       if ((this.stationInfo.Connectors[0] ? templateMaxConnectors - 1 : templateMaxConnectors) > 0) {
         for (let index = 1; index <= maxConnectors; index++) {
-          const randConnectorId = this.stationInfo.randomConnectors ? Utils.getRandomInt(Utils.convertToInt(lastConnector), 1) : index;
+          const randConnectorId = this.stationInfo.randomConnectors ? Utils.getRandomInteger(Utils.convertToInt(lastConnector), 1) : index;
           this.connectors[index] = Utils.cloneObject<Connector>(this.stationInfo.Connectors[randConnectorId]);
           this.connectors[index].availability = AvailabilityType.OPERATIVE;
           if (Utils.isUndefined(this.connectors[lastConnector]?.chargingProfiles)) {
index 1a0190e59d813d4c6b22bb9434aa198105c075e6..a8fb489093e8464a191dcb82316e9fbe231a3bdd 100644 (file)
@@ -132,7 +132,7 @@ export default class OCPP16RequestService extends OCPPRequestService {
       if (socSampledValueTemplate) {
         const socSampledValueTemplateValue = socSampledValueTemplate.value
           ? Utils.getRandomFloatFluctuatedRounded(parseInt(socSampledValueTemplate.value), socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
-          : Utils.getRandomInt(100);
+          : Utils.getRandomInteger(100);
         meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(socSampledValueTemplate, socSampledValueTemplateValue));
         const sampledValuesIndex = meterValue.sampledValue.length - 1;
         if (Utils.convertToInt(meterValue.sampledValue[sampledValuesIndex].value) > 100 || debug) {
@@ -313,7 +313,7 @@ export default class OCPP16RequestService extends OCPPRequestService {
         const energyMeasurandValue = energySampledValueTemplate.value
           // Cumulate the fluctuated value around the static one
           ? Utils.getRandomFloatFluctuatedRounded(parseInt(energySampledValueTemplate.value), energySampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
-          : Utils.getRandomInt(this.chargingStation.stationInfo.maxPower / (this.chargingStation.stationInfo.powerDivider * 3600000) * interval);
+          : Utils.getRandomInteger(this.chargingStation.stationInfo.maxPower / (this.chargingStation.stationInfo.powerDivider * 3600000) * interval);
         // Persist previous value on connector
         if (connector && !Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) && connector.energyActiveImportRegisterValue >= 0 &&
             !Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) && connector.transactionEnergyActiveImportRegisterValue >= 0) {
index 92373cf043ba2161426ae6066c3376ef53097af4..b04814a7a6437dd6a369b81b5998458f652e3465 100644 (file)
@@ -108,7 +108,7 @@ export default class Utils {
     return sign * (randomPositiveFloat * (max - min) + min);
   }
 
-  public static getRandomInt(max: number, min = 0): number {
+  public static getRandomInteger(max: number, min = 0): number {
     if (max < 0) {
       throw new RangeError('Invalid interval');
     }