refactor: cleanup reservation handling code
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 5 Jun 2023 16:29:25 +0000 (18:29 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Mon, 5 Jun 2023 16:29:25 +0000 (18:29 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/OCPPConstants.ts

index a3f6769607c5b01bb9774bf614a71f31a80a5afe..fc6a409adfc006c7200bc600441f83c8ebeb1490 100644 (file)
@@ -138,7 +138,7 @@ export class ChargingStation {
   private readonly sharedLRUCache: SharedLRUCache;
   private webSocketPingSetInterval!: NodeJS.Timeout;
   private readonly chargingStationWorkerBroadcastChannel: ChargingStationWorkerBroadcastChannel;
-  private reservationExpiryDateSetInterval?: NodeJS.Timeout;
+  private reservationExpirationSetInterval?: NodeJS.Timeout;
 
   constructor(index: number, templateFile: string) {
     this.started = false;
@@ -654,7 +654,7 @@ export class ChargingStation {
           this.performanceStatistics?.start();
         }
         if (this.hasFeatureProfile(SupportedFeatureProfiles.Reservation)) {
-          this.startReservationExpiryDateSetInterval();
+          this.startReservationExpirationSetInterval();
         }
         this.openWSConnection();
         // Monitor charging station template file
@@ -993,18 +993,18 @@ export class ChargingStation {
     }
   }
 
-  public getReservationBy(key: string, value: number | string): Reservation {
+  public getReservationBy(filterKey: ReservationFilterKey, value: number | string): Reservation {
     if (this.hasEvses) {
       for (const evse of this.evses.values()) {
         for (const connector of evse.connectors.values()) {
-          if (connector?.reservation?.[key] === value) {
+          if (connector?.reservation?.[filterKey] === value) {
             return connector.reservation;
           }
         }
       }
     } else {
       for (const connector of this.connectors.values()) {
-        if (connector?.reservation?.[key] === value) {
+        if (connector?.reservation?.[filterKey] === value) {
           return connector.reservation;
         }
       }
@@ -1019,15 +1019,15 @@ export class ChargingStation {
     return Utils.isUndefined(foundReservation) ? [false, null] : [true, foundReservation];
   }
 
-  public startReservationExpiryDateSetInterval(customInterval?: number): void {
+  public startReservationExpirationSetInterval(customInterval?: number): void {
     const interval =
       customInterval ?? Constants.DEFAULT_RESERVATION_EXPIRATION_OBSERVATION_INTERVAL;
     logger.info(
       `${this.logPrefix()} Reservation expiration date interval is set to ${interval}
-        and starts on CS now`
+        and starts on charging station now`
     );
     // eslint-disable-next-line @typescript-eslint/no-misused-promises
-    this.reservationExpiryDateSetInterval = setInterval(async (): Promise<void> => {
+    this.reservationExpirationSetInterval = setInterval(async (): Promise<void> => {
       if (this.hasEvses) {
         for (const evse of this.evses.values()) {
           for (const connector of evse.connectors.values()) {
@@ -1047,8 +1047,8 @@ export class ChargingStation {
   }
 
   public restartReservationExpiryDateSetInterval(): void {
-    this.stopReservationExpiryDateSetInterval();
-    this.startReservationExpiryDateSetInterval();
+    this.stopReservationExpirationSetInterval();
+    this.startReservationExpirationSetInterval();
   }
 
   public validateIncomingRequestWithReservation(connectorId: number, idTag: string): boolean {
@@ -1089,8 +1089,8 @@ export class ChargingStation {
 
   private countReservableConnectors(connectors: Map<number, ConnectorStatus>) {
     let reservableConnectors = 0;
-    for (const [id, connector] of connectors) {
-      if (id === 0) {
+    for (const [connectorId, connector] of connectors) {
+      if (connectorId === 0) {
         continue;
       }
       if (connector.status === ConnectorStatusEnum.Available) {
@@ -1141,9 +1141,9 @@ export class ChargingStation {
     return this.stationInfo.supervisionUrlOcppConfiguration ?? false;
   }
 
-  private stopReservationExpiryDateSetInterval(): void {
-    if (this.reservationExpiryDateSetInterval) {
-      clearInterval(this.reservationExpiryDateSetInterval);
+  private stopReservationExpirationSetInterval(): void {
+    if (this.reservationExpirationSetInterval) {
+      clearInterval(this.reservationExpirationSetInterval);
     }
   }
 
index 27045c89617c023da1b85d17ee6b8c4b9713e95f..8c6ec224f1edf91b7945ed6939bdbd07857850f1 100644 (file)
@@ -24,7 +24,6 @@ import {
   type ClearChargingProfileRequest,
   type ClearChargingProfileResponse,
   type ConnectorStatus,
-  ConnectorStatusEnum,
   ErrorType,
   type GenericResponse,
   GenericStatus,
@@ -90,7 +89,6 @@ import {
   type UnlockConnectorResponse,
 } from '../../../types';
 import { Constants, Utils, logger } from '../../../utils';
-import { OCPPConstants } from '../OCPPConstants';
 import { OCPPIncomingRequestService } from '../OCPPIncomingRequestService';
 
 const moduleName = 'OCPP16IncomingRequestService';
@@ -880,7 +878,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         connectorStatus.transactionRemoteStarted = true;
         const startTransactionPayload: Partial<StartTransactionRequest> = {
           connectorId: transactionConnectorId,
-          idTag: idTag,
+          idTag,
         };
         if (reserved || reservedOnConnectorZero) {
           const reservation = chargingStation.getReservationBy(
@@ -901,7 +899,6 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
             >(chargingStation, OCPP16RequestCommand.START_TRANSACTION, startTransactionPayload)
           ).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
         ) {
-          logger.debug(remoteStartTransactionLogMsg);
           return OCPP16Constants.OCPP_RESPONSE_ACCEPTED;
         }
         return this.notifyRemoteStartTransactionRejected(
@@ -936,7 +933,6 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
           })
         ).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
       ) {
-        logger.debug(remoteStartTransactionLogMsg);
         return OCPP16Constants.OCPP_RESPONSE_ACCEPTED;
       }
       return this.notifyRemoteStartTransactionRejected(
@@ -1535,56 +1531,60 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         OCPP16IncomingRequestCommand.RESERVE_NOW
       )
     ) {
-      return OCPPConstants.OCPP_RESERVATION_RESPONSE_REJECTED;
+      return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
     }
     const { reservationId, idTag, connectorId } = commandPayload;
     let response: OCPP16ReserveNowResponse;
     try {
       if (!chargingStation.isConnectorAvailable(connectorId) && connectorId > 0) {
-        return OCPPConstants.OCPP_RESERVATION_RESPONSE_REJECTED;
+        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
       }
       if (connectorId === 0 && !chargingStation.getReservationOnConnectorId0Enabled()) {
-        return OCPPConstants.OCPP_RESERVATION_RESPONSE_REJECTED;
+        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
       }
       if (!(await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, connectorId, idTag))) {
-        return OCPPConstants.OCPP_RESERVATION_RESPONSE_REJECTED;
+        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
       }
       switch (chargingStation.getConnectorStatus(connectorId).status) {
-        case ConnectorStatusEnum.Faulted:
-          response = OCPPConstants.OCPP_RESERVATION_RESPONSE_FAULTED;
+        case OCPP16ChargePointStatus.Faulted:
+          response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED;
           break;
-        case ConnectorStatusEnum.Occupied:
-          response = OCPPConstants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+        case OCPP16ChargePointStatus.Preparing:
+        case OCPP16ChargePointStatus.Charging:
+        case OCPP16ChargePointStatus.SuspendedEV:
+        case OCPP16ChargePointStatus.SuspendedEVSE:
+        case OCPP16ChargePointStatus.Finishing:
+          response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
           break;
-        case ConnectorStatusEnum.Unavailable:
-          response = OCPPConstants.OCPP_RESERVATION_RESPONSE_UNAVAILABLE;
+        case OCPP16ChargePointStatus.Unavailable:
+          response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_UNAVAILABLE;
           break;
-        case ConnectorStatusEnum.Reserved:
+        case OCPP16ChargePointStatus.Reserved:
           if (!chargingStation.isConnectorReservable(reservationId, idTag, connectorId)) {
-            response = OCPPConstants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+            response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
             break;
           }
         // eslint-disable-next-line no-fallthrough
         default:
           if (!chargingStation.isConnectorReservable(reservationId, idTag)) {
-            response = OCPPConstants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+            response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
             break;
           }
           await chargingStation.addReservation({
             id: commandPayload.reservationId,
             ...commandPayload,
           });
-          response = OCPPConstants.OCPP_RESERVATION_RESPONSE_ACCEPTED;
+          response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_ACCEPTED;
           break;
       }
       return response;
     } catch (error) {
-      chargingStation.getConnectorStatus(connectorId).status = ConnectorStatusEnum.Available;
+      chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.Available;
       return this.handleIncomingRequestError(
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
         error as Error,
-        { errorResponse: OCPPConstants.OCPP_RESERVATION_RESPONSE_FAULTED }
+        { errorResponse: OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED }
       );
     }
   }
@@ -1600,7 +1600,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION
       )
     ) {
-      return OCPPConstants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
+      return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
     }
     try {
       const { reservationId } = commandPayload;
@@ -1610,16 +1610,16 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
           `${chargingStation.logPrefix()} Reservation with ID ${reservationId}
             does not exist on charging station`
         );
-        return OCPPConstants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
+        return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
       }
       await chargingStation.removeReservation(reservation);
-      return OCPPConstants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED;
+      return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED;
     } catch (error) {
       return this.handleIncomingRequestError(
         chargingStation,
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
         error as Error,
-        { errorResponse: OCPPConstants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED }
+        { errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED }
       );
     }
   }
index 9d3fc74b14b6775b94baf5091722ebba2536e999..f8a5fa35046804a83544e124460bffd54bfb2d2a 100644 (file)
@@ -124,7 +124,7 @@ export class OCPPConstants {
 
   static readonly OCPP_RESERVATION_RESPONSE_REJECTED = Object.freeze({
     status: ReservationStatus.REJECTED,
-  }); // Reservation has not been made, because CS is not configured to accept reservations
+  }); // Reservation has not been made, because charging station is not configured to accept reservations
 
   static readonly OCPP_RESERVATION_RESPONSE_UNAVAILABLE = Object.freeze({
     status: ReservationStatus.UNAVAILABLE,