fix: fix TxProfile removal with transaction id defined at Tx stop
[e-mobility-charging-stations-simulator.git] / src / charging-station / Helpers.ts
index 2c264cd5612cfbeb8d1ccf01347e06810fcabf0d..93df1dedd9da579e2991bca552752745545f0506 100644 (file)
@@ -420,10 +420,11 @@ export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefine
   if (isNotEmptyArray(connectorStatus.chargingProfiles)) {
     connectorStatus.chargingProfiles = connectorStatus.chargingProfiles.filter(
       chargingProfile =>
-        chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE ||
-        (chargingProfile.transactionId != null &&
+        (chargingProfile.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE &&
+          chargingProfile.transactionId != null &&
           connectorStatus.transactionId != null &&
-          chargingProfile.transactionId !== connectorStatus.transactionId)
+          chargingProfile.transactionId !== connectorStatus.transactionId) ||
+        chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
     )
   }
   resetAuthorizeConnectorStatus(connectorStatus)
@@ -436,22 +437,25 @@ export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefine
   delete connectorStatus.transactionBeginMeterValue
 }
 
-export const prepareDatesInConnectorStatus = (
-  connectorStatus: ConnectorStatus
-): ConnectorStatus => {
+export const prepareConnectorStatus = (connectorStatus: ConnectorStatus): ConnectorStatus => {
   if (connectorStatus.reservation != null) {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     connectorStatus.reservation.expiryDate = convertToDate(connectorStatus.reservation.expiryDate)!
   }
   if (isNotEmptyArray(connectorStatus.chargingProfiles)) {
-    connectorStatus.chargingProfiles = connectorStatus.chargingProfiles.map(chargingProfile => {
-      chargingProfile.chargingSchedule.startSchedule = convertToDate(
-        chargingProfile.chargingSchedule.startSchedule
+    connectorStatus.chargingProfiles = connectorStatus.chargingProfiles
+      .filter(
+        chargingProfile =>
+          chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
       )
-      chargingProfile.validFrom = convertToDate(chargingProfile.validFrom)
-      chargingProfile.validTo = convertToDate(chargingProfile.validTo)
-      return chargingProfile
-    })
+      .map(chargingProfile => {
+        chargingProfile.chargingSchedule.startSchedule = convertToDate(
+          chargingProfile.chargingSchedule.startSchedule
+        )
+        chargingProfile.validFrom = convertToDate(chargingProfile.validFrom)
+        chargingProfile.validTo = convertToDate(chargingProfile.validTo)
+        return chargingProfile
+      })
   }
   return connectorStatus
 }
@@ -625,26 +629,41 @@ export const getAmperageLimitationUnitDivider = (stationInfo: ChargingStationInf
 }
 
 /**
- * Gets the connector cloned charging profiles applying a power limitation
- * and sorted by connector id descending then stack level descending
+ * Gets the connector charging profiles relevant for power limitation shallow cloned and sorted by priorities
  *
- * @param chargingStation -
- * @param connectorId -
+ * @param chargingStation - Charging station
+ * @param connectorId - Connector id
  * @returns connector charging profiles array
  */
 export const getConnectorChargingProfiles = (
   chargingStation: ChargingStation,
   connectorId: number
 ): ChargingProfile[] => {
-  return clone<ChargingProfile[]>(
-    (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
-      .sort((a, b) => b.stackLevel - a.stackLevel)
-      .concat(
-        (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? []).sort(
-          (a, b) => b.stackLevel - a.stackLevel
+  // FIXME: handle charging profile purpose CHARGE_POINT_MAX_PROFILE
+  return (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
+    .slice()
+    .sort((a, b) => {
+      if (
+        a.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE &&
+        b.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE
+      ) {
+        return -1
+      } else if (
+        a.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE &&
+        b.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE
+      ) {
+        return 1
+      }
+      return b.stackLevel - a.stackLevel
+    })
+    .concat(
+      (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? [])
+        .filter(
+          chargingProfile =>
+            chargingProfile.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE
         )
-      )
-  )
+        .sort((a, b) => b.stackLevel - a.stackLevel)
+    )
 }
 
 export const getChargingStationConnectorChargingProfilesPowerLimit = (
@@ -652,7 +671,6 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = (
   connectorId: number
 ): number | undefined => {
   let limit: number | undefined, chargingProfile: ChargingProfile | undefined
-  // Get charging profiles sorted by connector id then stack level
   const chargingProfiles = getConnectorChargingProfiles(chargingStation, connectorId)
   if (isNotEmptyArray(chargingProfiles)) {
     const result = getLimitFromChargingProfiles(
@@ -869,6 +887,7 @@ const getLimitFromChargingProfiles = (
   const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`
   const currentDate = new Date()
   const connectorStatus = chargingStation.getConnectorStatus(connectorId)
+  let previousActiveChargingProfile: ChargingProfile | undefined
   for (const chargingProfile of chargingProfiles) {
     const chargingSchedule = chargingProfile.chargingSchedule
     if (chargingSchedule.startSchedule == null) {
@@ -952,15 +971,12 @@ const getLimitFromChargingProfiles = (
           ) {
             // Found the schedule period: previous is the correct one
             const result: ChargingProfilesLimit = {
-              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-              limit: previousChargingSchedulePeriod!.limit,
-              chargingProfile
+              limit: previousChargingSchedulePeriod?.limit ?? chargingSchedulePeriod.limit,
+              chargingProfile: previousActiveChargingProfile ?? chargingProfile
             }
             logger.debug(debugLogMsg, result)
             return result
           }
-          // Keep a reference to previous one
-          previousChargingSchedulePeriod = chargingSchedulePeriod
           // Handle the last schedule period within the charging profile duration
           if (
             index === chargingSchedule.chargingSchedulePeriod.length - 1 ||
@@ -974,14 +990,18 @@ const getLimitFromChargingProfiles = (
               ) > chargingSchedule.duration)
           ) {
             const result: ChargingProfilesLimit = {
-              limit: previousChargingSchedulePeriod.limit,
+              limit: chargingSchedulePeriod.limit,
               chargingProfile
             }
             logger.debug(debugLogMsg, result)
             return result
           }
+          // Keep a reference to previous charging schedule period
+          previousChargingSchedulePeriod = chargingSchedulePeriod
         }
       }
+      // Keep a reference to previous active charging profile
+      previousActiveChargingProfile = chargingProfile
     }
   }
 }