build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / charging-station / Helpers.ts
index 4f34fe180a33b01714466c4fb3cc792335863965..6163f6780c379d0942e74f58a1b27aa04bd13503 100644 (file)
@@ -1,30 +1,29 @@
-import { createHash, randomBytes } from 'node:crypto';
-import type { EventEmitter } from 'node:events';
-import { basename, dirname, join } from 'node:path';
-import { env } from 'node:process';
-import { fileURLToPath } from 'node:url';
+import { createHash, randomBytes } from 'node:crypto'
+import type { EventEmitter } from 'node:events'
+import { basename, dirname, isAbsolute, join, parse, relative, resolve } from 'node:path'
+import { env } from 'node:process'
+import { fileURLToPath } from 'node:url'
 
-import chalk from 'chalk';
+import chalk from 'chalk'
 import {
-  type Interval,
   addDays,
   addSeconds,
   addWeeks,
   differenceInDays,
   differenceInSeconds,
   differenceInWeeks,
+  type Interval,
   isAfter,
   isBefore,
   isDate,
   isPast,
   isWithinInterval,
-  toDate,
-} from 'date-fns';
-import { maxTime } from 'date-fns/constants';
+  toDate
+} from 'date-fns'
+import { maxTime } from 'date-fns/constants'
+import { isEmpty } from 'rambda'
 
-import type { ChargingStation } from './ChargingStation';
-import { getConfigurationKey } from './ConfigurationKeyUtils';
-import { BaseError } from '../exception';
+import { BaseError } from '../exception/index.js'
 import {
   AmpereUnits,
   AvailabilityType,
@@ -32,12 +31,14 @@ import {
   BootReasonEnumType,
   type ChargingProfile,
   ChargingProfileKindType,
+  ChargingProfilePurposeType,
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
   type ChargingStationConfiguration,
   type ChargingStationInfo,
+  type ChargingStationOptions,
   type ChargingStationTemplate,
-  ChargingStationWorkerMessageEvents,
+  type ChargingStationWorkerMessageEvents,
   ConnectorPhaseRotation,
   type ConnectorStatus,
   ConnectorStatusEnum,
@@ -50,365 +51,443 @@ import {
   type Reservation,
   ReservationTerminationReason,
   StandardParametersKey,
-  SupportedFeatureProfiles,
-  Voltage,
-} from '../types';
+  type SupportedFeatureProfiles,
+  Voltage
+} from '../types/index.js'
 import {
   ACElectricUtils,
+  clone,
   Constants,
-  DCElectricUtils,
-  cloneObject,
   convertToDate,
   convertToInt,
+  DCElectricUtils,
   isArraySorted,
-  isEmptyObject,
-  isEmptyString,
   isNotEmptyArray,
   isNotEmptyString,
-  isNullOrUndefined,
-  isUndefined,
-  isValidTime,
+  isValidDate,
   logger,
-  secureRandom,
-} from '../utils';
+  secureRandom
+} from '../utils/index.js'
+import type { ChargingStation } from './ChargingStation.js'
+import { getConfigurationKey } from './ConfigurationKeyUtils.js'
 
