refactor: code cleanup
[e-mobility-charging-stations-simulator.git] / src / charging-station / AutomaticTransactionGenerator.ts
CommitLineData
edd13439 1// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
c8eeb62b 2
01f4001e 3import { AsyncResource } from 'node:async_hooks';
d4b944ae 4
be4c6702
JB
5import { hoursToMilliseconds, secondsToMilliseconds } from 'date-fns';
6
4c3c0d59 7import type { ChargingStation } from './ChargingStation';
08b58f00 8import { checkChargingStation } from './Helpers';
4c3c0d59 9import { IdTagsCache } from './IdTagsCache';
268a74bb 10import { BaseError } from '../exception';
b84bca85 11import { PerformanceStatistics } from '../performance';
e7aeea18
JB
12import {
13 AuthorizationStatus,
976d11ec
JB
14 type AuthorizeRequest,
15 type AuthorizeResponse,
9b4d0c70 16 ConnectorStatusEnum,
268a74bb 17 RequestCommand,
976d11ec
JB
18 type StartTransactionRequest,
19 type StartTransactionResponse,
268a74bb 20 type Status,
e7aeea18 21 StopTransactionReason,
976d11ec 22 type StopTransactionResponse,
268a74bb 23} from '../types';
9bf0ef23
JB
24import {
25 Constants,
26 cloneObject,
27 formatDurationMilliSeconds,
28 getRandomInteger,
29 isNullOrUndefined,
30 logPrefix,
31 logger,
32 secureRandom,
33 sleep,
34} from '../utils';
6af9012e 35
d4b944ae
JB
36const moduleName = 'AutomaticTransactionGenerator';
37
268a74bb 38export class AutomaticTransactionGenerator extends AsyncResource {
e7aeea18
JB
39 private static readonly instances: Map<string, AutomaticTransactionGenerator> = new Map<
40 string,
41 AutomaticTransactionGenerator
42 >();
10068088 43
5e3cb728 44 public readonly connectorsStatus: Map<number, Status>;
265e4266 45 public started: boolean;
11353865
JB
46 private starting: boolean;
47 private stopping: boolean;
9e23580d 48 private readonly chargingStation: ChargingStation;
6af9012e 49
ac7f79af 50 private constructor(chargingStation: ChargingStation) {
d4b944ae 51 super(moduleName);
aa428a31 52 this.started = false;
11353865
JB
53 this.starting = false;
54 this.stopping = false;
ad2f27c3 55 this.chargingStation = chargingStation;
7807ccf2
JB
56 this.connectorsStatus = new Map<number, Status>();
57 this.initializeConnectorsStatus();
6af9012e
JB
58 }
59
fa7bccf4 60 public static getInstance(
5edd8ba0 61 chargingStation: ChargingStation,
1895299d 62 ): AutomaticTransactionGenerator | undefined {
4dff3039 63 if (AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo.hashId) === false) {
e7aeea18 64 AutomaticTransactionGenerator.instances.set(
51c83d6f 65 chargingStation.stationInfo.hashId,
5edd8ba0 66 new AutomaticTransactionGenerator(chargingStation),
e7aeea18 67 );
73b9adec 68 }
51c83d6f 69 return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo.hashId);
73b9adec
JB
70 }
71
7d75bee1 72 public start(): void {
fba11dc6 73 if (checkChargingStation(this.chargingStation, this.logPrefix()) === false) {
d1c6c833
JB
74 return;
75 }
a5e9befc 76 if (this.started === true) {
ba7965c4 77 logger.warn(`${this.logPrefix()} is already started`);
b809adf1
JB
78 return;
79 }
11353865
JB
80 if (this.starting === true) {
81 logger.warn(`${this.logPrefix()} is already starting`);
82 return;
83 }
84 this.starting = true;
72740232 85 this.startConnectors();
265e4266 86 this.started = true;
11353865 87 this.starting = false;
6af9012e
JB
88 }
89
0045cef5 90 public stop(): void {
a5e9befc 91 if (this.started === false) {
ba7965c4 92 logger.warn(`${this.logPrefix()} is already stopped`);
265e4266
JB
93 return;
94 }
11353865
JB
95 if (this.stopping === true) {
96 logger.warn(`${this.logPrefix()} is already stopping`);
97 return;
98 }
99 this.stopping = true;
72740232 100 this.stopConnectors();
265e4266 101 this.started = false;
11353865 102 this.stopping = false;
6af9012e
JB
103 }
104
a5e9befc 105 public startConnector(connectorId: number): void {
fba11dc6 106 if (checkChargingStation(this.chargingStation, this.logPrefix(connectorId)) === false) {
d1c6c833
JB
107 return;
108 }
7807ccf2 109 if (this.connectorsStatus.has(connectorId) === false) {
a03a128d 110 logger.error(`${this.logPrefix(connectorId)} starting on non existing connector`);
7807ccf2 111 throw new BaseError(`Connector ${connectorId} does not exist`);
a5e9befc
JB
112 }
113 if (this.connectorsStatus.get(connectorId)?.start === false) {
d4b944ae 114 this.runInAsyncScope(
e6159ce8
JB
115 this.internalStartConnector.bind(this) as (
116 this: AutomaticTransactionGenerator,
e843aa40 117 ...args: unknown[]
64818750 118 ) => Promise<void>,
d4b944ae 119 this,
5edd8ba0 120 connectorId,
59b6ed8d 121 ).catch(Constants.EMPTY_FUNCTION);
ecb3869d 122 } else if (this.connectorsStatus.get(connectorId)?.start === true) {
ba7965c4 123 logger.warn(`${this.logPrefix(connectorId)} is already started on connector`);
a5e9befc
JB
124 }
125 }
126
127 public stopConnector(connectorId: number): void {
7807ccf2 128 if (this.connectorsStatus.has(connectorId) === false) {
a03a128d 129 logger.error(`${this.logPrefix(connectorId)} stopping on non existing connector`);
7807ccf2 130 throw new BaseError(`Connector ${connectorId} does not exist`);
ba7965c4
JB
131 }
132 if (this.connectorsStatus.get(connectorId)?.start === true) {
e1d9a0f4 133 this.connectorsStatus.get(connectorId)!.start = false;
ba7965c4
JB
134 } else if (this.connectorsStatus.get(connectorId)?.start === false) {
135 logger.warn(`${this.logPrefix(connectorId)} is already stopped on connector`);
136 }
a5e9befc
JB
137 }
138
72740232 139 private startConnectors(): void {
e7aeea18
JB
140 if (
141 this.connectorsStatus?.size > 0 &&
142 this.connectorsStatus.size !== this.chargingStation.getNumberOfConnectors()
143 ) {
54544ef1 144 this.connectorsStatus.clear();
7807ccf2 145 this.initializeConnectorsStatus();
54544ef1 146 }
4334db72
JB
147 if (this.chargingStation.hasEvses) {
148 for (const [evseId, evseStatus] of this.chargingStation.evses) {
149 if (evseId > 0) {
150 for (const connectorId of evseStatus.connectors.keys()) {
151 this.startConnector(connectorId);
152 }
153 }
154 }
155 } else {
156 for (const connectorId of this.chargingStation.connectors.keys()) {
157 if (connectorId > 0) {
158 this.startConnector(connectorId);
159 }
72740232
JB
160 }
161 }
162 }
163
164 private stopConnectors(): void {
4334db72
JB
165 if (this.chargingStation.hasEvses) {
166 for (const [evseId, evseStatus] of this.chargingStation.evses) {
167 if (evseId > 0) {
168 for (const connectorId of evseStatus.connectors.keys()) {
169 this.stopConnector(connectorId);
170 }
171 }
172 }
173 } else {
174 for (const connectorId of this.chargingStation.connectors.keys()) {
175 if (connectorId > 0) {
176 this.stopConnector(connectorId);
177 }
72740232
JB
178 }
179 }
180 }
181
83a3286a 182 private async internalStartConnector(connectorId: number): Promise<void> {
083fb002 183 this.setStartConnectorStatus(connectorId);
e7aeea18 184 logger.info(
44eb6026 185 `${this.logPrefix(
5edd8ba0 186 connectorId,
9bf0ef23 187 )} started on connector and will run for ${formatDurationMilliSeconds(
e1d9a0f4
JB
188 this.connectorsStatus.get(connectorId)!.stopDate!.getTime() -
189 this.connectorsStatus.get(connectorId)!.startDate!.getTime(),
5edd8ba0 190 )}`,
e7aeea18 191 );
1895299d 192 while (this.connectorsStatus.get(connectorId)?.start === true) {
0bd926c1 193 if (!this.canStartConnector(connectorId)) {
9b4d0c70
JB
194 this.stopConnector(connectorId);
195 break;
196 }
c0560973 197 if (!this.chargingStation?.ocppRequestService) {
e7aeea18
JB
198 logger.info(
199 `${this.logPrefix(
5edd8ba0
JB
200 connectorId,
201 )} transaction loop waiting for charging station service to be initialized`,
e7aeea18 202 );
c0560973 203 do {
9bf0ef23 204 await sleep(Constants.CHARGING_STATION_ATG_INITIALIZATION_TIME);
c0560973
JB
205 } while (!this.chargingStation?.ocppRequestService);
206 }
be4c6702 207 const wait = secondsToMilliseconds(
9bf0ef23 208 getRandomInteger(
ac7f79af 209 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
86b46b49 210 .maxDelayBetweenTwoTransactions,
ac7f79af 211 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
5edd8ba0 212 .minDelayBetweenTwoTransactions,
be4c6702
JB
213 ),
214 );
9bf0ef23
JB
215 logger.info(`${this.logPrefix(connectorId)} waiting for ${formatDurationMilliSeconds(wait)}`);
216 await sleep(wait);
217 const start = secureRandom();
ac7f79af
JB
218 if (
219 start <
220 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().probabilityOfStart
221 ) {
e1d9a0f4 222 this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0;
6af9012e 223 // Start transaction
aef1b33a 224 const startResponse = await this.startTransaction(connectorId);
0afed85f 225 if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
6af9012e 226 // Wait until end of transaction
be4c6702 227 const waitTrxEnd = secondsToMilliseconds(
9bf0ef23 228 getRandomInteger(
86b46b49 229 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().maxDuration,
5edd8ba0 230 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().minDuration,
be4c6702
JB
231 ),
232 );
e7aeea18 233 logger.info(
54ebb82c 234 `${this.logPrefix(connectorId)} transaction started with id ${this.chargingStation
44eb6026 235 .getConnectorStatus(connectorId)
9bf0ef23 236 ?.transactionId?.toString()} and will stop in ${formatDurationMilliSeconds(
5edd8ba0
JB
237 waitTrxEnd,
238 )}`,
e7aeea18 239 );
9bf0ef23 240 await sleep(waitTrxEnd);
6af9012e 241 // Stop transaction
e7aeea18 242 logger.info(
54ebb82c 243 `${this.logPrefix(connectorId)} stop transaction with id ${this.chargingStation
44eb6026 244 .getConnectorStatus(connectorId)
5edd8ba0 245 ?.transactionId?.toString()}`,
e7aeea18 246 );
85d20667 247 await this.stopTransaction(connectorId);
6af9012e
JB
248 }
249 } else {
e1d9a0f4
JB
250 ++this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions!;
251 ++this.connectorsStatus.get(connectorId)!.skippedTransactions!;
e7aeea18 252 logger.info(
44eb6026
JB
253 `${this.logPrefix(connectorId)} skipped consecutively ${this.connectorsStatus
254 .get(connectorId)
1895299d 255 ?.skippedConsecutiveTransactions?.toString()}/${this.connectorsStatus
44eb6026 256 .get(connectorId)
5edd8ba0 257 ?.skippedTransactions?.toString()} transaction(s)`,
e7aeea18 258 );
6af9012e 259 }
e1d9a0f4 260 this.connectorsStatus.get(connectorId)!.lastRunDate = new Date();
7d75bee1 261 }
e1d9a0f4 262 this.connectorsStatus.get(connectorId)!.stoppedDate = new Date();
e7aeea18 263 logger.info(
44eb6026 264 `${this.logPrefix(
5edd8ba0 265 connectorId,
9bf0ef23 266 )} stopped on connector and lasted for ${formatDurationMilliSeconds(
e1d9a0f4
JB
267 this.connectorsStatus.get(connectorId)!.stoppedDate!.getTime() -
268 this.connectorsStatus.get(connectorId)!.startDate!.getTime(),
5edd8ba0 269 )}`,
e7aeea18
JB
270 );
271 logger.debug(
be9ee554 272 `${this.logPrefix(connectorId)} connector status: %j`,
5edd8ba0 273 this.connectorsStatus.get(connectorId),
e7aeea18 274 );
6af9012e
JB
275 }
276
083fb002 277 private setStartConnectorStatus(connectorId: number): void {
e1d9a0f4 278 this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0;
e7aeea18 279 const previousRunDuration =
72092cfc
JB
280 this.connectorsStatus.get(connectorId)?.startDate &&
281 this.connectorsStatus.get(connectorId)?.lastRunDate
e1d9a0f4
JB
282 ? this.connectorsStatus.get(connectorId)!.lastRunDate!.getTime() -
283 this.connectorsStatus.get(connectorId)!.startDate!.getTime()
e7aeea18 284 : 0;
e1d9a0f4
JB
285 this.connectorsStatus.get(connectorId)!.startDate = new Date();
286 this.connectorsStatus.get(connectorId)!.stopDate = new Date(
287 this.connectorsStatus.get(connectorId)!.startDate!.getTime() +
be4c6702
JB
288 hoursToMilliseconds(
289 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().stopAfterHours,
290 ) -
5edd8ba0 291 previousRunDuration,
e7aeea18 292 );
e1d9a0f4 293 this.connectorsStatus.get(connectorId)!.start = true;
4dff3039
JB
294 }
295
0bd926c1
JB
296 private canStartConnector(connectorId: number): boolean {
297 if (new Date() > this.connectorsStatus.get(connectorId)!.stopDate!) {
298 return false;
299 }
300 if (this.chargingStation.inAcceptedState() === false) {
301 logger.error(
302 `${this.logPrefix(
303 connectorId,
304 )} entered in transaction loop while the charging station is not in accepted state`,
305 );
306 return false;
307 }
308 if (this.chargingStation.isChargingStationAvailable() === false) {
309 logger.info(
310 `${this.logPrefix(
311 connectorId,
312 )} entered in transaction loop while the charging station is unavailable`,
313 );
314 return false;
315 }
316 if (this.chargingStation.isConnectorAvailable(connectorId) === false) {
317 logger.info(
318 `${this.logPrefix(
319 connectorId,
320 )} entered in transaction loop while the connector ${connectorId} is unavailable`,
321 );
322 return false;
323 }
324 if (
325 this.chargingStation.getConnectorStatus(connectorId)?.status ===
326 ConnectorStatusEnum.Unavailable
327 ) {
328 logger.info(
329 `${this.logPrefix(
330 connectorId,
331 )} entered in transaction loop while the connector ${connectorId} status is unavailable`,
332 );
333 return false;
334 }
335 return true;
336 }
337
7807ccf2 338 private initializeConnectorsStatus(): void {
4334db72
JB
339 if (this.chargingStation.hasEvses) {
340 for (const [evseId, evseStatus] of this.chargingStation.evses) {
341 if (evseId > 0) {
342 for (const connectorId of evseStatus.connectors.keys()) {
5ced7e80 343 this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
4334db72
JB
344 }
345 }
346 }
347 } else {
348 for (const connectorId of this.chargingStation.connectors.keys()) {
349 if (connectorId > 0) {
5ced7e80 350 this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
4334db72 351 }
4dff3039
JB
352 }
353 }
72740232
JB
354 }
355
5ced7e80 356 private getConnectorStatus(connectorId: number): Status {
bdc9dc79 357 const connectorStatus = this.chargingStation.getAutomaticTransactionGeneratorStatuses()
32f5e42d
JB
358 ? cloneObject<Status[]>(this.chargingStation.getAutomaticTransactionGeneratorStatuses()!)[
359 connectorId
360 ]
bdc9dc79 361 : undefined;
5ced7e80
JB
362 delete connectorStatus?.startDate;
363 delete connectorStatus?.lastRunDate;
364 delete connectorStatus?.stopDate;
365 delete connectorStatus?.stoppedDate;
366 return (
367 connectorStatus ?? {
368 start: false,
369 authorizeRequests: 0,
370 acceptedAuthorizeRequests: 0,
371 rejectedAuthorizeRequests: 0,
372 startTransactionRequests: 0,
373 acceptedStartTransactionRequests: 0,
374 rejectedStartTransactionRequests: 0,
375 stopTransactionRequests: 0,
376 acceptedStopTransactionRequests: 0,
377 rejectedStopTransactionRequests: 0,
378 skippedConsecutiveTransactions: 0,
379 skippedTransactions: 0,
380 }
381 );
382 }
383
e7aeea18 384 private async startTransaction(
5edd8ba0 385 connectorId: number,
0afed85f 386 ): Promise<StartTransactionResponse | undefined> {
aef1b33a
JB
387 const measureId = 'StartTransaction with ATG';
388 const beginId = PerformanceStatistics.beginMeasure(measureId);
e1d9a0f4 389 let startResponse: StartTransactionResponse | undefined;
f911a4af
JB
390 if (this.chargingStation.hasIdTags()) {
391 const idTag = IdTagsCache.getInstance().getIdTag(
e1d9a0f4 392 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().idTagDistribution!,
aaf2bf9c 393 this.chargingStation,
5edd8ba0 394 connectorId,
aaf2bf9c 395 );
5cf9050d 396 const startTransactionLogMsg = `${this.logPrefix(
5edd8ba0 397 connectorId,
ba7965c4 398 )} start transaction with an idTag '${idTag}'`;
ccb1d6e9 399 if (this.getRequireAuthorize()) {
f4bf2abd 400 // Authorize idTag
2e3d65ae 401 const authorizeResponse: AuthorizeResponse =
f7f98c68 402 await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
403 AuthorizeRequest,
404 AuthorizeResponse
08f130a0 405 >(this.chargingStation, RequestCommand.AUTHORIZE, {
ef6fa3fb
JB
406 idTag,
407 });
e1d9a0f4 408 ++this.connectorsStatus.get(connectorId)!.authorizeRequests!;
5fdab605 409 if (authorizeResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
d984c13f 410 if (
611d5cd2 411 isNullOrUndefined(this.chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag)
d984c13f
JB
412 ) {
413 logger.warn(
414 `${this.chargingStation.logPrefix()} IdTag ${idTag} is not set as authorized remotely, applying deferred initialization`,
415 );
416 this.chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag = idTag;
417 }
e1d9a0f4 418 ++this.connectorsStatus.get(connectorId)!.acceptedAuthorizeRequests!;
5cf9050d 419 logger.info(startTransactionLogMsg);
5fdab605 420 // Start transaction
f7f98c68 421 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
422 StartTransactionRequest,
423 StartTransactionResponse
08f130a0 424 >(this.chargingStation, RequestCommand.START_TRANSACTION, {
ef6fa3fb
JB
425 connectorId,
426 idTag,
427 });
d9ac47ef 428 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
429 PerformanceStatistics.endMeasure(measureId, beginId);
430 return startResponse;
5fdab605 431 }
e1d9a0f4 432 ++this.connectorsStatus.get(connectorId)!.rejectedAuthorizeRequests!;
aef1b33a 433 PerformanceStatistics.endMeasure(measureId, beginId);
0afed85f 434 return startResponse;
ef6076c1 435 }
5cf9050d 436 logger.info(startTransactionLogMsg);
5fdab605 437 // Start transaction
f7f98c68 438 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
439 StartTransactionRequest,
440 StartTransactionResponse
08f130a0 441 >(this.chargingStation, RequestCommand.START_TRANSACTION, {
ef6fa3fb
JB
442 connectorId,
443 idTag,
444 });
d9ac47ef 445 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
446 PerformanceStatistics.endMeasure(measureId, beginId);
447 return startResponse;
6af9012e 448 }
5cf9050d 449 logger.info(`${this.logPrefix(connectorId)} start transaction without an idTag`);
f7f98c68 450 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
451 StartTransactionRequest,
452 StartTransactionResponse
08f130a0 453 >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId });
431b6bd5 454 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
455 PerformanceStatistics.endMeasure(measureId, beginId);
456 return startResponse;
6af9012e
JB
457 }
458
e7aeea18
JB
459 private async stopTransaction(
460 connectorId: number,
5edd8ba0 461 reason: StopTransactionReason = StopTransactionReason.LOCAL,
e1d9a0f4 462 ): Promise<StopTransactionResponse | undefined> {
aef1b33a
JB
463 const measureId = 'StopTransaction with ATG';
464 const beginId = PerformanceStatistics.beginMeasure(measureId);
e1d9a0f4 465 let stopResponse: StopTransactionResponse | undefined;
6d9876e7 466 if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
5e3cb728 467 stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason);
e1d9a0f4 468 ++this.connectorsStatus.get(connectorId)!.stopTransactionRequests!;
0afed85f 469 if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
e1d9a0f4 470 ++this.connectorsStatus.get(connectorId)!.acceptedStopTransactionRequests!;
6d9876e7 471 } else {
e1d9a0f4 472 ++this.connectorsStatus.get(connectorId)!.rejectedStopTransactionRequests!;
6d9876e7 473 }
0045cef5 474 } else {
1895299d 475 const transactionId = this.chargingStation.getConnectorStatus(connectorId)?.transactionId;
e7aeea18 476 logger.warn(
ba7965c4 477 `${this.logPrefix(connectorId)} stopping a not started transaction${
9bf0ef23 478 !isNullOrUndefined(transactionId) ? ` with id ${transactionId?.toString()}` : ''
5edd8ba0 479 }`,
e7aeea18 480 );
0045cef5 481 }
aef1b33a
JB
482 PerformanceStatistics.endMeasure(measureId, beginId);
483 return stopResponse;
c0560973
JB
484 }
485
ccb1d6e9 486 private getRequireAuthorize(): boolean {
ac7f79af
JB
487 return (
488 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.requireAuthorize ?? true
489 );
ccb1d6e9
JB
490 }
491
8b7072dc 492 private logPrefix = (connectorId?: number): string => {
9bf0ef23 493 return logPrefix(
6cd85def 494 ` ${this.chargingStation.stationInfo.chargingStationId} | ATG${
e1d9a0f4 495 !isNullOrUndefined(connectorId) ? ` on connector #${connectorId!.toString()}` : ''
5edd8ba0 496 }:`,
6cd85def 497 );
8b7072dc 498 };
d9ac47ef
JB
499
500 private handleStartTransactionResponse(
501 connectorId: number,
5edd8ba0 502 startResponse: StartTransactionResponse,
d9ac47ef 503 ): void {
e1d9a0f4 504 ++this.connectorsStatus.get(connectorId)!.startTransactionRequests!;
d9ac47ef 505 if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
e1d9a0f4 506 ++this.connectorsStatus.get(connectorId)!.acceptedStartTransactionRequests!;
d9ac47ef 507 } else {
44eb6026 508 logger.warn(`${this.logPrefix(connectorId)} start transaction rejected`);
e1d9a0f4 509 ++this.connectorsStatus.get(connectorId)!.rejectedStartTransactionRequests!;
d9ac47ef
JB
510 }
511 }
6af9012e 512}