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