-const moduleName = 'Helpers';
+const moduleName = 'Helpers'
+
+export const buildTemplateName = (templateFile: string): string => {
+  if (isAbsolute(templateFile)) {
+    templateFile = relative(
+      resolve(join(dirname(fileURLToPath(import.meta.url)), 'assets', 'station-templates')),
+      templateFile
+    )
+  }
+  const templateFileParsedPath = parse(templateFile)
+  return join(templateFileParsedPath.dir, templateFileParsedPath.name)
+}
 
 export const getChargingStationId = (
   index: number,
-  stationTemplate: ChargingStationTemplate | undefined,
+  stationTemplate: ChargingStationTemplate | undefined
 ): string => {
-  if (stationTemplate === undefined) {
-    return "Unknown 'chargingStationId'";
+  if (stationTemplate == null) {
+    return "Unknown 'chargingStationId'"
   }
   // In case of multiple instances: add instance index to charging station id
-  const instanceIndex = env.CF_INSTANCE_INDEX ?? 0;
-  const idSuffix = stationTemplate?.nameSuffix ?? '';
-  const idStr = `000000000${index.toString()}`;
-  return stationTemplate?.fixedName
+  const instanceIndex = env.CF_INSTANCE_INDEX ?? 0
+  const idSuffix = stationTemplate.nameSuffix ?? ''
+  const idStr = `000000000${index.toString()}`
+  return stationTemplate.fixedName === true
     ? stationTemplate.baseName
     : `${stationTemplate.baseName}-${instanceIndex.toString()}${idStr.substring(
-        idStr.length - 4,
-      )}${idSuffix}`;
-};
+        idStr.length - 4
+      )}${idSuffix}`
+}
 
 export const hasReservationExpired = (reservation: Reservation): boolean => {
-  return isPast(reservation.expiryDate);
-};
+  return isPast(reservation.expiryDate)
+}
 
 export const removeExpiredReservations = async (
-  chargingStation: ChargingStation,
+  chargingStation: ChargingStation
 ): Promise<void> => {
   if (chargingStation.hasEvses) {
     for (const evseStatus of chargingStation.evses.values()) {
       for (const connectorStatus of evseStatus.connectors.values()) {
-        if (connectorStatus.reservation && hasReservationExpired(connectorStatus.reservation)) {
+        if (
+          connectorStatus.reservation != null &&
+          hasReservationExpired(connectorStatus.reservation)
+        ) {
           await chargingStation.removeReservation(
             connectorStatus.reservation,
-            ReservationTerminationReason.EXPIRED,
-          );
+            ReservationTerminationReason.EXPIRED
+          )
         }
       }
     }
   } else {
     for (const connectorStatus of chargingStation.connectors.values()) {
-      if (connectorStatus.reservation && hasReservationExpired(connectorStatus.reservation)) {
+      if (
+        connectorStatus.reservation != null &&
+        hasReservationExpired(connectorStatus.reservation)
+      ) {
         await chargingStation.removeReservation(
           connectorStatus.reservation,
-          ReservationTerminationReason.EXPIRED,
-        );
+          ReservationTerminationReason.EXPIRED
+        )
       }
     }
   }
-};
+}
 
 export const getNumberOfReservableConnectors = (
-  connectors: Map<number, ConnectorStatus>,
+  connectors: Map<number, ConnectorStatus>
 ): number => {
-  let numberOfReservableConnectors = 0;
+  let numberOfReservableConnectors = 0
   for (const [connectorId, connectorStatus] of connectors) {
     if (connectorId === 0) {
-      continue;
+      continue
     }
     if (connectorStatus.status === ConnectorStatusEnum.Available) {
-      ++numberOfReservableConnectors;
+      ++numberOfReservableConnectors
     }
   }
-  return numberOfReservableConnectors;
-};
+  return numberOfReservableConnectors
+}
 
 export const getHashId = (index: number, stationTemplate: ChargingStationTemplate): string => {
   const chargingStationInfo = {
     chargePointModel: stationTemplate.chargePointModel,
     chargePointVendor: stationTemplate.chargePointVendor,
-    ...(!isUndefined(stationTemplate.chargeBoxSerialNumberPrefix) && {
-      chargeBoxSerialNumber: stationTemplate.chargeBoxSerialNumberPrefix,
+    ...(stationTemplate.chargeBoxSerialNumberPrefix != null && {
+      chargeBoxSerialNumber: stationTemplate.chargeBoxSerialNumberPrefix
     }),
-    ...(!isUndefined(stationTemplate.chargePointSerialNumberPrefix) && {
-      chargePointSerialNumber: stationTemplate.chargePointSerialNumberPrefix,
+    ...(stationTemplate.chargePointSerialNumberPrefix != null && {
+      chargePointSerialNumber: stationTemplate.chargePointSerialNumberPrefix
     }),
-    ...(!isUndefined(stationTemplate.meterSerialNumberPrefix) && {
-      meterSerialNumber: stationTemplate.meterSerialNumberPrefix,
+    ...(stationTemplate.meterSerialNumberPrefix != null && {
+      meterSerialNumber: stationTemplate.meterSerialNumberPrefix
     }),
-    ...(!isUndefined(stationTemplate.meterType) && {
-      meterType: stationTemplate.meterType,
-    }),
-  };
+    ...(stationTemplate.meterType != null && {
+      meterType: stationTemplate.meterType
+    })
+  }
   return createHash(Constants.DEFAULT_HASH_ALGORITHM)
     .update(`${JSON.stringify(chargingStationInfo)}${getChargingStationId(index, stationTemplate)}`)
-    .digest('hex');
-};
+    .digest('hex')
+}
 
 export const checkChargingStation = (
   chargingStation: ChargingStation,
-  logPrefix: string,
+  logPrefix: string
 ): boolean => {
-  if (chargingStation.started === false && chargingStation.starting === false) {
-    logger.warn(`${logPrefix} charging station is stopped, cannot proceed`);
-    return false;
+  if (!chargingStation.started && !chargingStation.starting) {
+    logger.warn(`${logPrefix} charging station is stopped, cannot proceed`)
+    return false
   }
-  return true;
-};
+  return true
+}
 
 export const getPhaseRotationValue = (
   connectorId: number,
-  numberOfPhases: number,
+  numberOfPhases: number
 ): string | undefined => {
   // AC/DC
   if (connectorId === 0 && numberOfPhases === 0) {
-    return `${connectorId}.${ConnectorPhaseRotation.RST}`;
+    return `${connectorId}.${ConnectorPhaseRotation.RST}`
   } else if (connectorId > 0 && numberOfPhases === 0) {
-    return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`;
+    return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`
     // AC
   } else if (connectorId >= 0 && numberOfPhases === 1) {
-    return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`;
+    return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`
   } else if (connectorId >= 0 && numberOfPhases === 3) {
-    return `${connectorId}.${ConnectorPhaseRotation.RST}`;
+    return `${connectorId}.${ConnectorPhaseRotation.RST}`
   }
-};
+}
 
-export const getMaxNumberOfEvses = (evses: Record<string, EvseTemplate>): number => {
-  if (!evses) {
-    return -1;
+export const getMaxNumberOfEvses = (evses: Record<string, EvseTemplate> | undefined): number => {
+  if (evses == null) {
+    return -1
   }
-  return Object.keys(evses).length;
-};
+  return Object.keys(evses).length
+}
 
-const getMaxNumberOfConnectors = (connectors: Record<string, ConnectorStatus>): number => {
-  if (!connectors) {
-    return -1;
+const getMaxNumberOfConnectors = (
+  connectors: Record<string, ConnectorStatus> | undefined
+): number => {
+  if (connectors == null) {
+    return -1
   }
-  return Object.keys(connectors).length;
-};
+  return Object.keys(connectors).length
+}
 
 export const getBootConnectorStatus = (
   chargingStation: ChargingStation,
   connectorId: number,
-  connectorStatus: ConnectorStatus,
+  connectorStatus: ConnectorStatus
 ): ConnectorStatusEnum => {
-  let connectorBootStatus: ConnectorStatusEnum;
+  let connectorBootStatus: ConnectorStatusEnum
   if (
-    !connectorStatus?.status &&
-    (chargingStation.isChargingStationAvailable() === false ||
-      chargingStation.isConnectorAvailable(connectorId) === false)
+    connectorStatus.status == null &&
+    (!chargingStation.isChargingStationAvailable() ||
+      !chargingStation.isConnectorAvailable(connectorId))
   ) {
-    connectorBootStatus = ConnectorStatusEnum.Unavailable;
-  } else if (!connectorStatus?.status && connectorStatus?.bootStatus) {
+    connectorBootStatus = ConnectorStatusEnum.Unavailable
+  } else if (connectorStatus.status == null && connectorStatus.bootStatus != null) {
     // Set boot status in template at startup
-    connectorBootStatus = connectorStatus?.bootStatus;
-  } else if (connectorStatus?.status) {
+    connectorBootStatus = connectorStatus.bootStatus
+  } else if (connectorStatus.status != null) {
     // Set previous status at startup
-    connectorBootStatus = connectorStatus?.status;
+    connectorBootStatus = connectorStatus.status
   } else {
     // Set default status
-    connectorBootStatus = ConnectorStatusEnum.Available;
+    connectorBootStatus = ConnectorStatusEnum.Available
   }
-  return connectorBootStatus;
-};
+  return connectorBootStatus
+}
 
 export const checkTemplate = (
-  stationTemplate: ChargingStationTemplate,
+  stationTemplate: ChargingStationTemplate | undefined,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): void => {
-  if (isNullOrUndefined(stationTemplate)) {
-    const errorMsg = `Failed to read charging station template file ${templateFile}`;
-    logger.error(`${logPrefix} ${errorMsg}`);
-    throw new BaseError(errorMsg);
-  }
-  if (isEmptyObject(stationTemplate)) {
-    const errorMsg = `Empty charging station information from template file ${templateFile}`;
-    logger.error(`${logPrefix} ${errorMsg}`);
-    throw new BaseError(errorMsg);
+  if (stationTemplate == null) {
+    const errorMsg = `Failed to read charging station template file ${templateFile}`
+    logger.error(`${logPrefix} ${errorMsg}`)
+    throw new BaseError(errorMsg)
   }
-  if (isEmptyObject(stationTemplate.AutomaticTransactionGenerator!)) {
-    stationTemplate.AutomaticTransactionGenerator = Constants.DEFAULT_ATG_CONFIGURATION;
-    logger.warn(
-      `${logPrefix} Empty automatic transaction generator configuration from template file ${templateFile}, set to default: %j`,
-      Constants.DEFAULT_ATG_CONFIGURATION,
-    );
+  if (isEmpty(stationTemplate)) {
+    const errorMsg = `Empty charging station information from template file ${templateFile}`
+    logger.error(`${logPrefix} ${errorMsg}`)
+    throw new BaseError(errorMsg)
   }
-  if (isNullOrUndefined(stationTemplate.idTagsFile) || isEmptyString(stationTemplate.idTagsFile)) {
+  if (stationTemplate.idTagsFile == null || isEmpty(stationTemplate.idTagsFile)) {
     logger.warn(
-      `${logPrefix} Missing id tags file in template file ${templateFile}. That can lead to issues with the Automatic Transaction Generator`,
-    );
+      `${logPrefix} Missing id tags file in template file ${templateFile}. That can lead to issues with the Automatic Transaction Generator`
+    )
   }
-};
+}
 
 export const checkConfiguration = (
   stationConfiguration: ChargingStationConfiguration | undefined,
   logPrefix: string,
-  configurationFile: string,
+  configurationFile: string
 ): void => {
-  if (isNullOrUndefined(stationConfiguration)) {
-    const errorMsg = `Failed to read charging station configuration file ${configurationFile}`;
-    logger.error(`${logPrefix} ${errorMsg}`);
-    throw new BaseError(errorMsg);
+  if (stationConfiguration == null) {
+    const errorMsg = `Failed to read charging station configuration file ${configurationFile}`
+    logger.error(`${logPrefix} ${errorMsg}`)
+    throw new BaseError(errorMsg)
   }
-  if (isEmptyObject(stationConfiguration!)) {
-    const errorMsg = `Empty charging station configuration from file ${configurationFile}`;
-    logger.error(`${logPrefix} ${errorMsg}`);
-    throw new BaseError(errorMsg);
+  if (isEmpty(stationConfiguration)) {
+    const errorMsg = `Empty charging station configuration from file ${configurationFile}`
+    logger.error(`${logPrefix} ${errorMsg}`)
+    throw new BaseError(errorMsg)
   }
-};
+}
 
 export const checkConnectorsConfiguration = (
   stationTemplate: ChargingStationTemplate,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): {
-  configuredMaxConnectors: number;
-  templateMaxConnectors: number;
-  templateMaxAvailableConnectors: number;
+  configuredMaxConnectors: number
+  templateMaxConnectors: number
+  templateMaxAvailableConnectors: number
 } => {
-  const configuredMaxConnectors = getConfiguredMaxNumberOfConnectors(stationTemplate);
-  checkConfiguredMaxConnectors(configuredMaxConnectors, logPrefix, templateFile);
-  const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors!);
-  checkTemplateMaxConnectors(templateMaxConnectors, logPrefix, templateFile);
-  const templateMaxAvailableConnectors = stationTemplate.Connectors?.[0]
-    ? templateMaxConnectors - 1
-    : templateMaxConnectors;
+  const configuredMaxConnectors = getConfiguredMaxNumberOfConnectors(stationTemplate)
+  checkConfiguredMaxConnectors(configuredMaxConnectors, logPrefix, templateFile)
+  const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors)
+  checkTemplateMaxConnectors(templateMaxConnectors, logPrefix, templateFile)
+  const templateMaxAvailableConnectors =
+    stationTemplate.Connectors?.[0] != null ? templateMaxConnectors - 1 : templateMaxConnectors
   if (
     configuredMaxConnectors > templateMaxAvailableConnectors &&
-    !stationTemplate?.randomConnectors
+    stationTemplate.randomConnectors !== true
   ) {
     logger.warn(
-      `${logPrefix} Number of connectors exceeds the number of connector configurations in template ${templateFile}, forcing random connector configurations affectation`,
-    );
-    stationTemplate.randomConnectors = true;
+      `${logPrefix} Number of connectors exceeds the number of connector configurations in template ${templateFile}, forcing random connector configurations affectation`
+    )
+    stationTemplate.randomConnectors = true
+  }
+  return {
+    configuredMaxConnectors,
+    templateMaxConnectors,
+    templateMaxAvailableConnectors
   }
-  return { configuredMaxConnectors, templateMaxConnectors, templateMaxAvailableConnectors };
-};
+}
 
 export const checkStationInfoConnectorStatus = (
   connectorId: number,
   connectorStatus: ConnectorStatus,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): void => {
-  if (!isNullOrUndefined(connectorStatus?.status)) {
+  if (connectorStatus.status != null) {
     logger.warn(
-      `${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it`,
-    );
-    delete connectorStatus.status;
+      `${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it`
+    )
+    delete connectorStatus.status
   }
-};
+}
+
+export const setChargingStationOptions = (
+  stationInfo: ChargingStationInfo,
+  options?: ChargingStationOptions
+): ChargingStationInfo => {
+  if (options?.supervisionUrls != null) {
+    stationInfo.supervisionUrls = options.supervisionUrls
+  }
+  if (options?.persistentConfiguration != null) {
+    stationInfo.stationInfoPersistentConfiguration = options.persistentConfiguration
+    stationInfo.ocppPersistentConfiguration = options.persistentConfiguration
+    stationInfo.automaticTransactionGeneratorPersistentConfiguration =
+      options.persistentConfiguration
+  }
+  if (options?.autoStart != null) {
+    stationInfo.autoStart = options.autoStart
+  }
+  if (options?.autoRegister != null) {
+    stationInfo.autoRegister = options.autoRegister
+  }
+  if (options?.enableStatistics != null) {
+    stationInfo.enableStatistics = options.enableStatistics
+  }
+  if (options?.ocppStrictCompliance != null) {
+    stationInfo.ocppStrictCompliance = options.ocppStrictCompliance
+  }
+  if (options?.stopTransactionsOnStopped != null) {
+    stationInfo.stopTransactionsOnStopped = options.stopTransactionsOnStopped
+  }
+  return stationInfo
+}
 
 export const buildConnectorsMap = (
   connectors: Record<string, ConnectorStatus>,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): Map<number, ConnectorStatus> => {
-  const connectorsMap = new Map<number, ConnectorStatus>();
+  const connectorsMap = new Map<number, ConnectorStatus>()
   if (getMaxNumberOfConnectors(connectors) > 0) {
     for (const connector in connectors) {
-      const connectorStatus = connectors[connector];
-      const connectorId = convertToInt(connector);
-      checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile);
-      connectorsMap.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus));
+      const connectorStatus = connectors[connector]
+      const connectorId = convertToInt(connector)
+      checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile)
+      connectorsMap.set(connectorId, clone<ConnectorStatus>(connectorStatus))
     }
   } else {
     logger.warn(
-      `${logPrefix} Charging station information from template ${templateFile} with no connectors, cannot build connectors map`,
-    );
+      `${logPrefix} Charging station information from template ${templateFile} with no connectors, cannot build connectors map`
+    )
   }
-  return connectorsMap;
-};
+  return connectorsMap
+}
 
 export const initializeConnectorsMapStatus = (
   connectors: Map<number, ConnectorStatus>,
-  logPrefix: string,
+  logPrefix: string
 ): void => {
   for (const connectorId of connectors.keys()) {
     if (connectorId > 0 && connectors.get(connectorId)?.transactionStarted === true) {
       logger.warn(
-        `${logPrefix} Connector id ${connectorId} at initialization has a transaction started with id ${connectors.get(
-          connectorId,
-        )?.transactionId}`,
-      );
+        `${logPrefix} Connector id ${connectorId} at initialization has a transaction started with id ${
+          connectors.get(connectorId)?.transactionId
+        }`
+      )
     }
     if (connectorId === 0) {
-      connectors.get(connectorId)!.availability = AvailabilityType.Operative;
-      if (isUndefined(connectors.get(connectorId)?.chargingProfiles)) {
-        connectors.get(connectorId)!.chargingProfiles = [];
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      connectors.get(connectorId)!.availability = AvailabilityType.Operative
+      if (connectors.get(connectorId)?.chargingProfiles == null) {
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        connectors.get(connectorId)!.chargingProfiles = []
       }
-    } else if (
-      connectorId > 0 &&
-      isNullOrUndefined(connectors.get(connectorId)?.transactionStarted)
-    ) {
-      initializeConnectorStatus(connectors.get(connectorId)!);
+    } else if (connectorId > 0 && connectors.get(connectorId)?.transactionStarted == null) {
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      initializeConnectorStatus(connectors.get(connectorId)!)
     }
   }
-};
+}
+
+export const resetAuthorizeConnectorStatus = (connectorStatus: ConnectorStatus): void => {
+  connectorStatus.idTagLocalAuthorized = false
+  connectorStatus.idTagAuthorized = false
+  delete connectorStatus.localAuthorizeIdTag
+  delete connectorStatus.authorizeIdTag
+}
+
+export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefined): void => {
+  if (connectorStatus == null) {
+    return
+  }
+  if (isNotEmptyArray(connectorStatus.chargingProfiles)) {
+    connectorStatus.chargingProfiles = connectorStatus.chargingProfiles.filter(
+      chargingProfile =>
+        (chargingProfile.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE &&
+          chargingProfile.transactionId != null &&
+          connectorStatus.transactionId != null &&
+          chargingProfile.transactionId !== connectorStatus.transactionId) ||
+        chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
+    )
+  }
+  resetAuthorizeConnectorStatus(connectorStatus)
+  connectorStatus.transactionRemoteStarted = false
+  connectorStatus.transactionStarted = false
+  delete connectorStatus.transactionStart
+  delete connectorStatus.transactionId
+  delete connectorStatus.transactionIdTag
+  connectorStatus.transactionEnergyActiveImportRegisterValue = 0
+  delete connectorStatus.transactionBeginMeterValue
+}
 
-export const resetConnectorStatus = (connectorStatus: ConnectorStatus): void => {
-  connectorStatus.chargingProfiles =
-    connectorStatus.transactionId && isNotEmptyArray(connectorStatus.chargingProfiles)
-      ? connectorStatus.chargingProfiles?.filter(
-          (chargingProfile) => chargingProfile.transactionId !== connectorStatus.transactionId,
+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
+      .filter(
+        chargingProfile =>
+          chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
+      )
+      .map(chargingProfile => {
+        chargingProfile.chargingSchedule.startSchedule = convertToDate(
+          chargingProfile.chargingSchedule.startSchedule
         )
-      : [];
-  connectorStatus.idTagLocalAuthorized = false;
-  connectorStatus.idTagAuthorized = false;
-  connectorStatus.transactionRemoteStarted = false;
-  connectorStatus.transactionStarted = false;
-  delete connectorStatus?.transactionStart;
-  delete connectorStatus?.transactionId;
-  delete connectorStatus?.localAuthorizeIdTag;
-  delete connectorStatus?.authorizeIdTag;
-  delete connectorStatus?.transactionIdTag;
-  connectorStatus.transactionEnergyActiveImportRegisterValue = 0;
-  delete connectorStatus?.transactionBeginMeterValue;
-};
+        chargingProfile.validFrom = convertToDate(chargingProfile.validFrom)
+        chargingProfile.validTo = convertToDate(chargingProfile.validTo)
+        return chargingProfile
+      })
+  }
+  return connectorStatus
+}
 
 export const createBootNotificationRequest = (
   stationInfo: ChargingStationInfo,
-  bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp,
-): BootNotificationRequest => {
-  const ocppVersion = stationInfo.ocppVersion!;
+  bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp
+): BootNotificationRequest | undefined => {
+  const ocppVersion = stationInfo.ocppVersion
   switch (ocppVersion) {
     case OCPPVersion.VERSION_16:
       return {
         chargePointModel: stationInfo.chargePointModel,
         chargePointVendor: stationInfo.chargePointVendor,
-        ...(!isUndefined(stationInfo.chargeBoxSerialNumber) && {
-          chargeBoxSerialNumber: stationInfo.chargeBoxSerialNumber,
-        }),
-        ...(!isUndefined(stationInfo.chargePointSerialNumber) && {
-          chargePointSerialNumber: stationInfo.chargePointSerialNumber,
+        ...(stationInfo.chargeBoxSerialNumber != null && {
+          chargeBoxSerialNumber: stationInfo.chargeBoxSerialNumber
         }),
-        ...(!isUndefined(stationInfo.firmwareVersion) && {
-          firmwareVersion: stationInfo.firmwareVersion,
+        ...(stationInfo.chargePointSerialNumber != null && {
+          chargePointSerialNumber: stationInfo.chargePointSerialNumber
         }),
-        ...(!isUndefined(stationInfo.iccid) && { iccid: stationInfo.iccid }),
-        ...(!isUndefined(stationInfo.imsi) && { imsi: stationInfo.imsi }),
-        ...(!isUndefined(stationInfo.meterSerialNumber) && {
-          meterSerialNumber: stationInfo.meterSerialNumber,
+        ...(stationInfo.firmwareVersion != null && {
+          firmwareVersion: stationInfo.firmwareVersion
         }),
-        ...(!isUndefined(stationInfo.meterType) && {
-          meterType: stationInfo.meterType,
+        ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }),
+        ...(stationInfo.imsi != null && { imsi: stationInfo.imsi }),
+        ...(stationInfo.meterSerialNumber != null && {
+          meterSerialNumber: stationInfo.meterSerialNumber
         }),
-      } as OCPP16BootNotificationRequest;
+        ...(stationInfo.meterType != null && {
+          meterType: stationInfo.meterType
+        })
+      } satisfies OCPP16BootNotificationRequest
     case OCPPVersion.VERSION_20:
     case OCPPVersion.VERSION_201:
       return {
@@ -416,589 +495,662 @@ export const createBootNotificationRequest = (
         chargingStation: {
           model: stationInfo.chargePointModel,
           vendorName: stationInfo.chargePointVendor,
-          ...(!isUndefined(stationInfo.firmwareVersion) && {
-            firmwareVersion: stationInfo.firmwareVersion,
+          ...(stationInfo.firmwareVersion != null && {
+            firmwareVersion: stationInfo.firmwareVersion
           }),
-          ...(!isUndefined(stationInfo.chargeBoxSerialNumber) && {
-            serialNumber: stationInfo.chargeBoxSerialNumber,
+          ...(stationInfo.chargeBoxSerialNumber != null && {
+            serialNumber: stationInfo.chargeBoxSerialNumber
           }),
-          ...((!isUndefined(stationInfo.iccid) || !isUndefined(stationInfo.imsi)) && {
+          ...((stationInfo.iccid != null || stationInfo.imsi != null) && {
             modem: {
-              ...(!isUndefined(stationInfo.iccid) && { iccid: stationInfo.iccid }),
-              ...(!isUndefined(stationInfo.imsi) && { imsi: stationInfo.imsi }),
-            },
-          }),
-        },
-      } as OCPP20BootNotificationRequest;
+              ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }),
+              ...(stationInfo.imsi != null && { imsi: stationInfo.imsi })
+            }
+          })
+        }
+      } satisfies OCPP20BootNotificationRequest
   }
-};
+}
 
 export const warnTemplateKeysDeprecation = (
   stationTemplate: ChargingStationTemplate,
   logPrefix: string,
-  templateFile: string,
-) => {
-  const templateKeys: { deprecatedKey: string; key?: string }[] = [
+  templateFile: string
+): void => {
+  const templateKeys: Array<{ deprecatedKey: string, key?: string }> = [
     { deprecatedKey: 'supervisionUrl', key: 'supervisionUrls' },
     { deprecatedKey: 'authorizationFile', key: 'idTagsFile' },
     { deprecatedKey: 'payloadSchemaValidation', key: 'ocppStrictCompliance' },
-    { deprecatedKey: 'mustAuthorizeAtRemoteStart', key: 'remoteAuthorization' },
-  ];
+    { deprecatedKey: 'mustAuthorizeAtRemoteStart', key: 'remoteAuthorization' }
+  ]
   for (const templateKey of templateKeys) {
     warnDeprecatedTemplateKey(
       stationTemplate,
       templateKey.deprecatedKey,
       logPrefix,
       templateFile,
-      !isUndefined(templateKey.key) ? `Use '${templateKey.key}' instead` : undefined,
-    );
-    convertDeprecatedTemplateKey(stationTemplate, templateKey.deprecatedKey, templateKey.key);
+      templateKey.key != null ? `Use '${templateKey.key}' instead` : undefined
+    )
+    convertDeprecatedTemplateKey(stationTemplate, templateKey.deprecatedKey, templateKey.key)
   }
-};
+}
 
 export const stationTemplateToStationInfo = (
-  stationTemplate: ChargingStationTemplate,
+  stationTemplate: ChargingStationTemplate
 ): ChargingStationInfo => {
-  stationTemplate = cloneObject<ChargingStationTemplate>(stationTemplate);
-  delete stationTemplate.power;
-  delete stationTemplate.powerUnit;
-  delete stationTemplate.Connectors;
-  delete stationTemplate.Evses;
-  delete stationTemplate.Configuration;
-  delete stationTemplate.AutomaticTransactionGenerator;
-  delete stationTemplate.chargeBoxSerialNumberPrefix;
-  delete stationTemplate.chargePointSerialNumberPrefix;
-  delete stationTemplate.meterSerialNumberPrefix;
-  return stationTemplate as ChargingStationInfo;
-};
+  stationTemplate = clone<ChargingStationTemplate>(stationTemplate)
+  delete stationTemplate.power
+  delete stationTemplate.powerUnit
+  delete stationTemplate.Connectors
+  delete stationTemplate.Evses
+  delete stationTemplate.Configuration
+  delete stationTemplate.AutomaticTransactionGenerator
+  delete stationTemplate.numberOfConnectors
+  delete stationTemplate.chargeBoxSerialNumberPrefix
+  delete stationTemplate.chargePointSerialNumberPrefix
+  delete stationTemplate.meterSerialNumberPrefix
+  return stationTemplate as ChargingStationInfo
+}
 
 export const createSerialNumber = (
   stationTemplate: ChargingStationTemplate,
   stationInfo: ChargingStationInfo,
   params?: {
-    randomSerialNumberUpperCase?: boolean;
-    randomSerialNumber?: boolean;
-  },
+    randomSerialNumberUpperCase?: boolean
+    randomSerialNumber?: boolean
+  }
 ): void => {
-  params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params };
-  const serialNumberSuffix = params?.randomSerialNumber
-    ? getRandomSerialNumberSuffix({
-        upperCase: params.randomSerialNumberUpperCase,
+  params = {
+    ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true },
+    ...params
+  }
+  const serialNumberSuffix =
+    params.randomSerialNumber === true
+      ? getRandomSerialNumberSuffix({
+        upperCase: params.randomSerialNumberUpperCase
       })
-    : '';
-  isNotEmptyString(stationTemplate?.chargePointSerialNumberPrefix) &&
-    (stationInfo.chargePointSerialNumber = `${stationTemplate.chargePointSerialNumberPrefix}${serialNumberSuffix}`);
-  isNotEmptyString(stationTemplate?.chargeBoxSerialNumberPrefix) &&
-    (stationInfo.chargeBoxSerialNumber = `${stationTemplate.chargeBoxSerialNumberPrefix}${serialNumberSuffix}`);
-  isNotEmptyString(stationTemplate?.meterSerialNumberPrefix) &&
-    (stationInfo.meterSerialNumber = `${stationTemplate.meterSerialNumberPrefix}${serialNumberSuffix}`);
-};
+      : ''
+  isNotEmptyString(stationTemplate.chargePointSerialNumberPrefix) &&
+    (stationInfo.chargePointSerialNumber = `${stationTemplate.chargePointSerialNumberPrefix}${serialNumberSuffix}`)
+  isNotEmptyString(stationTemplate.chargeBoxSerialNumberPrefix) &&
+    (stationInfo.chargeBoxSerialNumber = `${stationTemplate.chargeBoxSerialNumberPrefix}${serialNumberSuffix}`)
+  isNotEmptyString(stationTemplate.meterSerialNumberPrefix) &&
+    (stationInfo.meterSerialNumber = `${stationTemplate.meterSerialNumberPrefix}${serialNumberSuffix}`)
+}
 
 export const propagateSerialNumber = (
-  stationTemplate: ChargingStationTemplate,
-  stationInfoSrc: ChargingStationInfo,
-  stationInfoDst: ChargingStationInfo,
-) => {
-  if (!stationInfoSrc || !stationTemplate) {
+  stationTemplate: ChargingStationTemplate | undefined,
+  stationInfoSrc: ChargingStationInfo | undefined,
+  stationInfoDst: ChargingStationInfo
+): void => {
+  if (stationInfoSrc == null || stationTemplate == null) {
     throw new BaseError(
-      'Missing charging station template or existing configuration to propagate serial number',
-    );
+      'Missing charging station template or existing configuration to propagate serial number'
+    )
   }
-  stationTemplate?.chargePointSerialNumberPrefix && stationInfoSrc?.chargePointSerialNumber
+  stationTemplate.chargePointSerialNumberPrefix != null &&
+  stationInfoSrc.chargePointSerialNumber != null
     ? (stationInfoDst.chargePointSerialNumber = stationInfoSrc.chargePointSerialNumber)
-    : stationInfoDst?.chargePointSerialNumber && delete stationInfoDst.chargePointSerialNumber;
-  stationTemplate?.chargeBoxSerialNumberPrefix && stationInfoSrc?.chargeBoxSerialNumber
+    : stationInfoDst.chargePointSerialNumber != null &&
+      delete stationInfoDst.chargePointSerialNumber
+  stationTemplate.chargeBoxSerialNumberPrefix != null &&
+  stationInfoSrc.chargeBoxSerialNumber != null
     ? (stationInfoDst.chargeBoxSerialNumber = stationInfoSrc.chargeBoxSerialNumber)
-    : stationInfoDst?.chargeBoxSerialNumber && delete stationInfoDst.chargeBoxSerialNumber;
-  stationTemplate?.meterSerialNumberPrefix && stationInfoSrc?.meterSerialNumber
+    : stationInfoDst.chargeBoxSerialNumber != null && delete stationInfoDst.chargeBoxSerialNumber
+  stationTemplate.meterSerialNumberPrefix != null && stationInfoSrc.meterSerialNumber != null
     ? (stationInfoDst.meterSerialNumber = stationInfoSrc.meterSerialNumber)
-    : stationInfoDst?.meterSerialNumber && delete stationInfoDst.meterSerialNumber;
-};
+    : stationInfoDst.meterSerialNumber != null && delete stationInfoDst.meterSerialNumber
+}
 
 export const hasFeatureProfile = (
   chargingStation: ChargingStation,
-  featureProfile: SupportedFeatureProfiles,
+  featureProfile: SupportedFeatureProfiles
 ): boolean | undefined => {
   return getConfigurationKey(
     chargingStation,
-    StandardParametersKey.SupportedFeatureProfiles,
-  )?.value?.includes(featureProfile);
-};
+    StandardParametersKey.SupportedFeatureProfiles
+  )?.value?.includes(featureProfile)
+}
 
 export const getAmperageLimitationUnitDivider = (stationInfo: ChargingStationInfo): number => {
-  let unitDivider = 1;
+  let unitDivider = 1
   switch (stationInfo.amperageLimitationUnit) {
     case AmpereUnits.DECI_AMPERE:
-      unitDivider = 10;
-      break;
+      unitDivider = 10
+      break
     case AmpereUnits.CENTI_AMPERE:
-      unitDivider = 100;
-      break;
+      unitDivider = 100
+      break
     case AmpereUnits.MILLI_AMPERE:
-      unitDivider = 1000;
-      break;
+      unitDivider = 1000
+      break
+  }
+  return unitDivider
+}
+
+const getChargingStationChargingProfiles = (
+  chargingStation: ChargingStation
+): ChargingProfile[] => {
+  return (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? [])
+    .filter(
+      chargingProfile =>
+        chargingProfile.chargingProfilePurpose ===
+        ChargingProfilePurposeType.CHARGE_POINT_MAX_PROFILE
+    )
+    .sort((a, b) => b.stackLevel - a.stackLevel)
+}
+
+export const getChargingStationChargingProfilesLimit = (
+  chargingStation: ChargingStation
+): number | undefined => {
+  const chargingProfiles = getChargingStationChargingProfiles(chargingStation)
+  if (isNotEmptyArray(chargingProfiles)) {
+    const chargingProfilesLimit = getChargingProfilesLimit(chargingStation, 0, chargingProfiles)
+    if (chargingProfilesLimit != null) {
+      const limit = buildChargingProfilesLimit(chargingStation, chargingProfilesLimit)
+      const chargingStationMaximumPower =
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        chargingStation.stationInfo!.maximumPower!
+      if (limit > chargingStationMaximumPower) {
+        logger.error(
+          `${chargingStation.logPrefix()} ${moduleName}.getChargingStationChargingProfilesLimit: Charging profile id ${
+            chargingProfilesLimit.chargingProfile.chargingProfileId
+          } limit ${limit} is greater than charging station maximum ${chargingStationMaximumPower}: %j`,
+          chargingProfilesLimit
+        )
+        return chargingStationMaximumPower
+      }
+      return limit
+    }
   }
-  return unitDivider;
-};
+}
 
 /**
- * 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,
-) => {
-  return cloneObject<ChargingProfile[]>(
-    (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
-      .sort((a, b) => b.stackLevel - a.stackLevel)
-      .concat(
-        (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? []).sort(
-          (a, b) => b.stackLevel - a.stackLevel,
-        ),
-      ),
-  );
-};
+  connectorId: number
+): ChargingProfile[] => {
+  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 = (
+export const getConnectorChargingProfilesLimit = (
   chargingStation: ChargingStation,
-  connectorId: number,
+  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);
+  const chargingProfiles = getConnectorChargingProfiles(chargingStation, connectorId)
   if (isNotEmptyArray(chargingProfiles)) {
-    const result = getLimitFromChargingProfiles(
+    const chargingProfilesLimit = getChargingProfilesLimit(
       chargingStation,
       connectorId,
-      chargingProfiles,
-      chargingStation.logPrefix(),
-    );
-    if (!isNullOrUndefined(result)) {
-      limit = result?.limit;
-      chargingProfile = result?.chargingProfile;
-      switch (chargingStation.stationInfo?.currentOutType) {
-        case CurrentType.AC:
-          limit =
-            chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT
-              ? limit
-              : ACElectricUtils.powerTotal(
-                  chargingStation.getNumberOfPhases(),
-                  chargingStation.stationInfo.voltageOut!,
-                  limit!,
-                );
-          break;
-        case CurrentType.DC:
-          limit =
-            chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT
-              ? limit
-              : DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit!);
-      }
+      chargingProfiles
+    )
+    if (chargingProfilesLimit != null) {
+      const limit = buildChargingProfilesLimit(chargingStation, chargingProfilesLimit)
       const connectorMaximumPower =
-        chargingStation.stationInfo.maximumPower! / chargingStation.powerDivider;
-      if (limit! > connectorMaximumPower) {
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        chargingStation.stationInfo!.maximumPower! / chargingStation.powerDivider!
+      if (limit > connectorMaximumPower) {
         logger.error(
-          `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${chargingProfile?.chargingProfileId} limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`,
-          result,
-        );
-        limit = connectorMaximumPower;
+          `${chargingStation.logPrefix()} ${moduleName}.getConnectorChargingProfilesLimit: Charging profile id ${
+            chargingProfilesLimit.chargingProfile.chargingProfileId
+          } limit ${limit} is greater than connector ${connectorId} maximum ${connectorMaximumPower}: %j`,
+          chargingProfilesLimit
+        )
+        return connectorMaximumPower
       }
+      return limit
     }
   }
-  return limit;
-};
+}
+
+const buildChargingProfilesLimit = (
+  chargingStation: ChargingStation,
+  chargingProfilesLimit: ChargingProfilesLimit
+): number => {
+  const errorMsg = `Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in charging station information, cannot build charging profiles limit`
+  const { limit, chargingProfile } = chargingProfilesLimit
+  switch (chargingStation.stationInfo?.currentOutType) {
+    case CurrentType.AC:
+      return chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
+        ? limit
+        : ACElectricUtils.powerTotal(
+          chargingStation.getNumberOfPhases(),
+          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+          chargingStation.stationInfo.voltageOut!,
+          limit
+        )
+    case CurrentType.DC:
+      return chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
+        ? limit
+        : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit)
+    default:
+      logger.error(
+        `${chargingStation.logPrefix()} ${moduleName}.buildChargingProfilesLimit: ${errorMsg}`
+      )
+      throw new BaseError(errorMsg)
+  }
+}
 
 export const getDefaultVoltageOut = (
   currentType: CurrentType,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): Voltage => {
-  const errorMsg = `Unknown ${currentType} currentOutType in template file ${templateFile}, cannot define default voltage out`;
-  let defaultVoltageOut: number;
+  const errorMsg = `Unknown ${currentType} currentOutType in template file ${templateFile}, cannot define default voltage out`
+  let defaultVoltageOut: number
   switch (currentType) {
     case CurrentType.AC:
-      defaultVoltageOut = Voltage.VOLTAGE_230;
-      break;
+      defaultVoltageOut = Voltage.VOLTAGE_230
+      break
     case CurrentType.DC:
-      defaultVoltageOut = Voltage.VOLTAGE_400;
-      break;
+      defaultVoltageOut = Voltage.VOLTAGE_400
+      break
     default:
-      logger.error(`${logPrefix} ${errorMsg}`);
-      throw new BaseError(errorMsg);
+      logger.error(`${logPrefix} ${errorMsg}`)
+      throw new BaseError(errorMsg)
   }
-  return defaultVoltageOut;
-};
+  return defaultVoltageOut
+}
 
 export const getIdTagsFile = (stationInfo: ChargingStationInfo): string | undefined => {
-  return (
-    stationInfo.idTagsFile &&
-    join(dirname(fileURLToPath(import.meta.url)), 'assets', basename(stationInfo.idTagsFile))
-  );
-};
+  return stationInfo.idTagsFile != null
+    ? join(dirname(fileURLToPath(import.meta.url)), 'assets', basename(stationInfo.idTagsFile))
+    : undefined
+}
 
 export const waitChargingStationEvents = async (
   emitter: EventEmitter,
   event: ChargingStationWorkerMessageEvents,
-  eventsToWait: number,
+  eventsToWait: number
 ): Promise<number> => {
-  return new Promise<number>((resolve) => {
-    let events = 0;
+  return await new Promise<number>(resolve => {
+    let events = 0
     if (eventsToWait === 0) {
-      resolve(events);
-      return;
+      resolve(events)
+      return
     }
     emitter.on(event, () => {
-      ++events;
+      ++events
       if (events === eventsToWait) {
-        resolve(events);
+        resolve(events)
       }
-    });
-  });
-};
+    })
+  })
+}
 
 const getConfiguredMaxNumberOfConnectors = (stationTemplate: ChargingStationTemplate): number => {
-  let configuredMaxNumberOfConnectors = 0;
-  if (isNotEmptyArray(stationTemplate.numberOfConnectors) === true) {
-    const numberOfConnectors = stationTemplate.numberOfConnectors as number[];
+  let configuredMaxNumberOfConnectors = 0
+  if (isNotEmptyArray(stationTemplate.numberOfConnectors)) {
+    const numberOfConnectors = stationTemplate.numberOfConnectors
+    configuredMaxNumberOfConnectors =
+      numberOfConnectors[Math.floor(secureRandom() * numberOfConnectors.length)]
+  } else if (stationTemplate.numberOfConnectors != null) {
+    configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors
+  } else if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
     configuredMaxNumberOfConnectors =
-      numberOfConnectors[Math.floor(secureRandom() * numberOfConnectors.length)];
-  } else if (isUndefined(stationTemplate.numberOfConnectors) === false) {
-    configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number;
-  } else if (stationTemplate.Connectors && !stationTemplate.Evses) {
-    configuredMaxNumberOfConnectors = stationTemplate.Connectors?.[0]
-      ? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1
-      : getMaxNumberOfConnectors(stationTemplate.Connectors);
-  } else if (stationTemplate.Evses && !stationTemplate.Connectors) {
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+      stationTemplate.Connectors[0] != null
+        ? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1
+        : getMaxNumberOfConnectors(stationTemplate.Connectors)
+  } else if (stationTemplate.Evses != null && stationTemplate.Connectors == null) {
     for (const evse in stationTemplate.Evses) {
       if (evse === '0') {
-        continue;
+        continue
       }
       configuredMaxNumberOfConnectors += getMaxNumberOfConnectors(
-        stationTemplate.Evses[evse].Connectors,
-      );
+        stationTemplate.Evses[evse].Connectors
+      )
     }
   }
-  return configuredMaxNumberOfConnectors;
-};
+  return configuredMaxNumberOfConnectors
+}
 
 const checkConfiguredMaxConnectors = (
   configuredMaxConnectors: number,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): void => {
   if (configuredMaxConnectors <= 0) {
     logger.warn(
-      `${logPrefix} Charging station information from template ${templateFile} with ${configuredMaxConnectors} connectors`,
-    );
+      `${logPrefix} Charging station information from template ${templateFile} with ${configuredMaxConnectors} connectors`
+    )
   }
-};
+}
 
 const checkTemplateMaxConnectors = (
   templateMaxConnectors: number,
   logPrefix: string,
-  templateFile: string,
+  templateFile: string
 ): void => {
   if (templateMaxConnectors === 0) {
     logger.warn(
-      `${logPrefix} Charging station information from template ${templateFile} with empty connectors configuration`,
-    );
+      `${logPrefix} Charging station information from template ${templateFile} with empty connectors configuration`
+    )
   } else if (templateMaxConnectors < 0) {
     logger.error(
-      `${logPrefix} Charging station information from template ${templateFile} with no connectors configuration defined`,
-    );
+      `${logPrefix} Charging station information from template ${templateFile} with no connectors configuration defined`
+    )
   }
-};
+}
 
 const initializeConnectorStatus = (connectorStatus: ConnectorStatus): void => {
-  connectorStatus.availability = AvailabilityType.Operative;
-  connectorStatus.idTagLocalAuthorized = false;
-  connectorStatus.idTagAuthorized = false;
-  connectorStatus.transactionRemoteStarted = false;
-  connectorStatus.transactionStarted = false;
-  connectorStatus.energyActiveImportRegisterValue = 0;
-  connectorStatus.transactionEnergyActiveImportRegisterValue = 0;
-  if (isUndefined(connectorStatus.chargingProfiles)) {
-    connectorStatus.chargingProfiles = [];
+  connectorStatus.availability = AvailabilityType.Operative
+  connectorStatus.idTagLocalAuthorized = false
+  connectorStatus.idTagAuthorized = false
+  connectorStatus.transactionRemoteStarted = false
+  connectorStatus.transactionStarted = false
+  connectorStatus.energyActiveImportRegisterValue = 0
+  connectorStatus.transactionEnergyActiveImportRegisterValue = 0
+  if (connectorStatus.chargingProfiles == null) {
+    connectorStatus.chargingProfiles = []
   }
-};
+}
 
 const warnDeprecatedTemplateKey = (
   template: ChargingStationTemplate,
   key: string,
   logPrefix: string,
   templateFile: string,
-  logMsgToAppend = '',
+  logMsgToAppend = ''
 ): void => {
-  if (!isUndefined(template?.[key as keyof ChargingStationTemplate])) {
+  if (template[key as keyof ChargingStationTemplate] != null) {
     const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${
       isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : ''
-    }`;
-    logger.warn(`${logPrefix} ${logMsg}`);
-    console.warn(`${chalk.green(logPrefix)} ${chalk.yellow(logMsg)}`);
+    }`
+    logger.warn(`${logPrefix} ${logMsg}`)
+    console.warn(`${chalk.green(logPrefix)} ${chalk.yellow(logMsg)}`)
   }
-};
+}
 
 const convertDeprecatedTemplateKey = (
   template: ChargingStationTemplate,
   deprecatedKey: string,
-  key?: string,
+  key?: string
 ): void => {
-  if (!isUndefined(template?.[deprecatedKey as keyof ChargingStationTemplate])) {
-    if (!isUndefined(key)) {
-      (template as unknown as Record<string, unknown>)[key!] =
-        template[deprecatedKey as keyof ChargingStationTemplate];
+  if (template[deprecatedKey as keyof ChargingStationTemplate] != null) {
+    if (key != null) {
+      (template as unknown as Record<string, unknown>)[key] =
+        template[deprecatedKey as keyof ChargingStationTemplate]
     }
-    delete template[deprecatedKey as keyof ChargingStationTemplate];
+    // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
+    delete template[deprecatedKey as keyof ChargingStationTemplate]
   }
-};
+}
 
 interface ChargingProfilesLimit {
-  limit: number;
-  chargingProfile: ChargingProfile;
+  limit: number
+  chargingProfile: ChargingProfile
 }
 
 /**
- * Charging profiles shall already be sorted by connector id descending then stack level descending
+ * Get the charging profiles limit for a connector
+ * Charging profiles shall already be sorted by priorities
  *
  * @param chargingStation -
  * @param connectorId -
  * @param chargingProfiles -
- * @param logPrefix -
  * @returns ChargingProfilesLimit
  */
-const getLimitFromChargingProfiles = (
+const getChargingProfilesLimit = (
   chargingStation: ChargingStation,
   connectorId: number,
-  chargingProfiles: ChargingProfile[],
-  logPrefix: string,
+  chargingProfiles: ChargingProfile[]
 ): ChargingProfilesLimit | undefined => {
-  const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`;
-  const currentDate = new Date();
-  const connectorStatus = chargingStation.getConnectorStatus(connectorId)!;
+  const debugLogMsg = `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profiles limit found: %j`
+  const currentDate = new Date()
+  const connectorStatus = chargingStation.getConnectorStatus(connectorId)
+  let previousActiveChargingProfile: ChargingProfile | undefined
   for (const chargingProfile of chargingProfiles) {
-    const chargingSchedule = chargingProfile.chargingSchedule;
-    if (isNullOrUndefined(chargingSchedule?.startSchedule) && connectorStatus?.transactionStarted) {
+    const chargingSchedule = chargingProfile.chargingSchedule
+    if (chargingSchedule.startSchedule == null) {
       logger.debug(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date`,
-      );
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date`
+      )
       // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
-      chargingSchedule.startSchedule = connectorStatus?.transactionStart;
+      chargingSchedule.startSchedule = connectorStatus?.transactionStart
     }
-    if (
-      !isNullOrUndefined(chargingSchedule?.startSchedule) &&
-      !isDate(chargingSchedule?.startSchedule)
-    ) {
+    if (!isDate(chargingSchedule.startSchedule)) {
       logger.warn(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance`,
-      );
-      chargingSchedule.startSchedule = convertToDate(chargingSchedule?.startSchedule)!;
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance`
+      )
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!
     }
-    if (
-      !isNullOrUndefined(chargingSchedule?.startSchedule) &&
-      isNullOrUndefined(chargingSchedule?.duration)
-    ) {
+    if (chargingSchedule.duration == null) {
       logger.debug(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed`,
-      );
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed`
+      )
       // OCPP specifies that if duration is not defined, it should be infinite
-      chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule!);
+      chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule)
     }
-    if (!prepareChargingProfileKind(connectorStatus, chargingProfile, currentDate, logPrefix)) {
-      continue;
+    if (
+      !prepareChargingProfileKind(
+        connectorStatus,
+        chargingProfile,
+        currentDate,
+        chargingStation.logPrefix()
+      )
+    ) {
+      continue
     }
-    if (!canProceedChargingProfile(chargingProfile, currentDate, logPrefix)) {
-      continue;
+    if (!canProceedChargingProfile(chargingProfile, currentDate, chargingStation.logPrefix())) {
+      continue
     }
     // Check if the charging profile is active
     if (
       isWithinInterval(currentDate, {
-        start: chargingSchedule.startSchedule!,
-        end: addSeconds(chargingSchedule.startSchedule!, chargingSchedule.duration!),
+        start: chargingSchedule.startSchedule,
+        end: addSeconds(chargingSchedule.startSchedule, chargingSchedule.duration)
       })
     ) {
       if (isNotEmptyArray(chargingSchedule.chargingSchedulePeriod)) {
         const chargingSchedulePeriodCompareFn = (
           a: ChargingSchedulePeriod,
-          b: ChargingSchedulePeriod,
-        ) => a.startPeriod - b.startPeriod;
+          b: ChargingSchedulePeriod
+        ): number => a.startPeriod - b.startPeriod
         if (
           !isArraySorted<ChargingSchedulePeriod>(
             chargingSchedule.chargingSchedulePeriod,
-            chargingSchedulePeriodCompareFn,
+            chargingSchedulePeriodCompareFn
           )
         ) {
           logger.warn(
-            `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} schedule periods are not sorted by start period`,
-          );
-          chargingSchedule.chargingSchedulePeriod.sort(chargingSchedulePeriodCompareFn);
+            `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} schedule periods are not sorted by start period`
+          )
+          chargingSchedule.chargingSchedulePeriod.sort(chargingSchedulePeriodCompareFn)
         }
         // Check if the first schedule period startPeriod property is equal to 0
         if (chargingSchedule.chargingSchedulePeriod[0].startPeriod !== 0) {
           logger.error(
-            `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} first schedule period start period ${chargingSchedule.chargingSchedulePeriod[0].startPeriod} is not equal to 0`,
-          );
-          continue;
+            `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} first schedule period start period ${chargingSchedule.chargingSchedulePeriod[0].startPeriod} is not equal to 0`
+          )
+          continue
         }
         // Handle only one schedule period
         if (chargingSchedule.chargingSchedulePeriod.length === 1) {
-          const result: ChargingProfilesLimit = {
+          const chargingProfilesLimit: ChargingProfilesLimit = {
             limit: chargingSchedule.chargingSchedulePeriod[0].limit,
-            chargingProfile,
-          };
-          logger.debug(debugLogMsg, result);
-          return result;
+            chargingProfile
+          }
+          logger.debug(debugLogMsg, chargingProfilesLimit)
+          return chargingProfilesLimit
         }
-        let previousChargingSchedulePeriod: ChargingSchedulePeriod | undefined;
+        let previousChargingSchedulePeriod: ChargingSchedulePeriod | undefined
         // Search for the right schedule period
         for (const [
           index,
-          chargingSchedulePeriod,
+          chargingSchedulePeriod
         ] of chargingSchedule.chargingSchedulePeriod.entries()) {
           // Find the right schedule period
           if (
             isAfter(
-              addSeconds(chargingSchedule.startSchedule!, chargingSchedulePeriod.startPeriod),
-              currentDate,
+              addSeconds(chargingSchedule.startSchedule, chargingSchedulePeriod.startPeriod),
+              currentDate
             )
           ) {
             // Found the schedule period: previous is the correct one
-            const result: ChargingProfilesLimit = {
-              limit: previousChargingSchedulePeriod!.limit,
-              chargingProfile,
-            };
-            logger.debug(debugLogMsg, result);
-            return result;
+            const chargingProfilesLimit: ChargingProfilesLimit = {
+              limit: previousChargingSchedulePeriod?.limit ?? chargingSchedulePeriod.limit,
+              chargingProfile: previousActiveChargingProfile ?? chargingProfile
+            }
+            logger.debug(debugLogMsg, chargingProfilesLimit)
+            return chargingProfilesLimit
           }
-          // Keep a reference to previous one
-          previousChargingSchedulePeriod = chargingSchedulePeriod;
           // Handle the last schedule period within the charging profile duration
           if (
             index === chargingSchedule.chargingSchedulePeriod.length - 1 ||
             (index < chargingSchedule.chargingSchedulePeriod.length - 1 &&
               differenceInSeconds(
                 addSeconds(
-                  chargingSchedule.startSchedule!,
-                  chargingSchedule.chargingSchedulePeriod[index + 1].startPeriod,
+                  chargingSchedule.startSchedule,
+                  chargingSchedule.chargingSchedulePeriod[index + 1].startPeriod
                 ),
-                chargingSchedule.startSchedule!,
-              ) > chargingSchedule.duration!)
+                chargingSchedule.startSchedule
+              ) > chargingSchedule.duration)
           ) {
-            const result: ChargingProfilesLimit = {
-              limit: previousChargingSchedulePeriod.limit,
-              chargingProfile,
-            };
-            logger.debug(debugLogMsg, result);
-            return result;
+            const chargingProfilesLimit: ChargingProfilesLimit = {
+              limit: chargingSchedulePeriod.limit,
+              chargingProfile
+            }
+            logger.debug(debugLogMsg, chargingProfilesLimit)
+            return chargingProfilesLimit
           }
+          // Keep a reference to previous charging schedule period
+          previousChargingSchedulePeriod = chargingSchedulePeriod
         }
       }
+      // Keep a reference to previous active charging profile
+      previousActiveChargingProfile = chargingProfile
     }
   }
