From 34dcb3b54b6b7825adb8aa8129709febd2cf96ac Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 17 Oct 2020 22:47:04 +0200 Subject: [PATCH] Various initialization fixes. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../abb.station-template.json | 9 ++-- .../evlink.station-template.json | 3 +- .../keba.station-template.json | 4 +- .../schneider-imredd.station-template.json | 3 +- .../schneider.station-template.json | 3 +- .../siemens.mougins69.station-template.json | 3 +- .../virtual-simple-atg.station-template.json | 3 +- .../virtual-simple.station-template.json | 3 +- .../virtual.station-template.json | 3 +- .../AutomaticTransactionGenerator.js | 22 +++++--- src/charging-station/ChargingStation.js | 51 ++++++++++++------- 11 files changed, 70 insertions(+), 37 deletions(-) diff --git a/src/assets/station-templates/abb.station-template.json b/src/assets/station-templates/abb.station-template.json index 161febe4..f256c37e 100644 --- a/src/assets/station-templates/abb.station-template.json +++ b/src/assets/station-templates/abb.station-template.json @@ -1,11 +1,13 @@ { "authorizationFile": "./src/assets/authorization-tags.json", "baseName": "CS-ABB", - "chargePointModel": "ABB 5678", + "chargePointModel": "MD_TERRA_53", "chargePointVendor": "ABB", + "firmwareVersion": "4.0.4.22", "power": 50000, "powerUnit": "W", "numberOfConnectors": 2, + "useConnectorId0": false, "randomConnectors": false, "Configuration": { "configurationKey": [ @@ -37,13 +39,14 @@ ] }, "AutomaticTransactionGenerator": { - "enable": false, + "enable": true, "minDuration": 60, "maxDuration": 80, "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": true }, "Connectors": { "0": {}, diff --git a/src/assets/station-templates/evlink.station-template.json b/src/assets/station-templates/evlink.station-template.json index 95251174..41ba8e3e 100644 --- a/src/assets/station-templates/evlink.station-template.json +++ b/src/assets/station-templates/evlink.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "1": { diff --git a/src/assets/station-templates/keba.station-template.json b/src/assets/station-templates/keba.station-template.json index 8c00f7cc..9366edd3 100644 --- a/src/assets/station-templates/keba.station-template.json +++ b/src/assets/station-templates/keba.station-template.json @@ -3,6 +3,7 @@ "baseName": "CS-KEBA", "chargePointModel": "KC-P30-ESS400C2-E0R", "chargePointVendor": "Keba AG", + "firmwareVersion": "1.10.1", "power": 22000, "powerUnit": "W", "numberOfConnectors": 1, @@ -43,7 +44,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "1": { diff --git a/src/assets/station-templates/schneider-imredd.station-template.json b/src/assets/station-templates/schneider-imredd.station-template.json index 26c92a67..0c7c53b6 100644 --- a/src/assets/station-templates/schneider-imredd.station-template.json +++ b/src/assets/station-templates/schneider-imredd.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "1": { diff --git a/src/assets/station-templates/schneider.station-template.json b/src/assets/station-templates/schneider.station-template.json index 26c92a67..0c7c53b6 100644 --- a/src/assets/station-templates/schneider.station-template.json +++ b/src/assets/station-templates/schneider.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "1": { diff --git a/src/assets/station-templates/siemens.mougins69.station-template.json b/src/assets/station-templates/siemens.mougins69.station-template.json index 87a538af..9eecbc48 100644 --- a/src/assets/station-templates/siemens.mougins69.station-template.json +++ b/src/assets/station-templates/siemens.mougins69.station-template.json @@ -44,7 +44,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "1": { diff --git a/src/assets/station-templates/virtual-simple-atg.station-template.json b/src/assets/station-templates/virtual-simple-atg.station-template.json index fcc80955..808d4c0c 100644 --- a/src/assets/station-templates/virtual-simple-atg.station-template.json +++ b/src/assets/station-templates/virtual-simple-atg.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "0": {}, diff --git a/src/assets/station-templates/virtual-simple.station-template.json b/src/assets/station-templates/virtual-simple.station-template.json index 0bef7cfd..f2cc557c 100644 --- a/src/assets/station-templates/virtual-simple.station-template.json +++ b/src/assets/station-templates/virtual-simple.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "0": {}, diff --git a/src/assets/station-templates/virtual.station-template.json b/src/assets/station-templates/virtual.station-template.json index 6eb7d2ec..2b8a2bc1 100644 --- a/src/assets/station-templates/virtual.station-template.json +++ b/src/assets/station-templates/virtual.station-template.json @@ -43,7 +43,8 @@ "minDelayBetweenTwoTransaction": 15, "maxDelayBetweenTwoTransaction": 30, "probabilityOfStart": 1, - "stopAutomaticTransactionGeneratorAfterHours": 0.3 + "stopAfterHours": 0.3, + "stopOnConnectionFailure": false }, "Connectors": { "0": {}, diff --git a/src/charging-station/AutomaticTransactionGenerator.js b/src/charging-station/AutomaticTransactionGenerator.js index e30fafd8..6d46afee 100644 --- a/src/charging-station/AutomaticTransactionGenerator.js +++ b/src/charging-station/AutomaticTransactionGenerator.js @@ -5,7 +5,7 @@ const {performance, PerformanceObserver} = require('perf_hooks'); class AutomaticTransactionGenerator { constructor(chargingStation) { this._chargingStation = chargingStation; - this._timeToStop = false; + this._timeToStop = true; this._performanceObserver = new PerformanceObserver((list) => { const entry = list.getEntries()[0]; this._chargingStation._statistics.logPerformance(entry, 'AutomaticTransactionGenerator'); @@ -13,9 +13,13 @@ class AutomaticTransactionGenerator { }); } + get timeToStop() { + return this._timeToStop; + } + _basicFormatLog(connectorId = null) { if (connectorId) { - return Utils.basicFormatLog(' ' + this._chargingStation._stationInfo.name + ' ATG on connector #' + connectorId); + return Utils.basicFormatLog(' ' + this._chargingStation._stationInfo.name + ' ATG on connector #' + connectorId + ':'); } return Utils.basicFormatLog(' ' + this._chargingStation._stationInfo.name + ' ATG:'); } @@ -33,12 +37,12 @@ class AutomaticTransactionGenerator { async start() { this._timeToStop = false; - if (this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours && - this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours > 0) { - logger.info(this._basicFormatLog() + ' ATG will stop in ' + Utils.secondstoHHMMSS(this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours * 3600)); + if (this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours && + this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours > 0) { + logger.info(this._basicFormatLog() + ' ATG will stop in ' + Utils.secondstoHHMMSS(this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours * 3600)); setTimeout(() => { this.stop(); - }, this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours * 3600 * 1000); + }, this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours * 3600 * 1000); } for (const connector in this._chargingStation._connectors) { if (connector > 0) { @@ -49,7 +53,8 @@ class AutomaticTransactionGenerator { async startConnector(connectorId) { do { - const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransaction, this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransaction) * 1000; + const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransaction, + this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransaction) * 1000; logger.info(this._basicFormatLog(connectorId) + ' wait for ' + Utils.secondstoHHMMSS(wait / 1000)); await Utils.sleep(wait); if (this._timeToStop) break; @@ -66,7 +71,8 @@ class AutomaticTransactionGenerator { await Utils.sleep(2000); } else { // Wait until end of transaction - const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDuration, this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDuration) * 1000; + const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDuration, + this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDuration) * 1000; logger.info(this._basicFormatLog(connectorId) + ' transaction ' + this._chargingStation._connectors[connectorId].transactionId + ' will stop in ' + Utils.secondstoHHMMSS(wait / 1000)); await Utils.sleep(wait); // Stop transaction diff --git a/src/charging-station/ChargingStation.js b/src/charging-station/ChargingStation.js index ebc3509c..38e9f582 100644 --- a/src/charging-station/ChargingStation.js +++ b/src/charging-station/ChargingStation.js @@ -23,6 +23,8 @@ class ChargingStation { this._messageQueue = []; this._isSocketRestart = false; + + this._authorizedTags = this._getAuthorizedTags(); } _initialize() { @@ -30,9 +32,10 @@ class ChargingStation { this._bootNotificationMessage = { chargePointModel: this._stationInfo.chargePointModel, chargePointVendor: this._stationInfo.chargePointVendor, + // chargePointSerialNumber: this._stationInfo.chargePointSerialNumber, + firmwareVersion: this._stationInfo.firmwareVersion ? this._stationInfo.firmwareVersion : '', }; this._configuration = this._getConfiguration(); - this._authorizedTags = this._getAuthorizedTags(); this._supervisionUrl = this._getSupervisionURL(); this._statistics = new Statistics(this._stationInfo.name); this._performanceObserver = new PerformanceObserver((list) => { @@ -148,13 +151,13 @@ class ChargingStation { } async start() { + this._url = this._supervisionUrl + '/' + this._stationInfo.name; + this._wsConnection = new WebSocket(this._url, 'ocpp1.6'); logger.info(this._basicFormatLog() + ' Will communicate with ' + this._supervisionUrl); // Monitor authorization file this._startAuthorizationFileMonitoring(); // Monitor station template file this._startStationTemplateFileMonitoring(); - this._url = this._supervisionUrl + '/' + this._stationInfo.name; - this._wsConnection = new WebSocket(this._url, 'ocpp1.6'); // Handle Socket incoming messages this._wsConnection.on('message', this.onMessage.bind(this)); // Handle Socket error @@ -306,9 +309,11 @@ class ChargingStation { clearInterval(this._heartbeatSetInterval); this._heartbeatSetInterval = null; } - // Stop the ATG - if (this._stationInfo.AutomaticTransactionGenerator.enable && this._automaticTransactionGeneration && - !this._automaticTransactionGeneration._timeToStop) { + // Stop the ATG if needed + if (Utils.convertToBoolean(this._stationInfo.AutomaticTransactionGenerator.enable) && + Utils.convertToBoolean(this._stationInfo.AutomaticTransactionGenerator.stopOnConnectionFailure) && + this._automaticTransactionGeneration && + !this._automaticTransactionGeneration.timeToStop) { this._automaticTransactionGeneration.stop(); } if (this._autoReconnectTimeout !== 0 && @@ -433,7 +438,7 @@ class ChargingStation { let lastConnector; for (lastConnector in connectorsConfig) { // add connector 0, OCPP specification violation that for example KEBA have - if (Utils.convertToInt(lastConnector) === 0 && this._stationInfo.useConnectorId0) { + if (Utils.convertToInt(lastConnector) === 0 && Utils.convertToBoolean(this._stationInfo.useConnectorId0)) { this._connectors[lastConnector] = connectorsConfig[lastConnector]; } } @@ -446,7 +451,7 @@ class ChargingStation { } // generate all connectors for (let index = 1; index <= maxConnectors; index++) { - const randConnectorID = this._stationInfo.randomConnectors ? Utils.getRandomInt(maxConnectors, 1) : index; + const randConnectorID = Utils.convertToBoolean(this._stationInfo.randomConnectors) ? Utils.getRandomInt(lastConnector, 1) : index; this._connectors[index] = connectorsConfig[randConnectorID]; } } @@ -463,11 +468,13 @@ class ChargingStation { } } - if (this._stationInfo.AutomaticTransactionGenerator.enable) { + if (Utils.convertToBoolean(this._stationInfo.AutomaticTransactionGenerator.enable)) { if (!this._automaticTransactionGeneration) { this._automaticTransactionGeneration = new AutomaticTransactionGenerator(this); } - this._automaticTransactionGeneration.start(); + if (this._automaticTransactionGeneration.timeToStop) { + this._automaticTransactionGeneration.start(); + } } this._statistics.start(); } @@ -492,7 +499,7 @@ class ChargingStation { } handleResponseStartTransaction(payload, requestPayload) { - // Reset connector transaction related attributes + // Set connector transaction related attributes this._connectors[requestPayload.connectorId].transactionStarted = false; this._connectors[requestPayload.connectorId].idTag = requestPayload.idTag; @@ -522,6 +529,14 @@ class ChargingStation { } } + handleResponseStopTransaction(payload, requestPayload) { + if (payload.idTagInfo && payload.idTagInfo.status) { + logger.debug(this._basicFormatLog() + ' Stop transaction ' + requestPayload.transactionId + ' response status: ' + payload.idTagInfo.status ); + } else { + logger.debug(this._basicFormatLog() + ' Stop transaction ' + requestPayload.transactionId + ' response status: Unknown'); + } + } + handleResponseStatusNotification(payload) { logger.debug(this._basicFormatLog() + ' Status notification response received: %j', payload); } @@ -557,7 +572,7 @@ class ChargingStation { await this.sendMessage(messageId, result, Constants.OCPP_JSON_CALL_RESULT_MESSAGE); } - async handleGetConfiguration() { + async handleGetConfiguration(commandPayload) { return this._configuration; } @@ -649,7 +664,7 @@ class ChargingStation { if (sampledValueLcl.sampledValue[index].measurand && sampledValueLcl.sampledValue[index].measurand === 'SoC') { sampledValueLcl.sampledValue[index].value = Math.floor(Math.random() * 100) + 1; if (sampledValueLcl.sampledValue[index].value > 100) { - logger.info(self._basicFormatLog() + ' Meter type: ' + + logger.info(self._basicFormatLog() + ' MeterValues measurand: ' + (sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'default') + ', value: ' + sampledValueLcl.sampledValue[index].value); } @@ -664,10 +679,10 @@ class ChargingStation { connector.lastConsumptionValue = 0; } consumption = Math.round(connector.lastConsumptionValue * 3600 / interval); - logger.info(self._basicFormatLog() + ' ConnectorID ' + connectorID + ' transaction ' + connector.transactionId + ' value ' + connector.lastConsumptionValue); + logger.info(self._basicFormatLog() + ' MeterValues: connectorID ' + connectorID + ', transaction ' + connector.transactionId + ', value ' + connector.lastConsumptionValue); sampledValueLcl.sampledValue[index].value = connector.lastConsumptionValue; if (sampledValueLcl.sampledValue[index].value > (self._stationInfo.maxPower * 3600 / interval) || sampledValueLcl.sampledValue[index].value < 500) { - logger.info(self._basicFormatLog() + ' Meter type: ' + + logger.info(self._basicFormatLog() + ' MeterValues measurand: ' + (sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'default') + ', value: ' + sampledValueLcl.sampledValue[index].value + '/' + (self._stationInfo.maxPower * 3600 / interval)); } @@ -681,15 +696,15 @@ class ChargingStation { }; await self.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'MeterValues'); } catch (error) { - logger.error(self._basicFormatLog() + ' Send meter values error: ' + error); + logger.error(self._basicFormatLog() + ' Send MeterValues error: ' + error); } } async startMeterValues(connectorID, interval, self) { if (!this._connectors[connectorID].transactionStarted) { - logger.debug(`${self._basicFormatLog()} Trying to start meter values on connector ID ${connectorID} with no transaction started`); + logger.debug(`${self._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorID} with no transaction started`); } else if (this._connectors[connectorID].transactionStarted && !this._connectors[connectorID].transactionId) { - logger.debug(`${self._basicFormatLog()} Trying to start meter values on connector ID ${connectorID} with no transaction id`); + logger.debug(`${self._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorID} with no transaction id`); } this._connectors[connectorID].transactionInterval = setInterval(async () => { const sendMeterValues = performance.timerify(this.sendMeterValues); -- 2.34.1