refactor: improve tx changing profile checks
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16ResponseService.ts
index e5caf4bf3cfb9d23c41e1403125a23d784943fe2..a1fa0e43aa535ecbae64596431dbe058ef93966a 100644 (file)
@@ -10,11 +10,11 @@ import {
   type ChargingStation,
   addConfigurationKey,
   getConfigurationKey,
+  hasReservationExpired,
   resetConnectorStatus,
 } from '../../../charging-station';
 import { OCPPError } from '../../../exception';
 import {
-  type ChangeAvailabilityResponse,
   type ChangeConfigurationResponse,
   type ClearChargingProfileResponse,
   ErrorType,
@@ -27,6 +27,7 @@ import {
   type OCPP16AuthorizeRequest,
   type OCPP16AuthorizeResponse,
   type OCPP16BootNotificationResponse,
+  type OCPP16ChangeAvailabilityResponse,
   OCPP16ChargePointStatus,
   type OCPP16DataTransferResponse,
   type OCPP16DiagnosticsStatusNotificationResponse,
@@ -209,7 +210,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
       ],
       [
         OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
-        OCPP16ServiceUtils.parseJsonSchemaFile<ChangeAvailabilityResponse>(
+        OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16ChangeAvailabilityResponse>(
           'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
           moduleName,
           'constructor',
@@ -472,9 +473,9 @@ export class OCPP16ResponseService extends OCPPResponseService {
     const authorizeConnectorIdDefined = !isNullOrUndefined(authorizeConnectorId);
     if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
       if (authorizeConnectorIdDefined) {
+        // chargingStation.getConnectorStatus(authorizeConnectorId!)!.authorizeIdTag =
+        //   requestPayload.idTag;
         chargingStation.getConnectorStatus(authorizeConnectorId!)!.idTagAuthorized = true;
-        chargingStation.getConnectorStatus(authorizeConnectorId!)!.authorizeIdTag =
-          requestPayload.idTag;
       }
       logger.debug(
         `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
@@ -529,7 +530,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
       chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
         true &&
       chargingStation.getAuthorizeRemoteTxRequests() === true &&
-      chargingStation.getMustAuthorizeAtRemoteStart() === true &&
+      chargingStation.getRemoteAuthorization() === true &&
       chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
       chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
     ) {
@@ -613,7 +614,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
       );
       return;
     }
-    if (!Number.isInteger(payload.transactionId)) {
+    if (!Number.isSafeInteger(payload.transactionId)) {
       logger.warn(
         `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()} with a non integer transaction id ${
           payload.transactionId
@@ -639,17 +640,29 @@ export class OCPP16ResponseService extends OCPPResponseService {
           transactionConnectorId,
           requestPayload.meterStart,
         );
-      const reservedOnConnectorZero =
-        chargingStation.getConnectorStatus(0)!.status === OCPP16ChargePointStatus.Reserved;
-      if (
-        chargingStation.getConnectorStatus(transactionConnectorId)!.status ===
-          OCPP16ChargePointStatus.Reserved ||
-        reservedOnConnectorZero
-      ) {
+      if (requestPayload.reservationId) {
         const reservation = chargingStation.getReservationBy(
-          'connectorId',
-          reservedOnConnectorZero ? 0 : transactionConnectorId,
+          'reservationId',
+          requestPayload.reservationId,
         )!;
+        if (reservation.idTag !== requestPayload.idTag) {
+          logger.warn(
+            `${chargingStation.logPrefix()} Reserved transaction ${
+              payload.transactionId
+            } started with a different idTag ${requestPayload.idTag} than the reservation one ${
+              reservation.idTag
+            }`,
+          );
+        }
+        if (hasReservationExpired(reservation)) {
+          logger.warn(
+            `${chargingStation.logPrefix()} Reserved transaction ${
+              payload.transactionId
+            } started with expired reservation ${
+              requestPayload.reservationId
+            } (expiry date: ${reservation.expiryDate.toISOString()}))`,
+          );
+        }
         await chargingStation.removeReservation(
           reservation,
           ReservationTerminationReason.TRANSACTION_STARTED,
@@ -691,8 +704,19 @@ export class OCPP16ResponseService extends OCPPResponseService {
       );
     } else {
       logger.warn(
-        `${chargingStation.logPrefix()} Starting transaction with id ${payload.transactionId.toString()} REJECTED with status '${payload
-          .idTagInfo?.status}', idTag '${requestPayload.idTag}'`,
+        `${chargingStation.logPrefix()} Starting transaction with id ${payload.transactionId.toString()} REJECTED on ${
+          chargingStation.stationInfo.chargingStationId
+        }#${transactionConnectorId.toString()} with status '${payload.idTagInfo?.status}', idTag '${
+          requestPayload.idTag
+        }'${
+          OCPP16ServiceUtils.hasReservation(
+            chargingStation,
+            transactionConnectorId,
+            requestPayload.idTag,
+          )
+            ? `, reservationId '${requestPayload.reservationId}'`
+            : ''
+        }`,
       );
       await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
     }
@@ -704,7 +728,6 @@ export class OCPP16ResponseService extends OCPPResponseService {
   ): Promise<void> {
     resetConnectorStatus(chargingStation.getConnectorStatus(connectorId)!);
     chargingStation.stopMeterValues(connectorId);
-    parentPort?.postMessage(buildUpdatedMessage(chargingStation));
     if (
       chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
     ) {
@@ -714,6 +737,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
         OCPP16ChargePointStatus.Available,
       );
     }
+    parentPort?.postMessage(buildUpdatedMessage(chargingStation));
   }
 
   private async handleResponseStopTransaction(