From d984c13f2c929dd5e2750e0b5da23eba62c50ed8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 30 Jul 2023 21:16:20 +0200 Subject: [PATCH] fix: fix reservation removal at transaction start MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../AutomaticTransactionGenerator.ts | 9 +++- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 46 ++++++++----------- .../ocpp/1.6/OCPP16ResponseService.ts | 27 +++++++++-- .../ocpp/1.6/OCPP16ServiceUtils.ts | 16 +++---- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/charging-station/AutomaticTransactionGenerator.ts b/src/charging-station/AutomaticTransactionGenerator.ts index bdeffbd2..20c8e81a 100644 --- a/src/charging-station/AutomaticTransactionGenerator.ts +++ b/src/charging-station/AutomaticTransactionGenerator.ts @@ -397,7 +397,6 @@ export class AutomaticTransactionGenerator extends AsyncResource { connectorId, )} start transaction with an idTag '${idTag}'`; if (this.getRequireAuthorize()) { - this.chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag = idTag; // Authorize idTag const authorizeResponse: AuthorizeResponse = await this.chargingStation.ocppRequestService.requestHandler< @@ -408,6 +407,14 @@ export class AutomaticTransactionGenerator extends AsyncResource { }); ++this.connectorsStatus.get(connectorId)!.authorizeRequests!; if (authorizeResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) { + if ( + isNullOrUndefined(this.chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag) + ) { + logger.warn( + `${this.chargingStation.logPrefix()} IdTag ${idTag} is not set as authorized remotely, applying deferred initialization`, + ); + this.chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag = idTag; + } ++this.connectorsStatus.get(connectorId)!.acceptedAuthorizeRequests!; logger.info(startTransactionLogMsg); // Start transaction diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index cc16622a..f4799d8f 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -84,7 +84,6 @@ import { type ResetRequest, type SetChargingProfileRequest, type SetChargingProfileResponse, - type StartTransactionRequest, type UnlockConnectorRequest, type UnlockConnectorResponse, } from '../../../types'; @@ -826,15 +825,11 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { commandPayload: RemoteStartTransactionRequest, ): Promise { const { connectorId: transactionConnectorId, idTag, chargingProfile } = commandPayload; - const reserved = - chargingStation.getConnectorStatus(transactionConnectorId)!.status === - OCPP16ChargePointStatus.Reserved; - const reservedOnConnectorZero = - chargingStation.getConnectorStatus(0)!.status === OCPP16ChargePointStatus.Reserved; if ( - (reserved && + (chargingStation.getConnectorStatus(transactionConnectorId)!.status === + OCPP16ChargePointStatus.Reserved && chargingStation.getReservationBy('connectorId', transactionConnectorId)?.idTag !== idTag) || - (reservedOnConnectorZero && + (chargingStation.getConnectorStatus(0)!.status === OCPP16ChargePointStatus.Reserved && chargingStation.getReservationBy('connectorId', 0)?.idTag !== idTag) ) { return OCPP16Constants.OCPP_RESPONSE_REJECTED; @@ -866,9 +861,20 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { OCPP16ChargePointStatus.Preparing, ); const connectorStatus = chargingStation.getConnectorStatus(transactionConnectorId)!; - // Check if authorized if ( chargingStation.getAuthorizeRemoteTxRequests() && + !chargingStation.getLocalAuthListEnabled() && + !chargingStation.getMustAuthorizeAtRemoteStart() + ) { + logger.warn( + `${chargingStation.logPrefix()} The charging station configuration expects authorize at remote start transaction + but local authorization or must authorize at remote start isn't enabled`, + ); + } + // Authorization check required + if ( + chargingStation.getAuthorizeRemoteTxRequests() === true && + chargingStation.getMustAuthorizeAtRemoteStart() === true && (await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, transactionConnectorId, idTag)) ) { // Authorization successful, start transaction @@ -880,27 +886,15 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { ) === true ) { connectorStatus.transactionRemoteStarted = true; - const startTransactionPayload: Partial = { - connectorId: transactionConnectorId, - idTag, - }; - if (reserved || reservedOnConnectorZero) { - const reservation = chargingStation.getReservationBy( - 'connectorId', - reservedOnConnectorZero ? 0 : transactionConnectorId, - )!; - startTransactionPayload.reservationId = reservation.reservationId; - await chargingStation.removeReservation( - reservation, - ReservationTerminationReason.TRANSACTION_STARTED, - ); - } if ( ( await chargingStation.ocppRequestService.requestHandler< OCPP16StartTransactionRequest, OCPP16StartTransactionResponse - >(chargingStation, OCPP16RequestCommand.START_TRANSACTION, startTransactionPayload) + >(chargingStation, OCPP16RequestCommand.START_TRANSACTION, { + connectorId: transactionConnectorId, + idTag, + }) ).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED ) { logger.debug(remoteStartTransactionLogMsg); @@ -1547,7 +1541,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { const { reservationId, idTag, connectorId } = commandPayload; let response: OCPP16ReserveNowResponse; try { - if (!chargingStation.isConnectorAvailable(connectorId) && connectorId > 0) { + if (connectorId > 0 && !chargingStation.isConnectorAvailable(connectorId)) { return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED; } if (connectorId === 0 && !chargingStation.getReserveConnectorZeroSupported()) { diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index 3816c54f..7cafe937 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -48,6 +48,7 @@ import { type OCPP16UpdateFirmwareResponse, OCPPVersion, RegistrationStatusEnumType, + ReservationTerminationReason, type ResponseHandler, type SetChargingProfileResponse, type UnlockConnectorResponse, @@ -470,8 +471,11 @@ export class OCPP16ResponseService extends OCPPResponseService { } const authorizeConnectorIdDefined = !isNullOrUndefined(authorizeConnectorId); if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) { - authorizeConnectorIdDefined && - (chargingStation.getConnectorStatus(authorizeConnectorId!)!.idTagAuthorized = true); + if (authorizeConnectorIdDefined) { + chargingStation.getConnectorStatus(authorizeConnectorId!)!.idTagAuthorized = true; + chargingStation.getConnectorStatus(authorizeConnectorId!)!.authorizeIdTag = + requestPayload.idTag; + } logger.debug( `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${ authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : '' @@ -510,7 +514,7 @@ export class OCPP16ResponseService extends OCPPResponseService { true && chargingStation.getAuthorizeRemoteTxRequests() === true && chargingStation.getLocalAuthListEnabled() === true && - chargingStation.hasIdTags() && + chargingStation.hasIdTags() === true && chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false ) { logger.error( @@ -635,6 +639,23 @@ export class OCPP16ResponseService extends OCPPResponseService { transactionConnectorId, requestPayload.meterStart, ); + const reservedOnConnectorZero = + chargingStation.getConnectorStatus(0)!.status === OCPP16ChargePointStatus.Reserved; + if ( + chargingStation.getConnectorStatus(transactionConnectorId)!.status === + OCPP16ChargePointStatus.Reserved || + reservedOnConnectorZero + ) { + const reservation = chargingStation.getReservationBy( + 'connectorId', + reservedOnConnectorZero ? 0 : transactionConnectorId, + )!; + payload.reservationId = reservation.reservationId; + await chargingStation.removeReservation( + reservation, + ReservationTerminationReason.TRANSACTION_STARTED, + ); + } chargingStation.getBeginEndMeterValues() && (await chargingStation.ocppRequestService.requestHandler< OCPP16MeterValuesRequest, diff --git a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts index 7f065d30..bf019cee 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts @@ -897,14 +897,14 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { connectorStatus.localAuthorizeIdTag = idTag; connectorStatus.idTagLocalAuthorized = true; authorized = true; - } else if (chargingStation.getMustAuthorizeAtRemoteStart() === true) { - connectorStatus.authorizeIdTag = idTag; - authorized = await OCPP16ServiceUtils.isIdTagRemoteAuthorized(chargingStation, idTag); } else { - logger.warn( - `${chargingStation.logPrefix()} The charging station configuration expects authorize at - remote start transaction but local authorization or authorize isn't enabled`, - ); + authorized = await OCPP16ServiceUtils.isIdTagRemoteAuthorized(chargingStation, idTag); + if (authorized && isNullOrUndefined(connectorStatus.authorizeIdTag)) { + logger.warn( + `${chargingStation.logPrefix()} IdTag ${idTag} is not set as authorized remotely, applying deferred initialization`, + ); + connectorStatus.authorizeIdTag = idTag; + } } return authorized; } @@ -1006,7 +1006,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { OCPP16AuthorizeRequest, OCPP16AuthorizeResponse >(chargingStation, OCPP16RequestCommand.AUTHORIZE, { - idTag: idTag, + idTag, }); return authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED; } -- 2.34.1