-};
+}
 
 export const prepareChargingProfileKind = (
-  connectorStatus: ConnectorStatus,
+  connectorStatus: ConnectorStatus | undefined,
   chargingProfile: ChargingProfile,
-  currentDate: Date,
-  logPrefix: string,
+  currentDate: string | number | Date,
+  logPrefix: string
 ): boolean => {
   switch (chargingProfile.chargingProfileKind) {
     case ChargingProfileKindType.RECURRING:
       if (!canProceedRecurringChargingProfile(chargingProfile, logPrefix)) {
-        return false;
+        return false
       }
-      prepareRecurringChargingProfile(chargingProfile, currentDate, logPrefix);
-      break;
+      prepareRecurringChargingProfile(chargingProfile, currentDate, logPrefix)
+      break
     case ChargingProfileKindType.RELATIVE:
-      if (!isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule)) {
+      if (chargingProfile.chargingSchedule.startSchedule != null) {
         logger.warn(
-          `${logPrefix} ${moduleName}.prepareChargingProfileKind: Relative charging profile id ${chargingProfile.chargingProfileId} has a startSchedule property defined. It will be ignored or used if the connector has a transaction started`,
-        );
-        delete chargingProfile.chargingSchedule.startSchedule;
+          `${logPrefix} ${moduleName}.prepareChargingProfileKind: Relative charging profile id ${chargingProfile.chargingProfileId} has a startSchedule property defined. It will be ignored or used if the connector has a transaction started`
+        )
+        delete chargingProfile.chargingSchedule.startSchedule
       }
-      if (connectorStatus?.transactionStarted) {
-        chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart;
+      if (connectorStatus?.transactionStarted === true) {
+        chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart
       }
-      // FIXME: Handle relative charging profile duration
-      break;
+      // FIXME: handle relative charging profile duration
+      break
   }
-  return true;
-};
+  return true
+}
 
 export const canProceedChargingProfile = (
   chargingProfile: ChargingProfile,
-  currentDate: Date,
-  logPrefix: string,
+  currentDate: string | number | Date,
+  logPrefix: string
 ): boolean => {
   if (
-    (isValidTime(chargingProfile.validFrom) && isBefore(currentDate, chargingProfile.validFrom!)) ||
-    (isValidTime(chargingProfile.validTo) && isAfter(currentDate, chargingProfile.validTo!))
+    (isValidDate(chargingProfile.validFrom) && isBefore(currentDate, chargingProfile.validFrom)) ||
+    (isValidDate(chargingProfile.validTo) && isAfter(currentDate, chargingProfile.validTo))
   ) {
     logger.debug(
       `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${
         chargingProfile.chargingProfileId
-      } is not valid for the current date ${currentDate.toISOString()}`,
-    );
-    return false;
+      } is not valid for the current date ${
+        isDate(currentDate) ? currentDate.toISOString() : currentDate
+      }`
+    )
+    return false
   }
   if (
-    isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) ||
-    isNullOrUndefined(chargingProfile.chargingSchedule.duration)
+    chargingProfile.chargingSchedule.startSchedule == null ||
+    chargingProfile.chargingSchedule.duration == null
   ) {
     logger.error(
-      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule or duration defined`,
-    );
-    return false;
+      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule or duration defined`
+    )
+    return false
   }
-  if (
-    !isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) &&
-    !isValidTime(chargingProfile.chargingSchedule.startSchedule)
-  ) {
+  if (!isValidDate(chargingProfile.chargingSchedule.startSchedule)) {
     logger.error(
-      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has an invalid startSchedule date defined`,
-    );
-    return false;
+      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has an invalid startSchedule date defined`
+    )
+    return false
   }
-  if (
-    !isNullOrUndefined(chargingProfile.chargingSchedule.duration) &&
-    !Number.isSafeInteger(chargingProfile.chargingSchedule.duration)
-  ) {
+  if (!Number.isSafeInteger(chargingProfile.chargingSchedule.duration)) {
     logger.error(
-      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has non integer duration defined`,
-    );
-    return false;
+      `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has non integer duration defined`
+    )
+    return false
   }
