-// Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
+// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
import { AsyncResource } from 'async_hooks';
+import type ChargingStation from './ChargingStation';
+import { ChargingStationUtils } from './ChargingStationUtils';
import BaseError from '../exception/BaseError';
import PerformanceStatistics from '../performance/PerformanceStatistics';
import {
import Constants from '../utils/Constants';
import logger from '../utils/Logger';
import Utils from '../utils/Utils';
-import type ChargingStation from './ChargingStation';
-import { ChargingStationUtils } from './ChargingStationUtils';
const moduleName = 'AutomaticTransactionGenerator';
public static getInstance(
automaticTransactionGeneratorConfiguration: AutomaticTransactionGeneratorConfiguration,
chargingStation: ChargingStation
- ): AutomaticTransactionGenerator {
+ ): AutomaticTransactionGenerator | undefined {
if (AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo.hashId) === false) {
AutomaticTransactionGenerator.instances.set(
chargingStation.stationInfo.hashId,
}
public start(): void {
+ if (this.checkChargingStation() === false) {
+ return;
+ }
if (this.started === true) {
logger.warn(`${this.logPrefix()} is already started`);
return;
}
public startConnector(connectorId: number): void {
+ if (this.checkChargingStation(connectorId) === false) {
+ return;
+ }
if (this.connectorsStatus.has(connectorId) === false) {
logger.error(`${this.logPrefix(connectorId)} starting on non existing connector`);
throw new BaseError(`Connector ${connectorId} does not exist`);
this.internalStartConnector.bind(this) as (
this: AutomaticTransactionGenerator,
...args: any[]
- ) => void,
+ ) => Promise<void>,
this,
connectorId
- );
+ ).catch(() => {
+ /* This is intentional */
+ });
} else if (this.connectorsStatus.get(connectorId)?.start === true) {
logger.warn(`${this.logPrefix(connectorId)} is already started on connector`);
}
private async internalStartConnector(connectorId: number): Promise<void> {
this.setStartConnectorStatus(connectorId);
logger.info(
- this.logPrefix(connectorId) +
- ' started on connector and will run for ' +
- Utils.formatDurationMilliSeconds(
- this.connectorsStatus.get(connectorId).stopDate.getTime() -
- this.connectorsStatus.get(connectorId).startDate.getTime()
- )
+ `${this.logPrefix(
+ connectorId
+ )} started on connector and will run for ${Utils.formatDurationMilliSeconds(
+ this.connectorsStatus.get(connectorId).stopDate.getTime() -
+ this.connectorsStatus.get(connectorId).startDate.getTime()
+ )}`
);
- while (this.connectorsStatus.get(connectorId).start === true) {
+ while (this.connectorsStatus.get(connectorId)?.start === true) {
if (new Date() > this.connectorsStatus.get(connectorId).stopDate) {
this.stopConnector(connectorId);
break;
}
if (this.chargingStation.isInAcceptedState() === false) {
logger.error(
- this.logPrefix(connectorId) +
- ' entered in transaction loop while the charging station is not in accepted state'
+ `${this.logPrefix(
+ connectorId
+ )} entered in transaction loop while the charging station is not in accepted state`
);
this.stopConnector(connectorId);
break;
}
if (this.chargingStation.isChargingStationAvailable() === false) {
logger.info(
- this.logPrefix(connectorId) +
- ' entered in transaction loop while the charging station is unavailable'
+ `${this.logPrefix(
+ connectorId
+ )} entered in transaction loop while the charging station is unavailable`
);
this.stopConnector(connectorId);
break;
this.configuration.minDelayBetweenTwoTransactions
) * 1000;
logger.info(
- this.logPrefix(connectorId) + ' waiting for ' + Utils.formatDurationMilliSeconds(wait)
+ `${this.logPrefix(connectorId)} waiting for ${Utils.formatDurationMilliSeconds(wait)}`
);
await Utils.sleep(wait);
const start = Utils.secureRandom();
Utils.getRandomInteger(this.configuration.maxDuration, this.configuration.minDuration) *
1000;
logger.info(
- this.logPrefix(connectorId) +
- ' transaction ' +
- this.chargingStation.getConnectorStatus(connectorId).transactionId.toString() +
- ' started and will stop in ' +
- Utils.formatDurationMilliSeconds(waitTrxEnd)
+ `${this.logPrefix(connectorId)} transaction ${this.chargingStation
+ .getConnectorStatus(connectorId)
+ ?.transactionId?.toString()} started and will stop in ${Utils.formatDurationMilliSeconds(
+ waitTrxEnd
+ )}`
);
await Utils.sleep(waitTrxEnd);
// Stop transaction
logger.info(
- this.logPrefix(connectorId) +
- ' stop transaction ' +
- this.chargingStation.getConnectorStatus(connectorId).transactionId.toString()
+ `${this.logPrefix(connectorId)} stop transaction ${this.chargingStation
+ .getConnectorStatus(connectorId)
+ ?.transactionId?.toString()}`
);
await this.stopTransaction(connectorId);
}
this.connectorsStatus.get(connectorId).skippedConsecutiveTransactions++;
this.connectorsStatus.get(connectorId).skippedTransactions++;
logger.info(
- this.logPrefix(connectorId) +
- ' skipped consecutively ' +
- this.connectorsStatus.get(connectorId).skippedConsecutiveTransactions.toString() +
- '/' +
- this.connectorsStatus.get(connectorId).skippedTransactions.toString() +
- ' transaction(s)'
+ `${this.logPrefix(connectorId)} skipped consecutively ${this.connectorsStatus
+ .get(connectorId)
+ ?.skippedConsecutiveTransactions?.toString()}/${this.connectorsStatus
+ .get(connectorId)
+ ?.skippedTransactions?.toString()} transaction(s)`
);
}
this.connectorsStatus.get(connectorId).lastRunDate = new Date();
}
this.connectorsStatus.get(connectorId).stoppedDate = new Date();
logger.info(
- this.logPrefix(connectorId) +
- ' stopped on connector and lasted for ' +
- Utils.formatDurationMilliSeconds(
- this.connectorsStatus.get(connectorId).stoppedDate.getTime() -
- this.connectorsStatus.get(connectorId).startDate.getTime()
- )
+ `${this.logPrefix(
+ connectorId
+ )} stopped on connector and lasted for ${Utils.formatDurationMilliSeconds(
+ this.connectorsStatus.get(connectorId).stoppedDate.getTime() -
+ this.connectorsStatus.get(connectorId).startDate.getTime()
+ )}`
);
logger.debug(
`${this.logPrefix(connectorId)} connector status: %j`,
private setStartConnectorStatus(connectorId: number): void {
this.connectorsStatus.get(connectorId).skippedConsecutiveTransactions = 0;
const previousRunDuration =
- this?.connectorsStatus.get(connectorId)?.startDate &&
- this?.connectorsStatus.get(connectorId)?.lastRunDate
+ this.connectorsStatus.get(connectorId)?.startDate &&
+ this.connectorsStatus.get(connectorId)?.lastRunDate
? this.connectorsStatus.get(connectorId).lastRunDate.getTime() -
this.connectorsStatus.get(connectorId).startDate.getTime()
: 0;
this.connectorsStatus.get(connectorId).rejectedStopTransactionRequests++;
}
} else {
- const transactionId = this.chargingStation.getConnectorStatus(connectorId).transactionId;
+ const transactionId = this.chargingStation.getConnectorStatus(connectorId)?.transactionId;
logger.warn(
`${this.logPrefix(connectorId)} stopping a not started transaction${
- transactionId ? ' ' + transactionId.toString() : ''
+ !Utils.isNullOrUndefined(transactionId) ? ` ${transactionId?.toString()}` : ''
}`
);
}
if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
this.connectorsStatus.get(connectorId).acceptedStartTransactionRequests++;
} else {
- logger.warn(this.logPrefix(connectorId) + ' start transaction rejected');
+ logger.warn(`${this.logPrefix(connectorId)} start transaction rejected`);
this.connectorsStatus.get(connectorId).rejectedStartTransactionRequests++;
}
}
+
+ private checkChargingStation(connectorId?: number): boolean {
+ if (this.chargingStation.started === false && this.chargingStation.starting === false) {
+ logger.warn(`${this.logPrefix(connectorId)} charging station is stopped, cannot proceed`);
+ return false;
+ }
+ return true;
+ }
}