fix: ensure daily recurring charging profiles are adjusted on a day
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStationUtils.ts
index 4fdfe230a38360b5917f3d8627bdcb9860ea66d9..7865eb1f3d14433226aad8ddd16a8db496360645 100644 (file)
@@ -4,7 +4,7 @@ import { basename, dirname, join } from 'node:path';
 import { fileURLToPath } from 'node:url';
 
 import chalk from 'chalk';
-import moment from 'moment';
+import { addSeconds, isAfter, isTomorrow, isYesterday } from 'date-fns';
 
 import type { ChargingStation } from './ChargingStation';
 import { BaseError } from '../exception';
@@ -36,6 +36,7 @@ import {
   Constants,
   DCElectricUtils,
   cloneObject,
+  convertToDate,
   convertToInt,
   isEmptyObject,
   isEmptyString,
@@ -538,7 +539,7 @@ export const waitChargingStationEvents = async (
   event: ChargingStationWorkerMessageEvents,
   eventsToWait: number,
 ): Promise<number> => {
-  return new Promise((resolve) => {
+  return new Promise<number>((resolve) => {
     let events = 0;
     if (eventsToWait === 0) {
       resolve(events);
@@ -565,7 +566,6 @@ const getConfiguredNumberOfConnectors = (stationTemplate: ChargingStationTemplat
       ? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1
       : getMaxNumberOfConnectors(stationTemplate.Connectors);
   } else if (stationTemplate.Evses && !stationTemplate.Connectors) {
-    configuredMaxConnectors = 0;
     for (const evse in stationTemplate.Evses) {
       if (evse === '0') {
         continue;
@@ -624,7 +624,7 @@ const warnDeprecatedTemplateKey = (
   templateFile: string,
   logMsgToAppend = '',
 ): void => {
-  if (!isUndefined(template[key])) {
+  if (!isUndefined(template[key as keyof ChargingStationTemplate])) {
     const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${
       isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : ''
     }`;
@@ -638,11 +638,12 @@ const convertDeprecatedTemplateKey = (
   deprecatedKey: string,
   key?: string,
 ): void => {
-  if (!isUndefined(template[deprecatedKey])) {
+  if (!isUndefined(template[deprecatedKey as keyof ChargingStationTemplate])) {
     if (!isUndefined(key)) {
-      template[key!] = template[deprecatedKey] as unknown;
+      (template as unknown as Record<string, unknown>)[key!] =
+        template[deprecatedKey as keyof ChargingStationTemplate];
     }
-    delete template[deprecatedKey];
+    delete template[deprecatedKey as keyof ChargingStationTemplate];
   }
 };
 
@@ -661,7 +662,6 @@ const getLimitFromChargingProfiles = (
   matchingChargingProfile: ChargingProfile;
 } | null => {
   const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`;
-  const currentMoment = moment();
   const currentDate = new Date();
   for (const chargingProfile of chargingProfiles) {
     // Set helpers
@@ -671,36 +671,31 @@ const getLimitFromChargingProfiles = (
         `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not defined in charging profile id ${chargingProfile.chargingProfileId}`,
       );
     }
+    if (!(chargingSchedule?.startSchedule instanceof Date)) {
+      logger.warn(
+        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not a Date object in charging profile id ${chargingProfile.chargingProfileId}. Trying to convert it to a Date object`,
+      );
+      chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!;
+    }
     // Check type (recurring) and if it is already active
     // Adjust the daily recurring schedule to today
     if (
       chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING &&
-      chargingProfile.recurrencyKind === RecurrencyKindType.DAILY &&
-      currentMoment.isAfter(chargingSchedule.startSchedule)
+      chargingProfile.recurrencyKind === RecurrencyKindType.DAILY
     ) {
-      if (!(chargingSchedule?.startSchedule instanceof Date)) {
-        logger.warn(
-          `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not a Date object in charging profile id ${chargingProfile.chargingProfileId}. Trying to convert it to a Date object`,
+      if (isYesterday(chargingSchedule.startSchedule)) {
+        chargingSchedule.startSchedule.setFullYear(
+          currentDate.getFullYear(),
+          currentDate.getMonth(),
+          currentDate.getDate(),
         );
-        chargingSchedule.startSchedule = new Date(chargingSchedule.startSchedule!);
-      }
-      chargingSchedule.startSchedule.setFullYear(
-        currentDate.getFullYear(),
-        currentDate.getMonth(),
-        currentDate.getDate(),
-      );
-      // Check if the start of the schedule is yesterday
-      if (moment(chargingSchedule.startSchedule).isAfter(currentMoment)) {
+      } else if (isTomorrow(chargingSchedule.startSchedule)) {
         chargingSchedule.startSchedule.setDate(currentDate.getDate() - 1);
       }
-    } else if (moment(chargingSchedule.startSchedule).isAfter(currentMoment)) {
-      return null;
     }
     // Check if the charging profile is active
     if (
-      moment(chargingSchedule.startSchedule)
-        .add(chargingSchedule.duration, 's')
-        .isAfter(currentMoment)
+      isAfter(addSeconds(chargingSchedule.startSchedule, chargingSchedule.duration!), currentDate)
     ) {
       let lastButOneSchedule: ChargingSchedulePeriod | undefined;
       // Search the right schedule period
@@ -719,9 +714,10 @@ const getLimitFromChargingProfiles = (
         }
         // Find the right schedule period
         if (
-          moment(chargingSchedule.startSchedule)
-            .add(schedulePeriod.startPeriod, 's')
-            .isAfter(currentMoment)
+          isAfter(
+            addSeconds(chargingSchedule.startSchedule, schedulePeriod.startPeriod),
+            currentDate,
+          )
         ) {
           // Found the schedule: last but one is the correct one
           const result = {