-  return true;
-};
+  return true
+}
 
 const canProceedRecurringChargingProfile = (
   chargingProfile: ChargingProfile,
-  logPrefix: string,
+  logPrefix: string
 ): boolean => {
   if (
     chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING &&
-    isNullOrUndefined(chargingProfile.recurrencyKind)
+    chargingProfile.recurrencyKind == null
   ) {
     logger.error(
-      `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no recurrencyKind defined`,
-    );
-    return false;
+      `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no recurrencyKind defined`
+    )
+    return false
   }
   if (
     chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING &&
-    isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule)
+    chargingProfile.chargingSchedule.startSchedule == null
   ) {
     logger.error(
-      `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined`,
-    );
-    return false;
+      `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined`
+    )
+    return false
   }
-  return true;
-};
+  return true
+}
 
 /**
  * Adjust recurring charging profile startSchedule to the current recurrency time interval if needed
@@ -1009,80 +1161,87 @@ const canProceedRecurringChargingProfile = (
  */
 const prepareRecurringChargingProfile = (
   chargingProfile: ChargingProfile,
-  currentDate: Date,
-  logPrefix: string,
+  currentDate: string | number | Date,
+  logPrefix: string
 ): boolean => {
-  const chargingSchedule = chargingProfile.chargingSchedule;
-  let recurringIntervalTranslated = false;
-  let recurringInterval: Interval;
+  const chargingSchedule = chargingProfile.chargingSchedule
+  let recurringIntervalTranslated = false
+  let recurringInterval: Interval | undefined
   switch (chargingProfile.recurrencyKind) {
     case RecurrencyKindType.DAILY:
       recurringInterval = {
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         start: chargingSchedule.startSchedule!,
-        end: addDays(chargingSchedule.startSchedule!, 1),
-      };
-      checkRecurringChargingProfileDuration(chargingProfile, recurringInterval, logPrefix);
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        end: addDays(chargingSchedule.startSchedule!, 1)
+      }
+      checkRecurringChargingProfileDuration(chargingProfile, recurringInterval, logPrefix)
       if (
         !isWithinInterval(currentDate, recurringInterval) &&
         isBefore(recurringInterval.end, currentDate)
       ) {
         chargingSchedule.startSchedule = addDays(
           recurringInterval.start,
-          differenceInDays(currentDate, recurringInterval.start),
-        );
+          differenceInDays(currentDate, recurringInterval.start)
+        )
         recurringInterval = {
           start: chargingSchedule.startSchedule,
-          end: addDays(chargingSchedule.startSchedule, 1),
-        };
-        recurringIntervalTranslated = true;
+          end: addDays(chargingSchedule.startSchedule, 1)
+        }
+        recurringIntervalTranslated = true
       }
