Add Current.Import measurand support.
authorJérôme Benoit <jerome.benoit@sap.com>
Fri, 30 Oct 2020 17:46:30 +0000 (18:46 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Fri, 30 Oct 2020 17:46:30 +0000 (18:46 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
15 files changed:
package-lock.json
package.json
src/assets/station-templates/abb.station-template.json
src/charging-station/AutomaticTransactionGenerator.js
src/charging-station/ChargingStation.js
src/charging-station/OcppError.js
src/charging-station/StationWorker.js
src/charging-station/Worker.js
src/start.js
src/utils/Configuration.js
src/utils/Constants.js
src/utils/ElectricUtils.js [new file with mode: 0644]
src/utils/Logger.js
src/utils/Statistics.js
src/utils/Utils.js

index 90a91578df996e7b3e39ef8061ec39f85ef99505..048369519fff2435fc3321a645a2139c3ac0de98 100644 (file)
       }
     },
     "@eslint/eslintrc": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.0.tgz",
-      "integrity": "sha512-+cIGPCBdLCzqxdtwppswP+zTsH9BOIGzAeKfBIbtb4gW/giMlfMwP0HUSFfhzh20f9u8uZ8hOp62+4GPquTbwQ==",
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz",
+      "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
       }
     },
     "eslint": {
-      "version": "7.12.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.0.tgz",
-      "integrity": "sha512-n5pEU27DRxCSlOhJ2rO57GDLcNsxO0LPpAbpFdh7xmcDmjmlGUfoyrsB3I7yYdQXO5N3gkSTiDrPSPNFiiirXA==",
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz",
+      "integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.0.0",
-        "@eslint/eslintrc": "^0.2.0",
+        "@eslint/eslintrc": "^0.2.1",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
       "dev": true
     },
     "flow-bin": {
-      "version": "0.136.0",
-      "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.136.0.tgz",
-      "integrity": "sha512-Z0sycQDyWXiNsGAhOBUrvHPzz7Q4g38BT57+YzZGffbaBmWRNC6MGZb+R6XTzeWb30bZin5V21nPQZezJzm9cQ==",
+      "version": "0.137.0",
+      "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.137.0.tgz",
+      "integrity": "sha512-ytwUn68fPKK/VWVpCxJ4KNeNIjCC/uX0Ll6Z1E98sOXfMknB000WtgQjKYDdO6tOR8mvXBE0adzjgCrChVympw==",
       "dev": true
     },
     "flow-typed": {
index 4af689a365a11223f303fc8eeced584f682dc4dd..f3f85574a63ce23e4fb30cf10391c90c0c5698c0 100644 (file)
@@ -4,6 +4,7 @@
   "engines": {
     "node": "14.x.x"
   },
+  "type": "module",
   "repository": {
     "type": "git",
     "url": "https://github.com/LucasBrazi06/ev-simulator.git"
   "devDependencies": {
     "babel-eslint": "^10.1.0",
     "clinic": "^7.0.0",
-    "eslint": "^7.12.0",
+    "eslint": "^7.12.1",
     "eslint-config-google": "^0.14.0",
     "eslint-config-node": "^4.1.0",
     "eslint-plugin-flowtype": "^5.2.0",
-    "flow-bin": "^0.136.0",
+    "flow-bin": "^0.137.0",
     "flow-typed": "^3.2.1",
     "npm-check": "^5.9.2"
   }
index b5f86e59078f2c3023abe48128826afa20c36dd1..45da428fe5ebb7c83dd5c695785656eb9db865ef 100644 (file)
@@ -17,7 +17,7 @@
       {
         "key": "MeterValuesSampledData",
         "readonly": false,
-        "value": "SoC,Energy.Active.Import.Register,Voltage"
+        "value": "SoC,Energy.Active.Import.Register,Current.Import,Voltage"
       },
       {
         "key": "MeterValueSampleInterval",
           "context": "Sample.Periodic",
           "measurand": "Voltage"
         },
+        {
+          "unit": "A",
+          "context": "Sample.Periodic",
+          "measurand": "Current.Import"
+        },
         {
           "unit": "Wh",
           "context": "Sample.Periodic"
           "context": "Sample.Periodic",
           "measurand": "Voltage"
         },
+        {
+          "unit": "A",
+          "context": "Sample.Periodic",
+          "measurand": "Current.Import"
+        },
         {
           "unit": "Wh",
           "context": "Sample.Periodic"
index 23b247d353b1a37a1c1f2bb041069464921a5864..1551a7140348993a0c1cd927a128c97efa6e5839 100644 (file)
@@ -1,9 +1,10 @@
-const logger = require('../utils/Logger');
-const Constants = require('../utils/Constants');
-const Utils = require('../utils/Utils');
-const {performance, PerformanceObserver} = require('perf_hooks');
+import {PerformanceObserver, performance} from 'perf_hooks';
 
-class AutomaticTransactionGenerator {
+import Constants from '../utils/Constants.js';
+import Utils from '../utils/Utils.js';
+import logger from '../utils/Logger.js';
+
+export default class AutomaticTransactionGenerator {
   constructor(chargingStation) {
     this._chargingStation = chargingStation;
     this._timeToStop = true;
@@ -121,5 +122,3 @@ class AutomaticTransactionGenerator {
     await self._chargingStation.sendStopTransaction(self._chargingStation.getConnector(connectorId).transactionId);
   }
 }
-
-module.exports = AutomaticTransactionGenerator;
index 505c283d44ae3a822e2a2d024e86427f9983b90a..0e5ae1947ccc113a00d65d1f866fb152dd928c0c 100644 (file)
@@ -1,16 +1,18 @@
-const Configuration = require('../utils/Configuration');
-const logger = require('../utils/Logger');
-const WebSocket = require('ws');
-const Constants = require('../utils/Constants');
-const Utils = require('../utils/Utils');
-const OCPPError = require('./OcppError');
-const AutomaticTransactionGenerator = require('./AutomaticTransactionGenerator');
-const Statistics = require('../utils/Statistics');
-const fs = require('fs');
-const crypto = require('crypto');
-const {performance, PerformanceObserver} = require('perf_hooks');
-
-class ChargingStation {
+import {PerformanceObserver, performance} from 'perf_hooks';
+
+import AutomaticTransactionGenerator from './AutomaticTransactionGenerator.js';
+import Configuration from '../utils/Configuration.js';
+import Constants from '../utils/Constants.js';
+import ElectricUtils from '../utils/ElectricUtils.js';
+import OCPPError from './OcppError.js';
+import Statistics from '../utils/Statistics.js';
+import Utils from '../utils/Utils.js';
+import WebSocket from 'ws';
+import crypto from 'crypto';
+import fs from 'fs';
+import logger from '../utils/Logger.js';
+
+export default class ChargingStation {
   constructor(index, stationTemplateFile) {
     this._index = index;
     this._stationTemplateFile = stationTemplateFile;
@@ -68,13 +70,11 @@ class ChargingStation {
     // Build connectors if needed
     const maxConnectors = this._getMaxNumberOfConnectors();
     if (maxConnectors <= 0) {
-      const errMsg = `${this._logPrefix()} Charging station template ${this._stationTemplateFile} with ${maxConnectors} connectors`;
-      logger.warn(errMsg);
+      logger.warn(`${this._logPrefix()} Charging station template ${this._stationTemplateFile} with ${maxConnectors} connectors`);
     }
     const templateMaxConnectors = this._getTemplateMaxNumberOfConnectors();
     if (templateMaxConnectors <= 0) {
-      const errMsg = `${this._logPrefix()} Charging station template ${this._stationTemplateFile} with no connector configurations`;
-      logger.warn(errMsg);
+      logger.warn(`${this._logPrefix()} Charging station template ${this._stationTemplateFile} with no connector configurations`);
     }
     // Sanity check
     if (maxConnectors > (this._stationInfo.Connectors[0] ? templateMaxConnectors - 1 : templateMaxConnectors) && !Utils.convertToBoolean(this._stationInfo.randomConnectors)) {
@@ -216,6 +216,10 @@ class ChargingStation {
     return this._connectors[0] ? Object.keys(this._connectors).length - 1 : Object.keys(this._connectors).length;
   }
 
+  _getVoltageLineToNeutral() {
+    return !Utils.isUndefined(this._stationInfo.voltageLineToNeutral) ? this._stationInfo.voltageLineToNeutral : 230;
+  }
+
   _getSupervisionURL() {
     const supervisionUrls = Utils.cloneObject(this._stationInfo.supervisionURL ? this._stationInfo.supervisionURL : Configuration.getSupervisionURLs());
     let indexUrl = 0;
@@ -623,7 +627,7 @@ class ChargingStation {
           });
           const sampledValuesIndex = sampledValues.sampledValue.length - 1;
           if (sampledValues.sampledValue[sampledValuesIndex].value > 100 || debug) {
-            logger.error(`${self._logPrefix()} MeterValues measurand ${sampledValues.sampledValue[sampledValuesIndex].measurand ? sampledValues.sampledValue[sampledValuesIndex].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValues.sampledValue[sampledValuesIndex].value}`);
+            logger.error(`${self._logPrefix()} MeterValues measurand ${sampledValues.sampledValue[sampledValuesIndex].measurand ? sampledValues.sampledValue[sampledValuesIndex].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValues.sampledValue[sampledValuesIndex].value}/100`);
           }
         // Voltage measurand
         } else if (meterValuesTemplate[index].measurand && meterValuesTemplate[index].measurand === 'Voltage' && self._getConfigurationKey('MeterValuesSampledData').value.includes('Voltage')) {
@@ -632,7 +636,7 @@ class ChargingStation {
             ...!Utils.isUndefined(meterValuesTemplate[index].context) && {context: meterValuesTemplate[index].context},
             measurand: meterValuesTemplate[index].measurand,
             ...!Utils.isUndefined(meterValuesTemplate[index].location) && {location: meterValuesTemplate[index].location},
-            ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: 230},
+            ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: this._getVoltageLineToNeutral()},
           });
           for (let phase = 1; self._getNumberOfPhases() === 3 && phase <= self._getNumberOfPhases(); phase++) {
             const voltageValue = sampledValues.sampledValue[sampledValues.sampledValue.length - 1].value;
@@ -640,14 +644,61 @@ class ChargingStation {
             if (voltageValue >= 0 && voltageValue <= 240) {
               phaseValue = `L${phase}-N`;
             } else if (voltageValue > 240) {
-              phaseValue = `L${phase}-L${(phase + 1) % self._getNumberOfPhases() !== 0 ? (phase + 1) % self._getNumberOfPhases() : self._getNumberOfPhases() }`;
+              phaseValue = `L${phase}-L${(phase + 1) % self._getNumberOfPhases() !== 0 ? (phase + 1) % self._getNumberOfPhases() : self._getNumberOfPhases()}`;
             }
             sampledValues.sampledValue.push({
               ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? {unit: meterValuesTemplate[index].unit} : {unit: 'V'},
               ...!Utils.isUndefined(meterValuesTemplate[index].context) && {context: meterValuesTemplate[index].context},
               measurand: meterValuesTemplate[index].measurand,
               ...!Utils.isUndefined(meterValuesTemplate[index].location) && {location: meterValuesTemplate[index].location},
-              ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: 230},
+              ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: this._getVoltageLineToNeutral()},
+              phase: phaseValue,
+            });
+          }
+        // Current.Import measurand
+        } else if (meterValuesTemplate[index].measurand && meterValuesTemplate[index].measurand === 'Current.Import' && self._getConfigurationKey('MeterValuesSampledData').value.includes('Current.Import')) {
+          // FIXME: factor out powerDivider checks
+          if (Utils.isUndefined(self._stationInfo.powerDivider)) {
+            const errMsg = `${self._logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : 'Energy.Active.Import.Register'}: powerDivider is undefined`;
+            logger.error(errMsg);
+            throw Error(errMsg);
+          } else if (self._stationInfo.powerDivider && self._stationInfo.powerDivider <= 0) {
+            const errMsg = `${self._logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : 'Energy.Active.Import.Register'}: powerDivider have zero or below value ${self._stationInfo.powerDivider}`;
+            logger.error(errMsg);
+            throw Error(errMsg);
+          }
+          const maxAmpPerPhase = ElectricUtils.ampPerPhaseFromPower(self._getNumberOfPhases(), self._stationInfo.maxPower / self._stationInfo.powerDivider,
+              self._getVoltageLineToNeutral());
+          const currentMeasurandValues = {};
+          if (Utils.isUndefined(meterValuesTemplate[index].value)) {
+            currentMeasurandValues.L1 = Utils.getRandomFloatRounded(maxAmpPerPhase);
+            currentMeasurandValues.L2 = 0;
+            currentMeasurandValues.L3 = 0;
+            if (self._getNumberOfPhases() === 3) {
+              currentMeasurandValues.L2 = Utils.getRandomFloatRounded(maxAmpPerPhase);
+              currentMeasurandValues.L3 = Utils.getRandomFloatRounded(maxAmpPerPhase);
+            }
+            currentMeasurandValues.avg = Utils.roundTo((currentMeasurandValues.L1 + currentMeasurandValues.L2 + currentMeasurandValues.L3) / self._getNumberOfPhases(), 2);
+          }
+          sampledValues.sampledValue.push({
+            ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? {unit: meterValuesTemplate[index].unit} : {unit: 'A'},
+            ...!Utils.isUndefined(meterValuesTemplate[index].context) && {context: meterValuesTemplate[index].context},
+            measurand: meterValuesTemplate[index].measurand,
+            ...!Utils.isUndefined(meterValuesTemplate[index].location) && {location: meterValuesTemplate[index].location},
+            ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: currentMeasurandValues.avg},
+          });
+          const sampledValuesIndex = sampledValues.sampledValue.length - 1;
+          if (sampledValues.sampledValue[sampledValuesIndex].value > maxAmpPerPhase || debug) {
+            logger.error(`${self._logPrefix()} MeterValues measurand ${sampledValues.sampledValue[sampledValuesIndex].measurand ? sampledValues.sampledValue[sampledValuesIndex].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValues.sampledValue[sampledValuesIndex].value}/${maxAmpPerPhase}`);
+          }
+          for (let phase = 1; self._getNumberOfPhases() === 3 && phase <= self._getNumberOfPhases(); phase++) {
+            const phaseValue = `L${phase}`;
+            sampledValues.sampledValue.push({
+              ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? {unit: meterValuesTemplate[index].unit} : {unit: 'A'},
+              ...!Utils.isUndefined(meterValuesTemplate[index].context) && {context: meterValuesTemplate[index].context},
+              ...!Utils.isUndefined(meterValuesTemplate[index].measurand) && {measurand: meterValuesTemplate[index].measurand},
+              ...!Utils.isUndefined(meterValuesTemplate[index].location) && {location: meterValuesTemplate[index].location},
+              ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: currentMeasurandValues[phaseValue]},
               phase: phaseValue,
             });
           }
@@ -665,7 +716,7 @@ class ChargingStation {
           if (Utils.isUndefined(meterValuesTemplate[index].value)) {
             const measurandValue = Utils.getRandomInt(self._stationInfo.maxPower / (self._stationInfo.powerDivider * 3600000) * interval);
             // Persist previous value in connector
-            if (connector && connector.lastEnergyActiveImportRegisterValue >= 0) {
+            if (connector && !Utils.isNullOrUndefined(connector.lastEnergyActiveImportRegisterValue) && connector.lastEnergyActiveImportRegisterValue >= 0) {
               connector.lastEnergyActiveImportRegisterValue += measurandValue;
             } else {
               connector.lastEnergyActiveImportRegisterValue = 0;
@@ -679,19 +730,6 @@ class ChargingStation {
             ...!Utils.isUndefined(meterValuesTemplate[index].value) ? {value: meterValuesTemplate[index].value} : {value: connector.lastEnergyActiveImportRegisterValue},
           });
           const sampledValuesIndex = sampledValues.sampledValue.length - 1;
-          // const measurandValuePerPhase = Utils.roundTo(sampledValues.sampledValue[sampledValuesIndex].value / self._getNumberOfPhases(), 2);
-          // for (let phase = 1; self._getNumberOfPhases() === 3 && phase <= self._getNumberOfPhases(); phase++) {
-          //   const phaseValue = `L${phase}-N`;
-          //   sampledValues.sampledValue.push({
-          //     ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? {unit: meterValuesTemplate[index].unit} : {unit: 'Wh'},
-          //     ...!Utils.isUndefined(meterValuesTemplate[index].context) && {context: meterValuesTemplate[index].context},
-          //     ...!Utils.isUndefined(meterValuesTemplate[index].measurand) && {measurand: meterValuesTemplate[index].measurand},
-          //     ...!Utils.isUndefined(meterValuesTemplate[index].location) && {location: meterValuesTemplate[index].location},
-          //     value: measurandValuePerPhase,
-          //     phase: phaseValue,
-          //   });
-          // }
-          logger.info(`${self._logPrefix()} MeterValues measurand ${sampledValues.sampledValue[sampledValuesIndex].measurand ? sampledValues.sampledValue[sampledValuesIndex].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value ${sampledValues.sampledValue[sampledValuesIndex].value}`);
           const maxConsumption = self._stationInfo.maxPower * 3600 / (self._stationInfo.powerDivider * interval);
           if (sampledValues.sampledValue[sampledValuesIndex].value > maxConsumption || debug) {
             logger.error(`${self._logPrefix()} MeterValues measurand ${sampledValues.sampledValue[sampledValuesIndex].measurand ? sampledValues.sampledValue[sampledValuesIndex].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValues.sampledValue[sampledValuesIndex].value}/${maxConsumption}`);
@@ -775,15 +813,7 @@ class ChargingStation {
 
       // Function that will receive the request's response
       function responseCallback(payload, requestPayload) {
-        if (self.getEnableStatistics()) {
-          self._statistics.addMessage(commandName, true);
-        }
-        const responseCallbackFn = 'handleResponse' + commandName;
-        if (typeof self[responseCallbackFn] === 'function') {
-          self[responseCallbackFn](payload, requestPayload, self);
-        } else {
-          logger.debug(self._logPrefix() + ' Trying to call an undefined response callback function: ' + responseCallbackFn);
-        }
+        self.handleResponse(commandName, payload, requestPayload, self);
         // Send the response
         resolve(payload);
       }
@@ -803,6 +833,19 @@ class ChargingStation {
     });
   }
 
+  // eslint-disable-next-line class-methods-use-this
+  handleResponse(commandName, payload, requestPayload, self) {
+    if (self.getEnableStatistics()) {
+      self._statistics.addMessage(commandName, true);
+    }
+    const responseCallbackFn = 'handleResponse' + commandName;
+    if (typeof self[responseCallbackFn] === 'function') {
+      self[responseCallbackFn](payload, requestPayload, self);
+    } else {
+      logger.error(self._logPrefix() + ' Trying to call an undefined response callback function: ' + responseCallbackFn);
+    }
+  }
+
   handleResponseBootNotification(payload) {
     if (payload.status === 'Accepted') {
       this._heartbeatInterval = payload.interval * 1000;
@@ -907,12 +950,12 @@ class ChargingStation {
     if (this.getEnableStatistics()) {
       this._statistics.addMessage(commandName, true);
     }
-    let result;
+    let response;
     // Call
     if (typeof this['handle' + commandName] === 'function') {
       try {
-        // Call the method
-        result = await this['handle' + commandName](commandPayload);
+        // Call the method to build the response
+        response = await this['handle' + commandName](commandPayload);
       } catch (error) {
         // Log
         logger.error(this._logPrefix() + ' Handle request error: ' + error);
@@ -925,7 +968,7 @@ class ChargingStation {
       throw new Error(`${commandName} is not implemented ${JSON.stringify(commandPayload, null, ' ')}`);
     }
     // Send response
-    await this.sendMessage(messageId, result, Constants.OCPP_JSON_CALL_RESULT_MESSAGE);
+    await this.sendMessage(messageId, response, Constants.OCPP_JSON_CALL_RESULT_MESSAGE);
   }
 
   async handleReset(commandPayload) {
@@ -1074,4 +1117,3 @@ class ChargingStation {
   }
 }
 
-module.exports = ChargingStation;
index 89ead59a953473e53cb58098e08fb6c50f0578b1..df9cc425288a18fd504c96b5ee9d20e25f947ca8 100644 (file)
@@ -1,4 +1,4 @@
-class OCPPError extends Error {
+export default class OCPPError extends Error {
   constructor(code, message, details) {
     super(message);
 
@@ -11,5 +11,3 @@ class OCPPError extends Error {
     Error.captureStackTrace ? Error.captureStackTrace(this, this.constructor) : (this.stack = (new Error()).stack);
   }
 }
-
-module.exports = OCPPError;
index 1aa6d8e5e7f5f5e1635ed45f90860fdcdb587c27..f306c6ec42994d23d0eb9ddc8b2b960e996a7dcd 100644 (file)
@@ -1,5 +1,6 @@
-const {isMainThread, workerData} = require('worker_threads');
-const ChargingStation = require('./ChargingStation');
+import {isMainThread, workerData} from 'worker_threads';
+
+import ChargingStation from './ChargingStation.js';
 
 if (!isMainThread) {
   const station = new ChargingStation(workerData.index, workerData.templateFile);
index db82e8215fd0dad8fca89da13431c36f3c5c195d..cc8358559c5ce29d4bbda526b8de402309203de6 100644 (file)
@@ -1,9 +1,9 @@
-const Configuration = require('../utils/Configuration');
-const EventEmitter = require('events');
-const {Worker} = require('worker_threads');
-const Pool = require('worker-threads-pool');
+import Configuration from '../utils/Configuration.js';
+import EventEmitter from 'events';
+import Pool from 'worker-threads-pool';
+import {Worker} from 'worker_threads';
 
-class Wrk {
+export default class Wrk {
   /**
    * Create a new `Wrk`.
    *
@@ -82,5 +82,3 @@ class Wrk {
     return this._startWorker();
   }
 }
-
-module.exports = Wrk;
index ead30ea9e9c38ee3f5391457dde93bffd5e12a1f..0027fbae2dc4dee55e41bf368ada520957eb53a1 100644 (file)
@@ -1,7 +1,7 @@
-const Configuration = require('./utils/Configuration');
-const Utils = require('./utils/Utils');
-const Wrk = require('./charging-station/Worker');
-const logger = require('./utils/Logger');
+import Configuration from './utils/Configuration.js';
+import Utils from './utils/Utils.js';
+import Wrk from './charging-station/Worker.js';
+import logger from './utils/Logger.js';
 
 class Bootstrap {
   static async start() {
index 3227cb0ce660d2bb2eeb2e5eaef9514f4aa417f3..c8e96f032f6415f5835cf6f17468160747a488c4 100644 (file)
@@ -1,7 +1,7 @@
-const fs = require('fs');
-const Utils = require('./Utils');
+import Utils from './Utils.js';
+import fs from 'fs';
 
-class Configuration {
+export default class Configuration {
   static configuration;
 
   // Read the config file
@@ -69,5 +69,3 @@ class Configuration {
     return Utils.objectHasOwnProperty(Configuration.getConfig(), 'distributeStationToTenantEqually') ? Configuration.getConfig().distributeStationToTenantEqually : true;
   }
 }
-
-module.exports = Configuration;
index ba2412c2a08d87f723c8093c1a1b960fcd9eb38e..7667738004b954911316a2a7a69793d3038fea6b 100644 (file)
@@ -1,4 +1,4 @@
-class Constants {
+export default class Constants {
   static REST_RESPONSE_SUCCESS = {status: 'Success'};
 
   static CONN_STATUS_AVAILABLE = 'Available';
@@ -142,5 +142,3 @@ class Constants {
   static CHARGING_STATION_DEFAULT_RESET_TIME = 60000; // ms
   static CHARGING_STATION_ATG_WAIT_TIME = 2000; // ms
 }
-
-module.exports = Constants;
diff --git a/src/utils/ElectricUtils.js b/src/utils/ElectricUtils.js
new file mode 100644 (file)
index 0000000..4bbfc9b
--- /dev/null
@@ -0,0 +1,35 @@
+
+export default class ElectricUtils {
+  static ampTotal(nbOfPhases, Iph) {
+    return nbOfPhases * Iph;
+  }
+
+  static powerPerPhase(V, Iph, cosPhi = 1) {
+    const powerPerPhase = V * Iph * cosPhi;
+    if (cosPhi === 1) {
+      return powerPerPhase;
+    }
+    return Math.round(powerPerPhase);
+  }
+
+  static powerTotal(nbOfPhases, V, Iph, cosPhi = 1) {
+    return nbOfPhases * ElectricUtils.powerPerPhase(V, Iph, cosPhi);
+  }
+
+  static ampTotalFromPower(P, V, cosPhi = 1) {
+    const power = P / (V * cosPhi);
+    if (cosPhi === 1 && P % V === 0) {
+      return power;
+    }
+    return Math.round(power);
+  }
+
+  static ampPerPhaseFromPower(nbOfPhases, P, V, cosPhi = 1) {
+    const power = ElectricUtils.ampTotalFromPower(P, V, cosPhi);
+    const powerPerPhase = power / nbOfPhases;
+    if (power % nbOfPhases === 0) {
+      return powerPerPhase;
+    }
+    return Math.round(powerPerPhase);
+  }
+}
index 1f34b00cb2a6c4f87a78b7ee778f15490559b513..42d9d3076f19c8c661feda26269f851bb4c61fad 100644 (file)
@@ -1,5 +1,5 @@
-const Configuration = require('./Configuration');
-const Winston = require('winston');
+import Configuration from './Configuration.js';
+import Winston from 'winston';
 
 const logger = Winston.createLogger({
   level: Configuration.getLogLevel(),
@@ -24,4 +24,4 @@ if (Configuration.getConsoleLog()) {
   }));
 }
 
-module.exports = logger;
+export default logger;
index d53cbe45f415b447d118bd470cc4aab2b7526f95..85165097098354546b4f0eb589f5cd3e276ee3ce 100644 (file)
@@ -1,8 +1,8 @@
-const Configuration = require('./Configuration');
-const logger = require('./Logger');
-const Utils = require('./Utils');
+import Configuration from './Configuration.js';
+import Utils from './Utils.js';
+import logger from './Logger.js';
 
-class Statistics {
+export default class Statistics {
   static instance;
 
   constructor() {
@@ -94,5 +94,3 @@ class Statistics {
     this._displayInterval();
   }
 }
-
-module.exports = Statistics;
index db2017a8f6cee711e71750952646dfdab84d1171..6b6aba4292e7b77fc5af4406bc61f45c8ccaa13f 100644 (file)
@@ -1,6 +1,6 @@
-const {v4: uuid} = require('uuid');
+import {v4 as uuid} from 'uuid';
 
-class Utils {
+export default class Utils {
   static generateUUID() {
     return uuid();
   }
@@ -184,5 +184,3 @@ class Utils {
     return !Object.keys(obj).length;
   }
 }
-
-module.exports = Utils;