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