X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FAutomaticTransactionGenerator.ts;h=0eb47381876d833aef74796f6471a8af4bcb8c35;hb=a4d9680730c77debfb3b9455e4bd5b63e61ce664;hp=adf38e67b4591c0dae62a6b76827556bbba5382f;hpb=7e3bde4fa97ee4937b806bb4dfeb16ef0f99d1a4;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/AutomaticTransactionGenerator.ts b/src/charging-station/AutomaticTransactionGenerator.ts index adf38e67..0eb47381 100644 --- a/src/charging-station/AutomaticTransactionGenerator.ts +++ b/src/charging-station/AutomaticTransactionGenerator.ts @@ -1,11 +1,9 @@ // Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved. +import { randomInt } from 'node:crypto' + import { hoursToMilliseconds, secondsToMilliseconds } from 'date-fns' -import type { ChargingStation } from './ChargingStation.js' -import { checkChargingStation } from './Helpers.js' -import { IdTagsCache } from './IdTagsCache.js' -import { isIdTagAuthorized } from './ocpp/index.js' import { BaseError } from '../exception/index.js' import { PerformanceStatistics } from '../performance/index.js' import { @@ -18,17 +16,20 @@ import { type StopTransactionResponse } from '../types/index.js' import { - Constants, clone, + Constants, convertToDate, formatDurationMilliSeconds, - getRandomInteger, isValidDate, - logPrefix, logger, + logPrefix, secureRandom, sleep } from '../utils/index.js' +import type { ChargingStation } from './ChargingStation.js' +import { checkChargingStation } from './Helpers.js' +import { IdTagsCache } from './IdTagsCache.js' +import { isIdTagAuthorized } from './ocpp/index.js' export class AutomaticTransactionGenerator { private static readonly instances: Map = new Map< @@ -66,6 +67,11 @@ export class AutomaticTransactionGenerator { return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo!.hashId) } + public static deleteInstance (chargingStation: ChargingStation): boolean { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return AutomaticTransactionGenerator.instances.delete(chargingStation.stationInfo!.hashId) + } + public start (stopAbsoluteDuration?: boolean): void { if (!checkChargingStation(this.chargingStation, this.logPrefix())) { return @@ -194,11 +200,11 @@ export class AutomaticTransactionGenerator { break } const wait = secondsToMilliseconds( - getRandomInteger( + randomInt( this.chargingStation.getAutomaticTransactionGeneratorConfiguration() - ?.maxDelayBetweenTwoTransactions, + ?.minDelayBetweenTwoTransactions, this.chargingStation.getAutomaticTransactionGeneratorConfiguration() - ?.minDelayBetweenTwoTransactions + ?.maxDelayBetweenTwoTransactions ) ) logger.info(`${this.logPrefix(connectorId)} waiting for ${formatDurationMilliSeconds(wait)}`) @@ -216,9 +222,9 @@ export class AutomaticTransactionGenerator { if (startResponse?.idTagInfo.status === AuthorizationStatus.ACCEPTED) { // Wait until end of transaction const waitTrxEnd = secondsToMilliseconds( - getRandomInteger( - this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.maxDuration, - this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.minDuration + randomInt( + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.minDuration, + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.maxDuration ) ) logger.info( @@ -324,6 +330,15 @@ export class AutomaticTransactionGenerator { ) return false } + const connectorStatus = this.chargingStation.getConnectorStatus(connectorId) + if (connectorStatus?.transactionStarted === true) { + logger.info( + `${this.logPrefix(connectorId)} entered in transaction loop while a transaction ${ + connectorStatus.transactionId + } is already started on connector ${connectorId}` + ) + return false + } return true } @@ -363,9 +378,9 @@ export class AutomaticTransactionGenerator { while (connectorStatus?.transactionStarted === true) { if (!logged) { logger.info( - `${this.logPrefix( - connectorId - )} transaction loop waiting for running transaction ${connectorStatus.transactionId} on connector ${connectorId} to be stopped` + `${this.logPrefix(connectorId)} transaction loop waiting for started transaction ${ + connectorStatus.transactionId + } on connector ${connectorId} to be stopped` ) logged = true } @@ -393,15 +408,21 @@ export class AutomaticTransactionGenerator { private getConnectorStatus (connectorId: number): Status { const statusIndex = connectorId - 1 + if (statusIndex < 0) { + logger.error(`${this.logPrefix(connectorId)} invalid connector id`) + throw new BaseError(`Invalid connector id ${connectorId}`) + } let connectorStatus: Status | undefined if (this.chargingStation.getAutomaticTransactionGeneratorStatuses()?.[statusIndex] != null) { connectorStatus = clone( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.chargingStation.getAutomaticTransactionGeneratorStatuses()![statusIndex] ) - } else if (this.chargingStation.getAutomaticTransactionGeneratorStatuses() != null) { + } else { logger.warn( - `${this.logPrefix(connectorId)} no status found for connector #${connectorId} in charging station configuration file. New status will be created` + `${this.logPrefix( + connectorId + )} no status found for connector #${connectorId} in charging station configuration file. New status will be created` ) } if (connectorStatus != null) { @@ -460,7 +481,7 @@ export class AutomaticTransactionGenerator { logger.info(startTransactionLogMsg) // Start transaction startResponse = await this.chargingStation.ocppRequestService.requestHandler< - StartTransactionRequest, + Partial, StartTransactionResponse >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId, @@ -478,7 +499,7 @@ export class AutomaticTransactionGenerator { logger.info(startTransactionLogMsg) // Start transaction startResponse = await this.chargingStation.ocppRequestService.requestHandler< - StartTransactionRequest, + Partial, StartTransactionResponse >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId, @@ -490,9 +511,11 @@ export class AutomaticTransactionGenerator { } logger.info(`${this.logPrefix(connectorId)} start transaction without an idTag`) startResponse = await this.chargingStation.ocppRequestService.requestHandler< - StartTransactionRequest, + Partial, StartTransactionResponse - >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId }) + >(this.chargingStation, RequestCommand.START_TRANSACTION, { + connectorId + }) this.handleStartTransactionResponse(connectorId, startResponse) PerformanceStatistics.endMeasure(measureId, beginId) return startResponse