-      break;
+      break
     case RecurrencyKindType.WEEKLY:
       recurringInterval = {
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         start: chargingSchedule.startSchedule!,
-        end: addWeeks(chargingSchedule.startSchedule!, 1),
-      };
-      checkRecurringChargingProfileDuration(chargingProfile, recurringInterval, logPrefix);
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        end: addWeeks(chargingSchedule.startSchedule!, 1)
+      }
+      checkRecurringChargingProfileDuration(chargingProfile, recurringInterval, logPrefix)
       if (
         !isWithinInterval(currentDate, recurringInterval) &&
         isBefore(recurringInterval.end, currentDate)
       ) {
         chargingSchedule.startSchedule = addWeeks(
           recurringInterval.start,
-          differenceInWeeks(currentDate, recurringInterval.start),
-        );
+          differenceInWeeks(currentDate, recurringInterval.start)
+        )
         recurringInterval = {
           start: chargingSchedule.startSchedule,
-          end: addWeeks(chargingSchedule.startSchedule, 1),
-        };
-        recurringIntervalTranslated = true;
+          end: addWeeks(chargingSchedule.startSchedule, 1)
+        }
+        recurringIntervalTranslated = true
       }
-      break;
+      break
     default:
       logger.error(
-        `${logPrefix} ${moduleName}.prepareRecurringChargingProfile: Recurring ${chargingProfile.recurrencyKind} charging profile id ${chargingProfile.chargingProfileId} is not supported`,
-      );
+        `${logPrefix} ${moduleName}.prepareRecurringChargingProfile: Recurring ${chargingProfile.recurrencyKind} charging profile id ${chargingProfile.chargingProfileId} is not supported`
+      )
   }
