X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStation.js;h=c1ca553d365228842c6001b5df497d3d59c292c5;hb=bec64e8b13ebf62d6838d1f3fb647a5b06f170fb;hp=f644003c139f995c846eb8e6c54dfc3c9d398a3f;hpb=0a60c33c4f6592f6223136704fa4513b68603f2d;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStation.js b/src/charging-station/ChargingStation.js index f644003c..c1ca553d 100644 --- a/src/charging-station/ChargingStation.js +++ b/src/charging-station/ChargingStation.js @@ -251,24 +251,24 @@ class ChargingStation { }); } - async _startMeterValues(connectorID, interval) { - if (!this._connectors[connectorID].transactionStarted) { - logger.error(`${this._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorID} with no transaction started`); + async _startMeterValues(connectorId, interval) { + if (!this._connectors[connectorId].transactionStarted) { + logger.error(`${this._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorId} with no transaction started`); return; - } else if (this._connectors[connectorID].transactionStarted && !this._connectors[connectorID].transactionId) { - logger.error(`${this._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorID} with no transaction id`); + } else if (this._connectors[connectorId].transactionStarted && !this._connectors[connectorId].transactionId) { + logger.error(`${this._basicFormatLog()} Trying to start MeterValues on connector ID ${connectorId} with no transaction id`); return; } if (interval > 0) { - this._connectors[connectorID].transactionSetInterval = setInterval(async () => { + this._connectors[connectorId].transactionSetInterval = setInterval(async () => { const sendMeterValues = performance.timerify(this.sendMeterValues); this._performanceObserver.observe({ entryTypes: ['function'], }); - await sendMeterValues(connectorID, interval, this); + await sendMeterValues(connectorId, interval, this); }, interval); } else { - logger.info(`${this._basicFormatLog()} Charging station MeterValueSampleInterval configuration set to ${interval}ms, not sending MeterValues`); + logger.error(`${this._basicFormatLog()} Charging station MeterValueSampleInterval configuration set to ${interval}ms, not sending MeterValues`); } } @@ -277,7 +277,7 @@ class ChargingStation { this._wsConnectionUrl = this._supervisionUrl + '/' + this._stationInfo.name; } this._wsConnection = new WebSocket(this._wsConnectionUrl, 'ocpp' + Constants.OCPP_VERSION_16); - logger.info(this._basicFormatLog() + ' Will communicate with ' + this._supervisionUrl); + logger.info(this._basicFormatLog() + ' Will communicate through URL ' + this._supervisionUrl); // Monitor authorization file this._startAuthorizationFileMonitoring(); // Monitor station template file @@ -294,18 +294,18 @@ class ChargingStation { this._wsConnection.on('ping', this.onPing.bind(this)); } - async stop(type = '') { + async stop(reason = '') { // Stop heartbeat await this._stopHeartbeat(); // Stop the ATG if (Utils.convertToBoolean(this._stationInfo.AutomaticTransactionGenerator.enable) && this._automaticTransactionGeneration && !this._automaticTransactionGeneration.timeToStop) { - await this._automaticTransactionGeneration.stop(type ? type + 'Reset' : ''); + await this._automaticTransactionGeneration.stop(reason); } else { for (const connector in this._connectors) { if (this._connectors[connector].transactionStarted) { - await this.sendStopTransaction(this._connectors[connector].transactionId, type ? type + 'Reset' : ''); + await this.sendStopTransaction(this._connectors[connector].transactionId, reason); } } } @@ -350,7 +350,7 @@ class ChargingStation { } if (this._isSocketRestart) { this._basicStartMessageSequence(); - if (this._messageQueue.length > 0) { + if (!Utils.isEmptyArray(this._messageQueue)) { this._messageQueue.forEach((message) => { if (this._wsConnection && this._wsConnection.readyState === WebSocket.OPEN) { this._wsConnection.send(message); @@ -489,10 +489,10 @@ class ChargingStation { setTimeout(() => this.sendStatusNotification(connectorId, status, errorCode), timeout); } - async sendStartTransaction(connectorID, idTag) { + async sendStartTransaction(connectorId, idTag) { try { const payload = { - connectorId: connectorID, + connectorId, idTag, meterStart: 0, timestamp: new Date().toISOString(), @@ -504,18 +504,27 @@ class ChargingStation { } } - sendStartTransactionWithTimeout(connectorID, idTag, timeout) { - setTimeout(() => this.sendStartTransaction(connectorID, idTag), timeout); + sendStartTransactionWithTimeout(connectorId, idTag, timeout) { + setTimeout(() => this.sendStartTransaction(connectorId, idTag), timeout); } async sendStopTransaction(transactionId, reason = '') { try { - const payload = { - transactionId, - meterStop: 0, - timestamp: new Date().toISOString(), - reason, - }; + let payload; + if (reason) { + payload = { + transactionId, + meterStop: 0, + timestamp: new Date().toISOString(), + reason, + }; + } else { + payload = { + transactionId, + meterStop: 0, + timestamp: new Date().toISOString(), + }; + } await this.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'StopTransaction'); } catch (error) { logger.error(this._basicFormatLog() + ' Send StopTransaction error: ' + error); @@ -524,52 +533,56 @@ class ChargingStation { } // eslint-disable-next-line class-methods-use-this - async sendMeterValues(connectorID, interval, self, debug = false) { + async sendMeterValues(connectorId, interval, self, debug = false) { try { const sampledValueLcl = { timestamp: new Date().toISOString(), }; - const meterValuesClone = Utils.cloneJSonDocument(self._getConnector(connectorID).MeterValues); + const meterValuesClone = Utils.cloneJSonDocument(self._getConnector(connectorId).MeterValues); if (!Utils.isEmptyArray(meterValuesClone)) { sampledValueLcl.sampledValue = meterValuesClone; } else { sampledValueLcl.sampledValue = [meterValuesClone]; } for (let index = 0; index < sampledValueLcl.sampledValue.length; index++) { - const connector = self._connectors[connectorID]; + const connector = self._connectors[connectorId]; // SoC measurand if (sampledValueLcl.sampledValue[index].measurand && sampledValueLcl.sampledValue[index].measurand === 'SoC') { - sampledValueLcl.sampledValue[index].value = Utils.getRandomInt(100); + sampledValueLcl.sampledValue[index].value = sampledValueLcl.sampledValue[index].value ? + sampledValueLcl.sampledValue[index].value : + sampledValueLcl.sampledValue[index].value = Utils.getRandomInt(100); if (sampledValueLcl.sampledValue[index].value > 100 || debug) { - logger.error(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorID ${connectorID}, transaction ${connector.transactionId}, value: ${sampledValueLcl.sampledValue[index].value}`); + logger.error(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValueLcl.sampledValue[index].value}`); } // Voltage measurand } else if (sampledValueLcl.sampledValue[index].measurand && sampledValueLcl.sampledValue[index].measurand === 'Voltage') { - sampledValueLcl.sampledValue[index].value = 230; + sampledValueLcl.sampledValue[index].value = sampledValueLcl.sampledValue[index].value ? sampledValueLcl.sampledValue[index].value : 230; // Energy.Active.Import.Register measurand (default) } else if (!sampledValueLcl.sampledValue[index].measurand || sampledValueLcl.sampledValue[index].measurand === 'Energy.Active.Import.Register') { - // Persist previous value in connector - const consumption = Utils.getRandomInt(self._stationInfo.maxPower / 3600000 * interval); - if (connector && connector.lastConsumptionValue && connector.lastConsumptionValue >= 0) { - connector.lastConsumptionValue += consumption; - } else { - connector.lastConsumptionValue = 0; + if (!sampledValueLcl.sampledValue[index].value) { + const measurandValue = Utils.getRandomInt(self._stationInfo.maxPower / 3600000 * interval); + // Persist previous value in connector + if (connector && connector.lastEnergyActiveImportRegisterValue >= 0) { + connector.lastEnergyActiveImportRegisterValue += measurandValue; + } else { + connector.lastEnergyActiveImportRegisterValue = 0; + } + sampledValueLcl.sampledValue[index].value = connector.lastEnergyActiveImportRegisterValue; } + logger.info(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value ${sampledValueLcl.sampledValue[index].value}`); const maxConsumption = self._stationInfo.maxPower * 3600 / interval; - logger.info(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorID ${connectorID}, transaction ${connector.transactionId}, value ${connector.lastConsumptionValue}`); - sampledValueLcl.sampledValue[index].value = connector.lastConsumptionValue; if (sampledValueLcl.sampledValue[index].value > maxConsumption || debug) { - logger.error(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorID ${connectorID}, transaction ${connector.transactionId}, value: ${sampledValueLcl.sampledValue[index].value}/${maxConsumption}`); + logger.error(`${self._basicFormatLog()} MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${sampledValueLcl.sampledValue[index].value}/${maxConsumption}`); } // Unsupported measurand } else { - logger.info(`${self._basicFormatLog()} Unsupported MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'} on connectorID ${connectorID}`); + logger.info(`${self._basicFormatLog()} Unsupported MeterValues measurand ${sampledValueLcl.sampledValue[index].measurand ? sampledValueLcl.sampledValue[index].measurand : 'Energy.Active.Import.Register'} on connectorId ${connectorId}`); } } const payload = { - connectorId: connectorID, - transactionId: self._connectors[connectorID].transactionId, + connectorId, + transactionId: self._connectors[connectorId].transactionId, meterValue: [sampledValueLcl], }; await self.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'MeterValues'); @@ -671,23 +684,24 @@ class ChargingStation { } } - _initTransactionOnConnector(connectorID) { - this._connectors[connectorID].transactionStarted = false; - this._connectors[connectorID].transactionId = null; - this._connectors[connectorID].idTag = null; - this._connectors[connectorID].lastConsumptionValue = -1; + _initTransactionOnConnector(connectorId) { + this._connectors[connectorId].transactionStarted = false; + this._connectors[connectorId].transactionId = null; + this._connectors[connectorId].idTag = null; + this._connectors[connectorId].lastEnergyActiveImportRegisterValue = -1; } - _resetTransactionOnConnector(connectorID) { - this._initTransactionOnConnector(connectorID); - if (this._connectors[connectorID].transactionSetInterval) { - clearInterval(this._connectors[connectorID].transactionSetInterval); + _resetTransactionOnConnector(connectorId) { + this._initTransactionOnConnector(connectorId); + if (this._connectors[connectorId].transactionSetInterval) { + clearInterval(this._connectors[connectorId].transactionSetInterval); } } handleResponseStartTransaction(payload, requestPayload) { if (this._connectors[requestPayload.connectorId].transactionStarted) { - logger.debug(this._basicFormatLog() + ' Try to start a transaction on an already used connector ' + requestPayload.connectorId + ' by transaction ' + this._connectors[requestPayload.connectorId].transactionId); + logger.debug(this._basicFormatLog() + ' Try to start a transaction on an already used connector ' + requestPayload.connectorId + ': %s', this._connectors[requestPayload.connectorId]); + return; } let transactionConnectorId; @@ -705,9 +719,9 @@ class ChargingStation { this._connectors[transactionConnectorId].transactionStarted = true; this._connectors[transactionConnectorId].transactionId = payload.transactionId; this._connectors[transactionConnectorId].idTag = requestPayload.idTag; - this._connectors[transactionConnectorId].lastConsumptionValue = 0; + this._connectors[transactionConnectorId].lastEnergyActiveImportRegisterValue = 0; this.sendStatusNotification(requestPayload.connectorId, 'Charging'); - logger.info(this._basicFormatLog() + ' Transaction ' + this._connectors[transactionConnectorId].transactionId + ' STARTED on ' + this._stationInfo.name + '#' + requestPayload.connectorId + ' for idTag ' + requestPayload.idTag); + logger.info(this._basicFormatLog() + ' Transaction ' + payload.transactionId + ' STARTED on ' + this._stationInfo.name + '#' + requestPayload.connectorId + ' for idTag ' + requestPayload.idTag); const configuredMeterValueSampleInterval = this._getConfigurationKey('MeterValueSampleInterval'); this._startMeterValues(requestPayload.connectorId, configuredMeterValueSampleInterval ? configuredMeterValueSampleInterval.value * 1000 : 60000); @@ -732,15 +746,15 @@ class ChargingStation { } if (payload.idTagInfo && payload.idTagInfo.status === 'Accepted') { this.sendStatusNotification(transactionConnectorId, 'Available'); - logger.info(this._basicFormatLog() + ' Transaction ' + this._connectors[transactionConnectorId].transactionId + ' STOPPED on ' + this._stationInfo.name + '#' + transactionConnectorId); + logger.info(this._basicFormatLog() + ' Transaction ' + requestPayload.transactionId + ' STOPPED on ' + this._stationInfo.name + '#' + transactionConnectorId); this._resetTransactionOnConnector(transactionConnectorId); } else { - logger.error(this._basicFormatLog() + ' Stopping transaction id ' + this._connectors[transactionConnectorId].transactionId + ' REJECTED with status ' + payload.idTagInfo.status); + logger.error(this._basicFormatLog() + ' Stopping transaction id ' + requestPayload.transactionId + ' REJECTED with status ' + payload.idTagInfo.status); } } handleResponseStatusNotification(payload, requestPayload) { - logger.debug(this._basicFormatLog() + ' Status notification response received: %j to status notification request: %j', payload, requestPayload); + logger.debug(this._basicFormatLog() + ' Status notification response received: %j to StatusNotification request: %j', payload, requestPayload); } handleResponseMeterValues(payload, requestPayload) { @@ -777,7 +791,7 @@ class ChargingStation { async handleReset(commandPayload) { // Simulate charging station restart setImmediate(async () => { - await this.stop(commandPayload.type); + await this.stop(commandPayload.type + 'Reset'); await Utils.sleep(this._stationInfo.resetTime); await this.start(); });