Simplify DC current output type handling.
[e-mobility-charging-stations-simulator.git] / src / charging-station / AutomaticTransactionGenerator.js
1 import {PerformanceObserver, performance} from 'perf_hooks';
2
3 import Constants from '../utils/Constants.js';
4 import Utils from '../utils/Utils.js';
5 import logger from '../utils/Logger.js';
6
7 export default class AutomaticTransactionGenerator {
8 constructor(chargingStation) {
9 this._chargingStation = chargingStation;
10 this._timeToStop = true;
11 if (this._chargingStation.getEnableStatistics()) {
12 this._performanceObserver = new PerformanceObserver((list) => {
13 const entry = list.getEntries()[0];
14 this._chargingStation._statistics.logPerformance(entry, 'AutomaticTransactionGenerator');
15 this._performanceObserver.disconnect();
16 });
17 }
18 }
19
20 get timeToStop() {
21 return this._timeToStop;
22 }
23
24 _logPrefix(connectorId = null) {
25 if (connectorId) {
26 return Utils.logPrefix(' ' + this._chargingStation._stationInfo.name + ' ATG on connector #' + connectorId + ':');
27 }
28 return Utils.logPrefix(' ' + this._chargingStation._stationInfo.name + ' ATG:');
29 }
30
31 async start() {
32 this._timeToStop = false;
33 if (this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours &&
34 this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours > 0) {
35 setTimeout(() => {
36 this.stop();
37 }, this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours * 3600 * 1000);
38 }
39 for (const connector in this._chargingStation._connectors) {
40 if (connector > 0) {
41 this.startConnector(connector);
42 }
43 }
44 logger.info(this._logPrefix() + ' ATG started and will stop in ' + Utils.secondstoHHMMSS(this._chargingStation._stationInfo.AutomaticTransactionGenerator.stopAfterHours * 3600));
45 }
46
47 async stop(reason = '') {
48 logger.info(this._logPrefix() + ' ATG OVER => STOPPING ALL TRANSACTIONS');
49 for (const connector in this._chargingStation._connectors) {
50 if (this._chargingStation.getConnector(connector).transactionStarted) {
51 logger.info(this._logPrefix(connector) + ' ATG OVER. Stop transaction ' + this._chargingStation.getConnector(connector).transactionId);
52 await this._chargingStation.sendStopTransaction(this._chargingStation.getConnector(connector).transactionId, reason);
53 }
54 }
55 this._timeToStop = true;
56 }
57
58 async startConnector(connectorId) {
59 do {
60 const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransactions,
61 this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransactions) * 1000;
62 logger.info(this._logPrefix(connectorId) + ' wait for ' + Utils.secondstoHHMMSS(wait / 1000));
63 await Utils.sleep(wait);
64 if (this._timeToStop) {
65 logger.debug(this._logPrefix(connectorId) + ' Entered in transaction loop while a request to stop it was made');
66 break;
67 }
68 const start = Math.random();
69 let skip = 0;
70 if (start < this._chargingStation._stationInfo.AutomaticTransactionGenerator.probabilityOfStart) {
71 skip = 0;
72 // Start transaction
73 let startResponse;
74 if (this._chargingStation.getEnableStatistics()) {
75 const startTransaction = performance.timerify(this.startTransaction);
76 this._performanceObserver.observe({entryTypes: ['function']});
77 startResponse = await startTransaction(connectorId, this);
78 } else {
79 startResponse = await this.startTransaction(connectorId, this);
80 }
81 if (startResponse.idTagInfo.status !== 'Accepted') {
82 logger.info(this._logPrefix(connectorId) + ' transaction rejected');
83 await Utils.sleep(Constants.CHARGING_STATION_ATG_WAIT_TIME);
84 } else {
85 // Wait until end of transaction
86 const wait = Utils.getRandomInt(this._chargingStation._stationInfo.AutomaticTransactionGenerator.maxDuration,
87 this._chargingStation._stationInfo.AutomaticTransactionGenerator.minDuration) * 1000;
88 logger.info(this._logPrefix(connectorId) + ' transaction ' + this._chargingStation.getConnector(connectorId).transactionId + ' will stop in ' + Utils.secondstoHHMMSS(wait / 1000));
89 await Utils.sleep(wait);
90 // Stop transaction
91 if (this._chargingStation.getConnector(connectorId).transactionStarted) {
92 logger.info(this._logPrefix(connectorId) + ' stop transaction ' + this._chargingStation.getConnector(connectorId).transactionId);
93 if (this._chargingStation.getEnableStatistics()) {
94 const stopTransaction = performance.timerify(this.stopTransaction);
95 this._performanceObserver.observe({entryTypes: ['function']});
96 await stopTransaction(connectorId, this);
97 } else {
98 await this.stopTransaction(connectorId, this);
99 }
100 }
101 }
102 } else {
103 skip++;
104 logger.info(this._logPrefix(connectorId) + ' transaction skipped ' + skip);
105 }
106 } while (!this._timeToStop);
107 logger.info(this._logPrefix(connectorId) + ' ATG STOPPED on the connector');
108 }
109
110 // eslint-disable-next-line class-methods-use-this
111 async startTransaction(connectorId, self) {
112 if (self._chargingStation.hasAuthorizedTags()) {
113 const tagId = self._chargingStation.getRandomTagId();
114 logger.info(self._logPrefix(connectorId) + ' start transaction for tagID ' + tagId);
115 return self._chargingStation.sendStartTransaction(connectorId, tagId);
116 }
117 return self._chargingStation.sendStartTransaction(connectorId);
118 }
119
120 // eslint-disable-next-line class-methods-use-this
121 async stopTransaction(connectorId, self) {
122 await self._chargingStation.sendStopTransaction(self._chargingStation.getConnector(connectorId).transactionId);
123 }
124 }