addWeeks,
differenceInDays,
differenceInWeeks,
- endOfDay,
- endOfWeek,
isAfter,
isBefore,
isWithinInterval,
- startOfDay,
- startOfWeek,
+ toDate,
} from 'date-fns';
import type { ChargingStation } from './ChargingStation';
isNotEmptyString,
isNullOrUndefined,
isUndefined,
+ isValidDate,
logger,
secureRandom,
} from '../utils';
): ChargingProfilesLimit | undefined => {
const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`;
const currentDate = new Date();
+ const connectorStatus = chargingStation.getConnectorStatus(connectorId);
for (const chargingProfile of chargingProfiles) {
if (
- chargingProfile.validFrom &&
- chargingProfile.validTo &&
+ isValidDate(chargingProfile.validFrom) &&
+ isValidDate(chargingProfile.validTo) &&
!isWithinInterval(currentDate, {
- start: chargingProfile.validFrom,
- end: chargingProfile.validTo,
+ start: chargingProfile.validFrom!,
+ end: chargingProfile.validTo!,
})
) {
logger.debug(
continue;
}
const chargingSchedule = chargingProfile.chargingSchedule;
- if (!chargingSchedule?.startSchedule) {
+ if (connectorStatus?.transactionStarted && !chargingSchedule?.startSchedule) {
logger.debug(
`${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not defined in charging profile id ${chargingProfile.chargingProfileId}. Trying to set it to the connector transaction start date`,
);
// OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
- chargingSchedule.startSchedule =
- chargingStation.getConnectorStatus(connectorId)?.transactionStart;
+ chargingSchedule.startSchedule = connectorStatus?.transactionStart;
}
if (!(chargingSchedule?.startSchedule instanceof Date)) {
logger.warn(
);
continue;
}
- // Adjust recurring start schedule
if (chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING) {
- switch (chargingProfile.recurrencyKind) {
- case RecurrencyKindType.DAILY:
- if (isBefore(chargingSchedule.startSchedule, startOfDay(currentDate))) {
- addDays(
- chargingSchedule.startSchedule,
- differenceInDays(chargingSchedule.startSchedule, endOfDay(currentDate)),
- );
- if (
- isBefore(chargingSchedule.startSchedule, startOfDay(currentDate)) ||
- isAfter(chargingSchedule.startSchedule, endOfDay(currentDate))
- ) {
- logger.error(
- `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Recurring ${
- chargingProfile.recurrencyKind
- } charging profile id ${
- chargingProfile.chargingProfileId
- } startSchedule ${chargingSchedule.startSchedule.toISOString()} is not properly translated to the current day`,
- );
- }
- }
- break;
- case RecurrencyKindType.WEEKLY:
- if (isBefore(chargingSchedule.startSchedule, startOfWeek(currentDate))) {
- addWeeks(
- chargingSchedule.startSchedule,
- differenceInWeeks(chargingSchedule.startSchedule, endOfWeek(currentDate)),
- );
- if (
- isBefore(chargingSchedule.startSchedule, startOfWeek(currentDate)) ||
- isAfter(chargingSchedule.startSchedule, endOfWeek(currentDate))
- ) {
- logger.error(
- `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Recurring ${
- chargingProfile.recurrencyKind
- } charging profile id ${
- chargingProfile.chargingProfileId
- } startSchedule ${chargingSchedule.startSchedule.toISOString()} is not properly translated to the current week`,
- );
- }
- }
- break;
- }
- } else if (chargingProfile.chargingProfileKind === ChargingProfileKindType.RELATIVE) {
- chargingSchedule.startSchedule =
- chargingStation.getConnectorStatus(connectorId)?.transactionStart;
+ prepareRecurringChargingProfile(chargingProfile, currentDate, logPrefix);
+ } else if (
+ chargingProfile.chargingProfileKind === ChargingProfileKindType.RELATIVE &&
+ connectorStatus?.transactionStarted
+ ) {
+ chargingSchedule.startSchedule = connectorStatus?.transactionStart;
}
// Check if the charging profile is active
if (
+ isValidDate(chargingSchedule.startSchedule) &&
isAfter(addSeconds(chargingSchedule.startSchedule!, chargingSchedule.duration!), currentDate)
) {
if (isNotEmptyArray(chargingSchedule.chargingSchedulePeriod)) {
- // Handling of only one period
+ // Handling of only one schedule period
if (
chargingSchedule.chargingSchedulePeriod.length === 1 &&
chargingSchedule.chargingSchedulePeriod[0].startPeriod === 0
currentDate,
)
) {
- // Found the schedule: last but one is the correct one
+ // Found the schedule period: last but one is the correct one
const result: ChargingProfilesLimit = {
limit: lastButOneSchedule!.limit,
matchingChargingProfile: chargingProfile,
}
};
+/**
+ * Adjust recurring charging profile startSchedule to the current recurrency time interval if needed
+ *
+ * @param chargingProfile -
+ * @param currentDate -
+ * @param logPrefix -
+ */
+const prepareRecurringChargingProfile = (
+ chargingProfile: ChargingProfile,
+ currentDate: Date,
+ logPrefix: string,
+) => {
+ const chargingSchedule = chargingProfile.chargingSchedule;
+ let recurringInterval: Interval;
+ switch (chargingProfile.recurrencyKind) {
+ case RecurrencyKindType.DAILY:
+ recurringInterval = {
+ start: chargingSchedule.startSchedule!,
+ end: addDays(chargingSchedule.startSchedule!, 1),
+ };
+ if (
+ !isWithinInterval(currentDate, recurringInterval) &&
+ isBefore(chargingSchedule.startSchedule!, currentDate)
+ ) {
+ chargingSchedule.startSchedule = addDays(
+ chargingSchedule.startSchedule!,
+ differenceInDays(chargingSchedule.startSchedule!, recurringInterval.end),
+ );
+ recurringInterval = {
+ start: chargingSchedule.startSchedule,
+ end: addDays(chargingSchedule.startSchedule, 1),
+ };
+ }
+ break;
+ case RecurrencyKindType.WEEKLY:
+ recurringInterval = {
+ start: chargingSchedule.startSchedule!,
+ end: addWeeks(chargingSchedule.startSchedule!, 1),
+ };
+ if (
+ !isWithinInterval(currentDate, recurringInterval) &&
+ isBefore(chargingSchedule.startSchedule!, currentDate)
+ ) {
+ chargingSchedule.startSchedule = addWeeks(
+ chargingSchedule.startSchedule!,
+ differenceInWeeks(chargingSchedule.startSchedule!, recurringInterval.end),
+ );
+ recurringInterval = {
+ start: chargingSchedule.startSchedule,
+ end: addWeeks(chargingSchedule.startSchedule, 1),
+ };
+ }
+ break;
+ }
+ if (!isWithinInterval(currentDate, recurringInterval!)) {
+ logger.error(
+ `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Recurring ${
+ chargingProfile.recurrencyKind
+ } charging profile id ${
+ chargingProfile.chargingProfileId
+ } startSchedule ${chargingSchedule.startSchedule!.toISOString()} is not properly translated to current recurrency time interval [${toDate(
+ recurringInterval!.start,
+ ).toISOString()}, ${toDate(recurringInterval!.end).toISOString()}]`,
+ );
+ }
+};
+
const getRandomSerialNumberSuffix = (params?: {
randomBytesLength?: number;
upperCase?: boolean;