+ private static composeChargingSchedule = (
+ chargingSchedule: OCPP16ChargingSchedule,
+ targetInterval: Interval,
+ ): OCPP16ChargingSchedule | undefined => {
+ const chargingScheduleInterval: Interval = {
+ start: chargingSchedule.startSchedule!,
+ end: addSeconds(chargingSchedule.startSchedule!, chargingSchedule.duration!),
+ };
+ if (areIntervalsOverlapping(chargingScheduleInterval, targetInterval)) {
+ chargingSchedule.chargingSchedulePeriod.sort((a, b) => a.startPeriod - b.startPeriod);
+ if (isBefore(chargingScheduleInterval.start, targetInterval.start)) {
+ return {
+ ...chargingSchedule,
+ startSchedule: targetInterval.start as Date,
+ duration: differenceInSeconds(chargingScheduleInterval.end, targetInterval.start as Date),
+ chargingSchedulePeriod: chargingSchedule.chargingSchedulePeriod.filter(
+ (schedulePeriod, index) => {
+ if (
+ isWithinInterval(
+ addSeconds(chargingScheduleInterval.start, schedulePeriod.startPeriod)!,
+ targetInterval,
+ )
+ ) {
+ return true;
+ }
+ if (
+ index < chargingSchedule.chargingSchedulePeriod.length - 1 &&
+ !isWithinInterval(
+ addSeconds(chargingScheduleInterval.start, schedulePeriod.startPeriod),
+ targetInterval,
+ ) &&
+ isWithinInterval(
+ addSeconds(
+ chargingScheduleInterval.start,
+ chargingSchedule.chargingSchedulePeriod[index + 1].startPeriod,
+ ),
+ targetInterval,
+ )
+ ) {
+ schedulePeriod.startPeriod = 0;
+ return true;
+ }
+ return false;
+ },
+ ),
+ };
+ }
+ if (isAfter(chargingScheduleInterval.end, targetInterval.end)) {
+ return {
+ ...chargingSchedule,
+ duration: differenceInSeconds(targetInterval.end as Date, chargingScheduleInterval.start),
+ chargingSchedulePeriod: chargingSchedule.chargingSchedulePeriod.filter((schedulePeriod) =>
+ isWithinInterval(
+ addSeconds(chargingScheduleInterval.start, schedulePeriod.startPeriod)!,
+ targetInterval,
+ ),
+ ),
+ };
+ }
+ return chargingSchedule;
+ }
+ };
+