1 import {PerformanceObserver
, performance
} from 'perf_hooks';
3 import Constants
from '../utils/Constants.js';
4 import Utils
from '../utils/Utils.js';
5 import logger
from '../utils/Logger.js';
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();
21 return this._timeToStop
;
24 _logPrefix(connectorId
= null) {
26 return Utils
.logPrefix(' ' + this._chargingStation
._stationInfo
.name
+ ' ATG on connector #' + connectorId
+ ':');
28 return Utils
.logPrefix(' ' + this._chargingStation
._stationInfo
.name
+ ' ATG:');
32 this._timeToStop
= false;
33 if (this._chargingStation
._stationInfo
.AutomaticTransactionGenerator
.stopAfterHours
&&
34 this._chargingStation
._stationInfo
.AutomaticTransactionGenerator
.stopAfterHours
> 0) {
37 }, this._chargingStation
._stationInfo
.AutomaticTransactionGenerator
.stopAfterHours
* 3600 * 1000);
39 for (const connector
in this._chargingStation
._connectors
) {
41 this.startConnector(connector
);
44 logger
.info(this._logPrefix() + ' ATG started and will stop in ' + Utils
.secondstoHHMMSS(this._chargingStation
._stationInfo
.AutomaticTransactionGenerator
.stopAfterHours
* 3600));
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
);
55 this._timeToStop
= true;
58 async
startConnector(connectorId
) {
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');
68 const start
= Math
.random();
70 if (start
< this._chargingStation
._stationInfo
.AutomaticTransactionGenerator
.probabilityOfStart
) {
74 if (this._chargingStation
.getEnableStatistics()) {
75 const startTransaction
= performance
.timerify(this.startTransaction
);
76 this._performanceObserver
.observe({entryTypes
: ['function']});
77 startResponse
= await
startTransaction(connectorId
, this);
79 startResponse
= await
this.startTransaction(connectorId
, this);
81 if (startResponse
.idTagInfo
.status
!== 'Accepted') {
82 logger
.info(this._logPrefix(connectorId
) + ' transaction rejected');
83 await Utils
.sleep(Constants
.CHARGING_STATION_ATG_WAIT_TIME
);
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
);
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);
98 await
this.stopTransaction(connectorId
, this);
104 logger
.info(this._logPrefix(connectorId
) + ' transaction skipped ' + skip
);
106 } while (!this._timeToStop
);
107 logger
.info(this._logPrefix(connectorId
) + ' ATG STOPPED on the connector');
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
);
117 return self
._chargingStation
.sendStartTransaction(connectorId
);
120 // eslint-disable-next-line class-methods-use-this
121 async
stopTransaction(connectorId
, self
) {
122 await self
._chargingStation
.sendStopTransaction(self
._chargingStation
.getConnector(connectorId
).transactionId
);