From e1a8e1a524e7e0311dbd7bc64dc0c0e0f642a0a9 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Sat, 22 Nov 2025 15:01:37 +0100 Subject: [PATCH] Forecast/Planner: 4-day forecast data (#25385) --- assets/js/components/ChargingPlans/Preview.test.ts | 4 ++-- assets/js/components/ChargingPlans/Preview.vue | 2 +- assets/js/components/Forecast/Chart.vue | 2 +- assets/js/components/Forecast/Details.vue | 2 +- assets/js/components/Tariff/SmartTariffBase.vue | 2 +- tests/battery-settings-co2.spec.ts | 3 ++- tests/battery-settings.spec.ts | 2 +- tests/smart-cost.spec.ts | 2 +- tests/smart-feedin.spec.ts | 4 ++-- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/assets/js/components/ChargingPlans/Preview.test.ts b/assets/js/components/ChargingPlans/Preview.test.ts index ebce237e8..edbe1c5dc 100644 --- a/assets/js/components/ChargingPlans/Preview.test.ts +++ b/assets/js/components/ChargingPlans/Preview.test.ts @@ -39,8 +39,8 @@ describe("basics", () => { result = wrapper.vm.slots; }); - test("should return 39 slots", () => { - expect(result.length).eq(192); + test("should return 384 slots", () => { + expect(result.length).eq(384); }); test("slots should be an hour apart", () => { diff --git a/assets/js/components/ChargingPlans/Preview.vue b/assets/js/components/ChargingPlans/Preview.vue index dc7f02304..46c9bc351 100644 --- a/assets/js/components/ChargingPlans/Preview.vue +++ b/assets/js/components/ChargingPlans/Preview.vue @@ -144,7 +144,7 @@ export default defineComponent({ base.setSeconds(0, 0); base.setMinutes(base.getMinutes() - (base.getMinutes() % 15)); - return Array.from({ length: 48 * 4 }, (_, i) => { + return Array.from({ length: 96 * 4 }, (_, i) => { const start = new Date(base.getTime() + quarterHour * i); const end = new Date(start.getTime() + quarterHour); const charging = !!this.findSlotInRange(start, end, plan); diff --git a/assets/js/components/Forecast/Chart.vue b/assets/js/components/Forecast/Chart.vue index 24b91a002..8ad7f142d 100644 --- a/assets/js/components/Forecast/Chart.vue +++ b/assets/js/components/Forecast/Chart.vue @@ -85,7 +85,7 @@ export default defineComponent({ computed: { endDate() { const end = new Date(this.startDate); - end.setHours(end.getHours() + 48); + end.setHours(end.getHours() + 96); return end; }, solarEntries() { diff --git a/assets/js/components/Forecast/Details.vue b/assets/js/components/Forecast/Details.vue index 276606219..f334a0aac 100644 --- a/assets/js/components/Forecast/Details.vue +++ b/assets/js/components/Forecast/Details.vue @@ -71,7 +71,7 @@ import { ForecastType, findLowestSumSlotIndex } from "@/utils/forecast"; import type { ForecastSlot, SolarDetails } from "./types"; const LOCALES_WITHOUT_DAY_AFTER_TOMORROW = ["en", "tr"]; -const FORECASTED_HOURS = 48; +const FORECASTED_HOURS = 96; const SLOTS_PER_HOUR = 4; export interface Energy { diff --git a/assets/js/components/Tariff/SmartTariffBase.vue b/assets/js/components/Tariff/SmartTariffBase.vue index 995a4369a..de3af6cde 100644 --- a/assets/js/components/Tariff/SmartTariffBase.vue +++ b/assets/js/components/Tariff/SmartTariffBase.vue @@ -216,7 +216,7 @@ export default defineComponent({ base.setSeconds(0, 0); base.setMinutes(base.getMinutes() - (base.getMinutes() % 15)); - return Array.from({ length: 48 * 4 }, (_, i) => { + return Array.from({ length: 96 * 4 }, (_, i) => { const start = new Date(base.getTime() + quarterHour * i); const end = new Date(start.getTime() + quarterHour); const value = this.findRateInRange(start, end, rates)?.value; diff --git a/tests/battery-settings-co2.spec.ts b/tests/battery-settings-co2.spec.ts index 7758056cf..72ad7aa24 100644 --- a/tests/battery-settings-co2.spec.ts +++ b/tests/battery-settings-co2.spec.ts @@ -21,7 +21,8 @@ test.describe("battery settings co2", async () => { await modal.getByRole("link", { name: "Grid charging" }).click(); await modal.getByLabel("Enable limit").check(); await modal.getByLabel("CO₂ limit").selectOption({ label: "≤ 150 g/kWh" }); - await expect(modal.getByTestId("active-hours")).toHaveText(["Active time", "48 hr"].join("")); + // CO2 demo tariff provides 72 hours, so active hours vary by test execution time + await expect(modal.getByTestId("active-hours").locator(".value")).toHaveText(/^\d+ hr/); await expect(modal).toContainText("20 g – 150 g"); await page.getByRole("button", { name: "Close" }).click(); await expectModalHidden(modal); diff --git a/tests/battery-settings.spec.ts b/tests/battery-settings.spec.ts index 4c4b83922..dcb708ca4 100644 --- a/tests/battery-settings.spec.ts +++ b/tests/battery-settings.spec.ts @@ -49,7 +49,7 @@ test.describe("battery settings", async () => { await modal.getByRole("link", { name: "Grid charging" }).click(); await modal.getByLabel("Enable limit").check(); await modal.getByLabel("Price limit").selectOption({ label: "≤ 50.0 ct/kWh" }); - await expect(modal.getByTestId("active-hours")).toHaveText(["Active time", "48 hr"].join("")); + await expect(modal.getByTestId("active-hours")).toHaveText(["Active time", "96 hr"].join("")); await expect(modal).toContainText("5.0 ct – 50.0 ct"); await page.getByRole("button", { name: "Close" }).click(); await expectModalHidden(modal); diff --git a/tests/smart-cost.spec.ts b/tests/smart-cost.spec.ts index 32e38f3ac..f9efe8d53 100644 --- a/tests/smart-cost.spec.ts +++ b/tests/smart-cost.spec.ts @@ -42,7 +42,7 @@ test.describe("smart cost limit", async () => { await expect(modal).toBeVisible(); await modal.getByLabel("Enable limit").check(); await modal.getByLabel("Price limit").selectOption("≤ 40.0 ct/kWh"); - await expect(modal.getByTestId("active-hours")).toHaveText(["Active time", "48 hr"].join("")); + await expect(modal.getByTestId("active-hours")).toHaveText(["Active time", "96 hr"].join("")); await modal.getByLabel("Close").click(); await expect(modal).not.toBeVisible(); await expect(page.getByTestId("vehicle-status-charger")).toHaveText("Charging…"); diff --git a/tests/smart-feedin.spec.ts b/tests/smart-feedin.spec.ts index 6ec39d647..dc3ed6bd2 100644 --- a/tests/smart-feedin.spec.ts +++ b/tests/smart-feedin.spec.ts @@ -31,7 +31,7 @@ test.describe("smart feed-in priority", async () => { await expectModalVisible(modal); await modal.getByLabel("Enable limit").check(); await modal.getByLabel("Feed-in limit").selectOption("≥ 10.0 ct/kWh"); - await expect(modal.getByTestId("active-hours")).toHaveText(["Paused time", "48 hr"].join("")); + await expect(modal.getByTestId("active-hours")).toHaveText(["Paused time", "96 hr"].join("")); await modal.getByLabel("Close").click(); await expectModalHidden(modal); @@ -59,7 +59,7 @@ test.describe("smart feed-in priority", async () => { await expectModalVisible(modal1); await modal1.getByLabel("Enable limit").check(); await modal1.getByLabel("Feed-in limit").selectOption("≥ 10.0 ct/kWh"); - await expect(modal1.getByTestId("active-hours")).toHaveText(["Paused time", "48 hr"].join("")); + await expect(modal1.getByTestId("active-hours")).toHaveText(["Paused time", "96 hr"].join("")); await modal1.getByRole("button", { name: "Apply everywhere?" }).click(); await modal1.getByLabel("Close").click(); await expectModalHidden(modal1);