evcc-io/assets/js/utils/tariffSlots.ts
Michael Geers a4ed1080e1
Config UI: add tariffs (#26698)
Co-authored-by: Maschga <88616799+Maschga@users.noreply.github.com>
Co-authored-by: andig <cpuidle@gmail.com>
Co-authored-by: andig <andi@evcc.io>
2026-03-01 11:06:34 +00:00

64 lines
2 KiB
TypeScript

import type { Rate, Slot } from "../types/evcc";
export function calculateCostRange(slots: Slot[]): {
min: number | undefined;
max: number | undefined;
} {
let min = undefined as number | undefined;
let max = undefined as number | undefined;
slots.forEach((slot) => {
if (slot.value === undefined) return;
min = min === undefined ? slot.value : Math.min(min, slot.value);
max = max === undefined ? slot.value : Math.max(max, slot.value);
});
return { min, max };
}
export function findRateInRange(start: Date, end: Date, rates: Rate[]): Rate | undefined {
return rates.find((r) => {
if (r.start.getTime() < start.getTime()) {
return r.end.getTime() > start.getTime();
}
return r.start.getTime() < end.getTime();
});
}
export function generateRateSlots(
rates: Rate[],
weekdayFormatter: (date: Date) => string,
isCharging?: (value: number | undefined, start: Date, end: Date) => boolean,
isWarning?: (value: number | undefined, start: Date, end: Date) => boolean
): Slot[] {
if (!rates?.length) {
return [];
}
const quarterHour = 15 * 60 * 1000;
const base = new Date();
base.setSeconds(0, 0);
base.setMinutes(base.getMinutes() - (base.getMinutes() % 15));
// Create slots for the duration of the rates
const lastRate = rates[rates.length - 1]!;
const duration = Math.ceil((lastRate.end.getTime() - base.getTime()) / quarterHour);
return Array.from({ length: Math.min(duration, 96 * 4) }, (_, i) => {
const start = new Date(base.getTime() + quarterHour * i);
const end = new Date(start.getTime() + quarterHour);
const value = findRateInRange(start, end, rates)?.value;
const charging = isCharging ? isCharging(value, start, end) : false;
const warning = isWarning ? isWarning(value, start, end) : false;
const selectable = value !== undefined;
return {
day: weekdayFormatter(start),
value,
start,
end,
charging,
selectable,
warning,
};
});
}