e30fafd83dc8163e2c793e600968144fbf54d47f
[e-mobility-charging-stations-simulator.git] / src / charging-station / AutomaticTransactionGenerator.js
1 const logger = require('../utils/Logger');
2 const Utils = require('../utils/Utils');
3 const {performance, PerformanceObserver} = require('perf_hooks');
4
5 class AutomaticTransactionGenerator {
6 constructor(chargingStation) {
7 this._chargingStation = chargingStation;
8 this._timeToStop = false;
9 this._performanceObserver = new PerformanceObserver((list) => {
10 const entry = list.getEntries()[0];
11 this._chargingStation._statistics.logPerformance(entry, 'AutomaticTransactionGenerator');
12 this._performanceObserver.disconnect();
13 });
14 }
15
16 _basicFormatLog(connectorId = null) {
17 if (connectorId) {
18 return Utils.basicFormatLog(' ' + this._chargingStation._stationInfo.name + ' ATG on connector #' + connectorId);
19 }
20 return Utils.basicFormatLog(' ' + this._chargingStation._stationInfo.name + ' ATG:');
21 }
22
23 async stop() {
24 logger.info(this._basicFormatLog() + ' ATG OVER => STOPPING ALL TRANSACTIONS');
25 for (const connector in this._chargingStation._connectors) {
26 if (this._chargingStation._connectors[connector].transactionStarted) {
27 logger.info(this._basicFormatLog(connector) + ' ATG OVER. Stop transaction ' + this._chargingStation._connectors[connector].transactionId);
28 await this._chargingStation.sendStopTransaction(this._chargingStation._connectors[connector].transactionId, connector);
29 }
30 }
31 this._timeToStop = true;
32 }
33
34 async start() {
35 this._timeToStop = false;
36 if (this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours &&
37 this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours > 0) {
38 logger.info(this._basicFormatLog() + ' ATG will stop in ' + Utils.secondstoHHMMSS(this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours * 3600));
39 setTimeout(() => {
40 this.stop();
41 }, this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAutomaticTransactionGeneratorAfterHours * 3600 * 1000);
42 }
43 for (const connector in this._chargingStation._connectors) {
44 if (connector > 0) {
45 this.startConnector(connector);
46 }
47 }
48 }
49
50 async startConnector(connectorId) {
51 do {
52 const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransaction, this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransaction) * 1000;
53 logger.info(this._basicFormatLog(connectorId) + ' wait for ' + Utils.secondstoHHMMSS(wait / 1000));
54 await Utils.sleep(wait);
55 if (this._timeToStop) break;
56 const start = Math.random();
57 let skip = 0;
58 if (start < this._chargingStation._stationInfo.AutomaticTransactionGenerator.probabilityOfStart) {
59 skip = 0;
60 // Start transaction
61 const startTransaction = performance.timerify(this.startTransaction);
62 this._performanceObserver.observe({entryTypes: ['function']});
63 const startResponse = await startTransaction(connectorId, this);
64 if (startResponse.idTagInfo.status !== 'Accepted') {
65 logger.info(this._basicFormatLog(connectorId) + ' transaction rejected');
66 await Utils.sleep(2000);
67 } else {
68 // Wait until end of transaction
69 const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDuration, this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDuration) * 1000;
70 logger.info(this._basicFormatLog(connectorId) + ' transaction ' + this._chargingStation._connectors[connectorId].transactionId + ' will stop in ' + Utils.secondstoHHMMSS(wait / 1000));
71 await Utils.sleep(wait);
72 // Stop transaction
73 if (this._chargingStation._connectors[connectorId].transactionStarted) {
74 logger.info(this._basicFormatLog(connectorId) + ' stop transaction ' + this._chargingStation._connectors[connectorId].transactionId);
75 const stopTransaction = performance.timerify(this.stopTransaction);
76 this._performanceObserver.observe({entryTypes: ['function']});
77 await stopTransaction(connectorId, this);
78 }
79 }
80 } else {
81 skip++;
82 logger.info(this._basicFormatLog(connectorId) + ' transaction skipped ' + skip);
83 }
84 } while (!this._timeToStop);
85 logger.info(this._basicFormatLog() + ' ATG is STOPPED');
86 }
87
88 // eslint-disable-next-line class-methods-use-this
89 async startTransaction(connectorId, self) {
90 if (self._chargingStation.hasAuthorizedTags()) {
91 const tagId = self._chargingStation.getRandomTagId();
92 logger.info(self._basicFormatLog(connectorId) + ' start transaction for tagID ' + tagId);
93 return self._chargingStation.sendStartTransaction(connectorId, tagId);
94 }
95 return self._chargingStation.sendStartTransaction(connectorId);
96 }
97
98 // eslint-disable-next-line class-methods-use-this
99 async stopTransaction(connectorId, self) {
100 await self._chargingStation.sendStopTransaction(self._chargingStation._connectors[connectorId].transactionId, connectorId);
101 }
102 }
103
104 module.exports = AutomaticTransactionGenerator;