+  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
   if (recurringIntervalTranslated && !isWithinInterval(currentDate, recurringInterval!)) {
     logger.error(
       `${logPrefix} ${moduleName}.prepareRecurringChargingProfile: Recurring ${
         chargingProfile.recurrencyKind
       } charging profile id ${chargingProfile.chargingProfileId} recurrency time interval [${toDate(
-        recurringInterval!.start,
+        recurringInterval?.start as Date
       ).toISOString()}, ${toDate(
-        recurringInterval!.end,
-      ).toISOString()}] has not been properly translated to current date ${currentDate.toISOString()} `,
-    );
+        recurringInterval?.end as Date
+      ).toISOString()}] has not been properly translated to current date ${
+        isDate(currentDate) ? currentDate.toISOString() : currentDate
+      } `
+    )
   }
-  return recurringIntervalTranslated;
-};
+  return recurringIntervalTranslated
+}
 
 const checkRecurringChargingProfileDuration = (
   chargingProfile: ChargingProfile,
   interval: Interval,
-  logPrefix: string,
+  logPrefix: string
 ): void => {
-  if (isNullOrUndefined(chargingProfile.chargingSchedule.duration)) {
+  if (chargingProfile.chargingSchedule.duration == null) {
     logger.warn(
       `${logPrefix} ${moduleName}.checkRecurringChargingProfileDuration: Recurring ${
         chargingProfile.chargingProfileKind
@@ -1090,12 +1249,12 @@ const checkRecurringChargingProfileDuration = (
         chargingProfile.chargingProfileId
       } duration is not defined, set it to the recurrency time interval duration ${differenceInSeconds(
         interval.end,
-        interval.start,
-      )}`,
-    );
-    chargingProfile.chargingSchedule.duration = differenceInSeconds(interval.end, interval.start);
+        interval.start
+      )}`
+    )
+    chargingProfile.chargingSchedule.duration = differenceInSeconds(interval.end, interval.start)
   } else if (
-    chargingProfile.chargingSchedule.duration! > differenceInSeconds(interval.end, interval.start)
+    chargingProfile.chargingSchedule.duration > differenceInSeconds(interval.end, interval.start)
   ) {
     logger.warn(
       `${logPrefix} ${moduleName}.checkRecurringChargingProfileDuration: Recurring ${
@@ -1104,20 +1263,20 @@ const checkRecurringChargingProfileDuration = (
         chargingProfile.chargingSchedule.duration
       } is greater than the recurrency time interval duration ${differenceInSeconds(
         interval.end,
-        interval.start,
-      )}`,
-    );
-    chargingProfile.chargingSchedule.duration = differenceInSeconds(interval.end, interval.start);
+        interval.start
+      )}`
+    )
+    chargingProfile.chargingSchedule.duration = differenceInSeconds(interval.end, interval.start)
   }
-};
+}
 
 const getRandomSerialNumberSuffix = (params?: {
-  randomBytesLength?: number;
-  upperCase?: boolean;
+  randomBytesLength?: number
+  upperCase?: boolean
 }): string => {
-  const randomSerialNumberSuffix = randomBytes(params?.randomBytesLength ?? 16).toString('hex');
-  if (params?.upperCase) {
-    return randomSerialNumberSuffix.toUpperCase();
+  const randomSerialNumberSuffix = randomBytes(params?.randomBytesLength ?? 16).toString('hex')
+  if (params?.upperCase === true) {
+    return randomSerialNumberSuffix.toUpperCase()
   }
-  return randomSerialNumberSuffix;
-};
+  return randomSerialNumberSuffix
+}