+ private async stopTransaction(
+ connectorId: number,
+ reason: StopTransactionReason = StopTransactionReason.LOCAL
+ ): Promise<StopTransactionResponse> {
+ const measureId = 'StopTransaction with ATG';
+ const beginId = PerformanceStatistics.beginMeasure(measureId);
+ let stopResponse: StopTransactionResponse;
+ if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
+ stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason);
+ this.connectorsStatus.get(connectorId).stopTransactionRequests++;
+ if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
+ this.connectorsStatus.get(connectorId).acceptedStopTransactionRequests++;
+ } else {
+ this.connectorsStatus.get(connectorId).rejectedStopTransactionRequests++;
+ }
+ } else {
+ const transactionId = this.chargingStation.getConnectorStatus(connectorId)?.transactionId;
+ logger.warn(
+ `${this.logPrefix(connectorId)} stopping a not started transaction${
+ !Utils.isNullOrUndefined(transactionId) ? ` ${transactionId?.toString()}` : ''
+ }`
+ );
+ }
+ PerformanceStatistics.endMeasure(measureId, beginId);
+ return stopResponse;
+ }
+
+ private getRequireAuthorize(): boolean {
+ return this.configuration?.requireAuthorize ?? true;
+ }
+
+ private getRandomIdTag(authorizationFile: string): string {
+ const tags = this.chargingStation.authorizedTagsCache.getAuthorizedTags(authorizationFile);
+ this.idTagIndex = Math.floor(Utils.secureRandom() * tags.length);
+ return tags[this.idTagIndex];
+ }
+
+ private getRoundRobinIdTag(authorizationFile: string): string {
+ const tags = this.chargingStation.authorizedTagsCache.getAuthorizedTags(authorizationFile);
+ const idTag = tags[this.idTagIndex];
+ this.idTagIndex = this.idTagIndex === tags.length - 1 ? 0 : this.idTagIndex + 1;
+ return idTag;
+ }
+
+ private getConnectorAffinityIdTag(authorizationFile: string, connectorId: number): string {
+ const tags = this.chargingStation.authorizedTagsCache.getAuthorizedTags(authorizationFile);
+ this.idTagIndex = (this.chargingStation.index - 1 + (connectorId - 1)) % tags.length;
+ return tags[this.idTagIndex];
+ }
+
+ private getIdTag(connectorId: number): string {
+ const authorizationFile = ChargingStationUtils.getAuthorizationFile(
+ this.chargingStation.stationInfo
+ );
+ switch (this.configuration?.idTagDistribution) {
+ case IdTagDistribution.RANDOM:
+ return this.getRandomIdTag(authorizationFile);
+ case IdTagDistribution.ROUND_ROBIN:
+ return this.getRoundRobinIdTag(authorizationFile);
+ case IdTagDistribution.CONNECTOR_AFFINITY:
+ return this.getConnectorAffinityIdTag(authorizationFile, connectorId);
+ default:
+ return this.getRoundRobinIdTag(authorizationFile);
+ }
+ }
+
+ private logPrefix(connectorId?: number): string {
+ return Utils.logPrefix(
+ ` ${this.chargingStation.stationInfo.chargingStationId} | ATG${
+ connectorId !== undefined ? ` on connector #${connectorId.toString()}` : ''
+ }:`
+ );
+ }
+
+ private handleStartTransactionResponse(
+ connectorId: number,
+ startResponse: StartTransactionResponse
+ ): void {
+ this.connectorsStatus.get(connectorId).startTransactionRequests++;
+ if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
+ this.connectorsStatus.get(connectorId).acceptedStartTransactionRequests++;
+ } else {
+ logger.warn(`${this.logPrefix(connectorId)} start transaction rejected`);
+ this.connectorsStatus.get(connectorId).rejectedStartTransactionRequests++;
+ }