From 3f40bc9c40beaa5d90c5e05997c6bc0fdda21bae Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 30 Oct 2020 18:46:30 +0100 Subject: [PATCH] Add Current.Import measurand support. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- package-lock.json | 20 +-- package.json | 5 +- .../abb.station-template.json | 12 +- .../AutomaticTransactionGenerator.js | 13 +- src/charging-station/ChargingStation.js | 140 ++++++++++++------ src/charging-station/OcppError.js | 4 +- src/charging-station/StationWorker.js | 5 +- src/charging-station/Worker.js | 12 +- src/start.js | 8 +- src/utils/Configuration.js | 8 +- src/utils/Constants.js | 4 +- src/utils/ElectricUtils.js | 35 +++++ src/utils/Logger.js | 6 +- src/utils/Statistics.js | 10 +- src/utils/Utils.js | 6 +- 15 files changed, 182 insertions(+), 106 deletions(-) create mode 100644 src/utils/ElectricUtils.js diff --git a/package-lock.json b/package-lock.json index 90a91578..04836951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -244,9 +244,9 @@ } }, "@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", @@ -3608,13 +3608,13 @@ } }, "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", @@ -4572,9 +4572,9 @@ "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": { diff --git a/package.json b/package.json index 4af689a3..f3f85574 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "engines": { "node": "14.x.x" }, + "type": "module", "repository": { "type": "git", "url": "https://github.com/LucasBrazi06/ev-simulator.git" @@ -46,11 +47,11 @@ "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" } diff --git a/src/assets/station-templates/abb.station-template.json b/src/assets/station-templates/abb.station-template.json index b5f86e59..45da428f 100644 --- a/src/assets/station-templates/abb.station-template.json +++ b/src/assets/station-templates/abb.station-template.json @@ -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", @@ -73,6 +73,11 @@ "context": "Sample.Periodic", "measurand": "Voltage" }, + { + "unit": "A", + "context": "Sample.Periodic", + "measurand": "Current.Import" + }, { "unit": "Wh", "context": "Sample.Periodic" @@ -92,6 +97,11 @@ "context": "Sample.Periodic", "measurand": "Voltage" }, + { + "unit": "A", + "context": "Sample.Periodic", + "measurand": "Current.Import" + }, { "unit": "Wh", "context": "Sample.Periodic" diff --git a/src/charging-station/AutomaticTransactionGenerator.js b/src/charging-station/AutomaticTransactionGenerator.js index 23b247d3..1551a714 100644 --- a/src/charging-station/AutomaticTransactionGenerator.js +++ b/src/charging-station/AutomaticTransactionGenerator.js @@ -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; diff --git a/src/charging-station/ChargingStation.js b/src/charging-station/ChargingStation.js index 505c283d..0e5ae194 100644 --- a/src/charging-station/ChargingStation.js +++ b/src/charging-station/ChargingStation.js @@ -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; diff --git a/src/charging-station/OcppError.js b/src/charging-station/OcppError.js index 89ead59a..df9cc425 100644 --- a/src/charging-station/OcppError.js +++ b/src/charging-station/OcppError.js @@ -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; diff --git a/src/charging-station/StationWorker.js b/src/charging-station/StationWorker.js index 1aa6d8e5..f306c6ec 100644 --- a/src/charging-station/StationWorker.js +++ b/src/charging-station/StationWorker.js @@ -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); diff --git a/src/charging-station/Worker.js b/src/charging-station/Worker.js index db82e821..cc835855 100644 --- a/src/charging-station/Worker.js +++ b/src/charging-station/Worker.js @@ -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; diff --git a/src/start.js b/src/start.js index ead30ea9..0027fbae 100644 --- a/src/start.js +++ b/src/start.js @@ -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() { diff --git a/src/utils/Configuration.js b/src/utils/Configuration.js index 3227cb0c..c8e96f03 100644 --- a/src/utils/Configuration.js +++ b/src/utils/Configuration.js @@ -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; diff --git a/src/utils/Constants.js b/src/utils/Constants.js index ba2412c2..76677380 100644 --- a/src/utils/Constants.js +++ b/src/utils/Constants.js @@ -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 index 00000000..4bbfc9b4 --- /dev/null +++ b/src/utils/ElectricUtils.js @@ -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); + } +} diff --git a/src/utils/Logger.js b/src/utils/Logger.js index 1f34b00c..42d9d307 100644 --- a/src/utils/Logger.js +++ b/src/utils/Logger.js @@ -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; diff --git a/src/utils/Statistics.js b/src/utils/Statistics.js index d53cbe45..85165097 100644 --- a/src/utils/Statistics.js +++ b/src/utils/Statistics.js @@ -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; diff --git a/src/utils/Utils.js b/src/utils/Utils.js index db2017a8..6b6aba42 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -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; -- 2.34.1