feat: add support for relative charging profile
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 24 Jul 2023 17:18:14 +0000 (19:18 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Mon, 24 Jul 2023 17:18:14 +0000 (19:18 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ChargingStationUtils.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts

index aa590b7819b197cf59d4bf2150288eada03b4d2c..6a64df3d59d44d4f18cbf7880e99a090a3eeacda 100644 (file)
@@ -746,10 +746,13 @@ const getLimitFromChargingProfiles = (
           }
           break;
       }
+    } else if (chargingProfile.chargingProfileKind === ChargingProfileKindType.RELATIVE) {
+      chargingSchedule.startSchedule =
+        chargingStation.getConnectorStatus(connectorId)?.transactionStart;
     }
     // Check if the charging profile is active
     if (
-      isAfter(addSeconds(chargingSchedule.startSchedule, chargingSchedule.duration!), currentDate)
+      isAfter(addSeconds(chargingSchedule.startSchedule!, chargingSchedule.duration!), currentDate)
     ) {
       let lastButOneSchedule: ChargingSchedulePeriod | undefined;
       // Search the right schedule period
@@ -769,7 +772,7 @@ const getLimitFromChargingProfiles = (
         // Find the right schedule period
         if (
           isAfter(
-            addSeconds(chargingSchedule.startSchedule, schedulePeriod.startPeriod),
+            addSeconds(chargingSchedule.startSchedule!, schedulePeriod.startPeriod),
             currentDate,
           )
         ) {
index 163b006f5bdac0fea1d2ed00396715d3fc26ecd6..82647835535d725a5bd89f545c17169790d32b14 100644 (file)
@@ -730,53 +730,23 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     }
     if (isNullOrUndefined(commandPayload.connectorId)) {
       let clearedCP = false;
-      const clearChargingProfiles = (connectorStatus: ConnectorStatus) => {
-        if (isNotEmptyArray(connectorStatus?.chargingProfiles)) {
-          connectorStatus?.chargingProfiles?.forEach(
-            (chargingProfile: OCPP16ChargingProfile, index: number) => {
-              let clearCurrentCP = false;
-              if (chargingProfile.chargingProfileId === commandPayload.id) {
-                clearCurrentCP = true;
-              }
-              if (
-                !commandPayload.chargingProfilePurpose &&
-                chargingProfile.stackLevel === commandPayload.stackLevel
-              ) {
-                clearCurrentCP = true;
-              }
-              if (
-                !chargingProfile.stackLevel &&
-                chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
-              ) {
-                clearCurrentCP = true;
-              }
-              if (
-                chargingProfile.stackLevel === commandPayload.stackLevel &&
-                chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
-              ) {
-                clearCurrentCP = true;
-              }
-              if (clearCurrentCP) {
-                connectorStatus?.chargingProfiles?.splice(index, 1);
-                logger.debug(
-                  `${chargingStation.logPrefix()} Matching charging profile(s) cleared: %j`,
-                  chargingProfile,
-                );
-                clearedCP = true;
-              }
-            },
-          );
-        }
-      };
       if (chargingStation.hasEvses) {
         for (const evseStatus of chargingStation.evses.values()) {
           for (const connectorStatus of evseStatus.connectors.values()) {
-            clearChargingProfiles(connectorStatus);
+            clearedCP = OCPP16ServiceUtils.clearChargingProfiles(
+              chargingStation,
+              commandPayload,
+              connectorStatus.chargingProfiles,
+            );
           }
         }
       } else {
         for (const connectorId of chargingStation.connectors.keys()) {
-          clearChargingProfiles(chargingStation.getConnectorStatus(connectorId)!);
+          clearedCP = OCPP16ServiceUtils.clearChargingProfiles(
+            chargingStation,
+            commandPayload,
+            chargingStation.getConnectorStatus(connectorId)?.chargingProfiles,
+          );
         }
       }
       if (clearedCP) {
index c3e708df176d8c08a8c7f8a85c1bd99e0927dbcd..b2f1c400f3b0217cbc613b815393f67c9ecd0a08 100644 (file)
@@ -5,6 +5,7 @@ import type { JSONSchemaType } from 'ajv';
 import { type ChargingStation, getIdTagsFile } from '../../../charging-station';
 import { OCPPError } from '../../../exception';
 import {
+  type ClearChargingProfileRequest,
   type ConnectorStatus,
   CurrentType,
   ErrorType,
@@ -832,6 +833,49 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
     !cpReplaced && chargingStation.getConnectorStatus(connectorId)?.chargingProfiles?.push(cp);
   }
 
+  public static clearChargingProfiles = (
+    chargingStation: ChargingStation,
+    commandPayload: ClearChargingProfileRequest,
+    chargingProfiles: OCPP16ChargingProfile[] | undefined,
+  ): boolean => {
+    let clearedCP = false;
+    if (isNotEmptyArray(chargingProfiles)) {
+      chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => {
+        let clearCurrentCP = false;
+        if (chargingProfile.chargingProfileId === commandPayload.id) {
+          clearCurrentCP = true;
+        }
+        if (
+          !commandPayload.chargingProfilePurpose &&
+          chargingProfile.stackLevel === commandPayload.stackLevel
+        ) {
+          clearCurrentCP = true;
+        }
+        if (
+          !chargingProfile.stackLevel &&
+          chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
+        ) {
+          clearCurrentCP = true;
+        }
+        if (
+          chargingProfile.stackLevel === commandPayload.stackLevel &&
+          chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
+        ) {
+          clearCurrentCP = true;
+        }
+        if (clearCurrentCP) {
+          chargingProfiles.splice(index, 1);
+          logger.debug(
+            `${chargingStation.logPrefix()} Matching charging profile(s) cleared: %j`,
+            chargingProfile,
+          );
+          clearedCP = true;
+        }
+      });
+    }
+    return clearedCP;
+  };
+
   public static parseJsonSchemaFile<T extends JsonType>(
     relativePath: string,
     moduleName?: string,