docs: refine README.md
[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';
fba11dc6 8import { checkChargingStation } from './ChargingStationUtils';
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) {
e1d9a0f4 193 if (new Date() > this.connectorsStatus.get(connectorId)!.stopDate!) {
9664ec50 194 this.stopConnector(connectorId);
17991e8c
JB
195 break;
196 }
f7c2994d 197 if (this.chargingStation.inAcceptedState() === false) {
e7aeea18 198 logger.error(
44eb6026 199 `${this.logPrefix(
5edd8ba0
JB
200 connectorId,
201 )} entered in transaction loop while the charging station is not in accepted state`,
e7aeea18 202 );
9664ec50 203 this.stopConnector(connectorId);
17991e8c
JB
204 break;
205 }
1789ba2c 206 if (this.chargingStation.isChargingStationAvailable() === false) {
e7aeea18 207 logger.info(
44eb6026 208 `${this.logPrefix(
5edd8ba0
JB
209 connectorId,
210 )} entered in transaction loop while the charging station is unavailable`,
e7aeea18 211 );
9664ec50 212 this.stopConnector(connectorId);
ab5f4b03
JB
213 break;
214 }
1789ba2c 215 if (this.chargingStation.isConnectorAvailable(connectorId) === false) {
e7aeea18
JB
216 logger.info(
217 `${this.logPrefix(
5edd8ba0
JB
218 connectorId,
219 )} entered in transaction loop while the connector ${connectorId} is unavailable`,
e7aeea18 220 );
9c7195b2 221 this.stopConnector(connectorId);
17991e8c
JB
222 break;
223 }
9b4d0c70
JB
224 if (
225 this.chargingStation.getConnectorStatus(connectorId)?.status ===
226 ConnectorStatusEnum.Unavailable
227 ) {
228 logger.info(
229 `${this.logPrefix(
5edd8ba0
JB
230 connectorId,
231 )} entered in transaction loop while the connector ${connectorId} status is unavailable`,
9b4d0c70
JB
232 );
233 this.stopConnector(connectorId);
234 break;
235 }
c0560973 236 if (!this.chargingStation?.ocppRequestService) {
e7aeea18
JB
237 logger.info(
238 `${this.logPrefix(
5edd8ba0
JB
239 connectorId,
240 )} transaction loop waiting for charging station service to be initialized`,
e7aeea18 241 );
c0560973 242 do {
9bf0ef23 243 await sleep(Constants.CHARGING_STATION_ATG_INITIALIZATION_TIME);
c0560973
JB
244 } while (!this.chargingStation?.ocppRequestService);
245 }
be4c6702 246 const wait = secondsToMilliseconds(
9bf0ef23 247 getRandomInteger(
ac7f79af 248 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
86b46b49 249 .maxDelayBetweenTwoTransactions,
ac7f79af 250 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
5edd8ba0 251 .minDelayBetweenTwoTransactions,
be4c6702
JB
252 ),
253 );
9bf0ef23
JB
254 logger.info(`${this.logPrefix(connectorId)} waiting for ${formatDurationMilliSeconds(wait)}`);
255 await sleep(wait);
256 const start = secureRandom();
ac7f79af
JB
257 if (
258 start <
259 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().probabilityOfStart
260 ) {
e1d9a0f4 261 this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0;
6af9012e 262 // Start transaction
aef1b33a 263 const startResponse = await this.startTransaction(connectorId);
0afed85f 264 if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
6af9012e 265 // Wait until end of transaction
be4c6702 266 const waitTrxEnd = secondsToMilliseconds(
9bf0ef23 267 getRandomInteger(
86b46b49 268 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().maxDuration,
5edd8ba0 269 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().minDuration,
be4c6702
JB
270 ),
271 );
e7aeea18 272 logger.info(
54ebb82c 273 `${this.logPrefix(connectorId)} transaction started with id ${this.chargingStation
44eb6026 274 .getConnectorStatus(connectorId)
9bf0ef23 275 ?.transactionId?.toString()} and will stop in ${formatDurationMilliSeconds(
5edd8ba0
JB
276 waitTrxEnd,
277 )}`,
e7aeea18 278 );
9bf0ef23 279 await sleep(waitTrxEnd);
6af9012e 280 // Stop transaction
e7aeea18 281 logger.info(
54ebb82c 282 `${this.logPrefix(connectorId)} stop transaction with id ${this.chargingStation
44eb6026 283 .getConnectorStatus(connectorId)
5edd8ba0 284 ?.transactionId?.toString()}`,
e7aeea18 285 );
85d20667 286 await this.stopTransaction(connectorId);
6af9012e
JB
287 }
288 } else {
e1d9a0f4
JB
289 ++this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions!;
290 ++this.connectorsStatus.get(connectorId)!.skippedTransactions!;
e7aeea18 291 logger.info(
44eb6026
JB
292 `${this.logPrefix(connectorId)} skipped consecutively ${this.connectorsStatus
293 .get(connectorId)
1895299d 294 ?.skippedConsecutiveTransactions?.toString()}/${this.connectorsStatus
44eb6026 295 .get(connectorId)
5edd8ba0 296 ?.skippedTransactions?.toString()} transaction(s)`,
e7aeea18 297 );
6af9012e 298 }
e1d9a0f4 299 this.connectorsStatus.get(connectorId)!.lastRunDate = new Date();
7d75bee1 300 }
e1d9a0f4 301 this.connectorsStatus.get(connectorId)!.stoppedDate = new Date();
e7aeea18 302 logger.info(
44eb6026 303 `${this.logPrefix(
5edd8ba0 304 connectorId,
9bf0ef23 305 )} stopped on connector and lasted for ${formatDurationMilliSeconds(
e1d9a0f4
JB
306 this.connectorsStatus.get(connectorId)!.stoppedDate!.getTime() -
307 this.connectorsStatus.get(connectorId)!.startDate!.getTime(),
5edd8ba0 308 )}`,
e7aeea18
JB
309 );
310 logger.debug(
be9ee554 311 `${this.logPrefix(connectorId)} connector status: %j`,
5edd8ba0 312 this.connectorsStatus.get(connectorId),
e7aeea18 313 );
6af9012e
JB
314 }
315
083fb002 316 private setStartConnectorStatus(connectorId: number): void {
e1d9a0f4 317 this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0;
e7aeea18 318 const previousRunDuration =
72092cfc
JB
319 this.connectorsStatus.get(connectorId)?.startDate &&
320 this.connectorsStatus.get(connectorId)?.lastRunDate
e1d9a0f4
JB
321 ? this.connectorsStatus.get(connectorId)!.lastRunDate!.getTime() -
322 this.connectorsStatus.get(connectorId)!.startDate!.getTime()
e7aeea18 323 : 0;
e1d9a0f4
JB
324 this.connectorsStatus.get(connectorId)!.startDate = new Date();
325 this.connectorsStatus.get(connectorId)!.stopDate = new Date(
326 this.connectorsStatus.get(connectorId)!.startDate!.getTime() +
be4c6702
JB
327 hoursToMilliseconds(
328 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().stopAfterHours,
329 ) -
5edd8ba0 330 previousRunDuration,
e7aeea18 331 );
e1d9a0f4 332 this.connectorsStatus.get(connectorId)!.start = true;
4dff3039
JB
333 }
334
7807ccf2 335 private initializeConnectorsStatus(): void {
4334db72
JB
336 if (this.chargingStation.hasEvses) {
337 for (const [evseId, evseStatus] of this.chargingStation.evses) {
338 if (evseId > 0) {
339 for (const connectorId of evseStatus.connectors.keys()) {
5ced7e80 340 this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
4334db72
JB
341 }
342 }
343 }
344 } else {
345 for (const connectorId of this.chargingStation.connectors.keys()) {
346 if (connectorId > 0) {
5ced7e80 347 this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
4334db72 348 }
4dff3039
JB
349 }
350 }
72740232
JB
351 }
352
5ced7e80 353 private getConnectorStatus(connectorId: number): Status {
bdc9dc79
JB
354 const connectorStatus = this.chargingStation.getAutomaticTransactionGeneratorStatuses()
355 ? cloneObject(this.chargingStation.getAutomaticTransactionGeneratorStatuses()!)[connectorId]
356 : undefined;
5ced7e80
JB
357 delete connectorStatus?.startDate;
358 delete connectorStatus?.lastRunDate;
359 delete connectorStatus?.stopDate;
360 delete connectorStatus?.stoppedDate;
361 return (
362 connectorStatus ?? {
363 start: false,
364 authorizeRequests: 0,
365 acceptedAuthorizeRequests: 0,
366 rejectedAuthorizeRequests: 0,
367 startTransactionRequests: 0,
368 acceptedStartTransactionRequests: 0,
369 rejectedStartTransactionRequests: 0,
370 stopTransactionRequests: 0,
371 acceptedStopTransactionRequests: 0,
372 rejectedStopTransactionRequests: 0,
373 skippedConsecutiveTransactions: 0,
374 skippedTransactions: 0,
375 }
376 );
377 }
378
e7aeea18 379 private async startTransaction(
5edd8ba0 380 connectorId: number,
0afed85f 381 ): Promise<StartTransactionResponse | undefined> {
aef1b33a
JB
382 const measureId = 'StartTransaction with ATG';
383 const beginId = PerformanceStatistics.beginMeasure(measureId);
e1d9a0f4 384 let startResponse: StartTransactionResponse | undefined;
f911a4af
JB
385 if (this.chargingStation.hasIdTags()) {
386 const idTag = IdTagsCache.getInstance().getIdTag(
e1d9a0f4 387 this.chargingStation.getAutomaticTransactionGeneratorConfiguration().idTagDistribution!,
aaf2bf9c 388 this.chargingStation,
5edd8ba0 389 connectorId,
aaf2bf9c 390 );
5cf9050d 391 const startTransactionLogMsg = `${this.logPrefix(
5edd8ba0 392 connectorId,
ba7965c4 393 )} start transaction with an idTag '${idTag}'`;
ccb1d6e9 394 if (this.getRequireAuthorize()) {
e1d9a0f4 395 this.chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag = idTag;
f4bf2abd 396 // Authorize idTag
2e3d65ae 397 const authorizeResponse: AuthorizeResponse =
f7f98c68 398 await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
399 AuthorizeRequest,
400 AuthorizeResponse
08f130a0 401 >(this.chargingStation, RequestCommand.AUTHORIZE, {
ef6fa3fb
JB
402 idTag,
403 });
e1d9a0f4 404 ++this.connectorsStatus.get(connectorId)!.authorizeRequests!;
5fdab605 405 if (authorizeResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
e1d9a0f4 406 ++this.connectorsStatus.get(connectorId)!.acceptedAuthorizeRequests!;
5cf9050d 407 logger.info(startTransactionLogMsg);
5fdab605 408 // Start transaction
f7f98c68 409 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
410 StartTransactionRequest,
411 StartTransactionResponse
08f130a0 412 >(this.chargingStation, RequestCommand.START_TRANSACTION, {
ef6fa3fb
JB
413 connectorId,
414 idTag,
415 });
d9ac47ef 416 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
417 PerformanceStatistics.endMeasure(measureId, beginId);
418 return startResponse;
5fdab605 419 }
e1d9a0f4 420 ++this.connectorsStatus.get(connectorId)!.rejectedAuthorizeRequests!;
aef1b33a 421 PerformanceStatistics.endMeasure(measureId, beginId);
0afed85f 422 return startResponse;
ef6076c1 423 }
5cf9050d 424 logger.info(startTransactionLogMsg);
5fdab605 425 // Start transaction
f7f98c68 426 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
427 StartTransactionRequest,
428 StartTransactionResponse
08f130a0 429 >(this.chargingStation, RequestCommand.START_TRANSACTION, {
ef6fa3fb
JB
430 connectorId,
431 idTag,
432 });
d9ac47ef 433 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
434 PerformanceStatistics.endMeasure(measureId, beginId);
435 return startResponse;
6af9012e 436 }
5cf9050d 437 logger.info(`${this.logPrefix(connectorId)} start transaction without an idTag`);
f7f98c68 438 startResponse = await this.chargingStation.ocppRequestService.requestHandler<
ef6fa3fb
JB
439 StartTransactionRequest,
440 StartTransactionResponse
08f130a0 441 >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId });
431b6bd5 442 this.handleStartTransactionResponse(connectorId, startResponse);
aef1b33a
JB
443 PerformanceStatistics.endMeasure(measureId, beginId);
444 return startResponse;
6af9012e
JB
445 }
446
e7aeea18
JB
447 private async stopTransaction(
448 connectorId: number,
5edd8ba0 449 reason: StopTransactionReason = StopTransactionReason.LOCAL,
e1d9a0f4 450 ): Promise<StopTransactionResponse | undefined> {
aef1b33a
JB
451 const measureId = 'StopTransaction with ATG';
452 const beginId = PerformanceStatistics.beginMeasure(measureId);
e1d9a0f4 453 let stopResponse: StopTransactionResponse | undefined;
6d9876e7 454 if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
5e3cb728 455 stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason);
e1d9a0f4 456 ++this.connectorsStatus.get(connectorId)!.stopTransactionRequests!;
0afed85f 457 if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
e1d9a0f4 458 ++this.connectorsStatus.get(connectorId)!.acceptedStopTransactionRequests!;
6d9876e7 459 } else {
e1d9a0f4 460 ++this.connectorsStatus.get(connectorId)!.rejectedStopTransactionRequests!;
6d9876e7 461 }
0045cef5 462 } else {
1895299d 463 const transactionId = this.chargingStation.getConnectorStatus(connectorId)?.transactionId;
e7aeea18 464 logger.warn(
ba7965c4 465 `${this.logPrefix(connectorId)} stopping a not started transaction${
9bf0ef23 466 !isNullOrUndefined(transactionId) ? ` with id ${transactionId?.toString()}` : ''
5edd8ba0 467 }`,
e7aeea18 468 );
0045cef5 469 }
aef1b33a
JB
470 PerformanceStatistics.endMeasure(measureId, beginId);
471 return stopResponse;
c0560973
JB
472 }
473
ccb1d6e9 474 private getRequireAuthorize(): boolean {
ac7f79af
JB
475 return (
476 this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.requireAuthorize ?? true
477 );
ccb1d6e9
JB
478 }
479
8b7072dc 480 private logPrefix = (connectorId?: number): string => {
9bf0ef23 481 return logPrefix(
6cd85def 482 ` ${this.chargingStation.stationInfo.chargingStationId} | ATG${
e1d9a0f4 483 !isNullOrUndefined(connectorId) ? ` on connector #${connectorId!.toString()}` : ''
5edd8ba0 484 }:`,
6cd85def 485 );
8b7072dc 486 };
d9ac47ef
JB
487
488 private handleStartTransactionResponse(
489 connectorId: number,
5edd8ba0 490 startResponse: StartTransactionResponse,
d9ac47ef 491 ): void {
e1d9a0f4 492 ++this.connectorsStatus.get(connectorId)!.startTransactionRequests!;
d9ac47ef 493 if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
e1d9a0f4 494 ++this.connectorsStatus.get(connectorId)!.acceptedStartTransactionRequests!;
d9ac47ef 495 } else {
44eb6026 496 logger.warn(`${this.logPrefix(connectorId)} start transaction rejected`);
e1d9a0f4 497 ++this.connectorsStatus.get(connectorId)!.rejectedStartTransactionRequests!;
d9ac47ef
JB
498 }
499 }
6af9012e 500}