Tariffs: add outdoor temperature type and OpenMeteo (#27780)

Co-authored-by: Michael Geers <michael@geers.tv>
This commit is contained in:
Daniel Martin 2026-07-17 14:54:56 +02:00 • committed by GitHub
parent 68db0b7727
commit d68e5e5809
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 449 additions and 135 deletions

View file

@ -104,6 +104,9 @@ grid:
"-10.0 öre",
"Grid CO₂",
"300 g",
"Solar forecast",
"Outdoor temperature",
"15.5°C",
].join("")
);
});
@ -117,6 +120,7 @@ grid:
const tariffFeedin = page.getByTestId("tariff-feedIn");
const tariffCo2 = page.getByTestId("tariff-co2");
const tariffSolar = page.getByTestId("tariff-solar");
const tariffTemperature = page.getByTestId("tariff-temperature");
const tariffPlanner = page.getByTestId("tariff-planner");
const addTariff = page.getByRole("button", { name: "Add tariff" });
const addForecast = page.getByRole("button", { name: "Add forecast" });
@ -126,6 +130,9 @@ grid:
const addGridExport = modal.getByRole("button", { name: "Add grid export tariff" });
const addCo2Forecast = modal.getByRole("button", { name: "Add CO₂ forecast" });
const addSolarForecast = modal.getByRole("button", { name: "Add solar forecast" });
const addTemperatureForecast = modal.getByRole("button", {
name: "Add temperature forecast",
});
const addPlannerForecast = modal.getByRole("button", { name: "Add planner forecast" });
const save = modal.getByRole("button", { name: "Validate & save" });
@ -184,11 +191,22 @@ grid:
await expectModalHidden(modal);
await expect(tariffSolar.nth(1)).toContainText("Roof West");
// create temperature forecast
await addForecast.click();
await expectModalVisible(modal);
await addTemperatureForecast.click();
await modal.getByLabel("Provider").selectOption("Demo Temperature Forecast");
await save.click();
await expectModalHidden(modal);
await expect(tariffTemperature).toContainText("Outdoor temperature");
await expect(tariffTemperature).toContainText(["Forecast", "10.0°C – 20.0°C"].join(""));
// create planner forecast
await addForecast.click();
await expectModalVisible(modal);
// co2 already exists, should not be offered
// co2 and temperature already exist, should not be offered
await expect(addCo2Forecast).not.toBeVisible();
await expect(addTemperatureForecast).not.toBeVisible();
await expect(addSolarForecast).toBeVisible();
await expect(addPlannerForecast).toBeVisible();
await addPlannerForecast.click();
@ -214,12 +232,16 @@ grid:
await expect(tariffSolar).toHaveCount(2);
await expect(tariffSolar.nth(0)).toContainText("Roof South");
await expect(tariffSolar.nth(1)).toContainText("Roof West");
await expect(tariffTemperature).toBeVisible();
await expect(tariffTemperature).toContainText("Outdoor temperature");
await expect(tariffPlanner).toBeVisible();
await expect(tariffPlanner).toContainText("Price");
// delete all in reverse order
await deleteTariff(modal, tariffPlanner);
await expect(tariffPlanner).toHaveCount(0);
await deleteTariff(modal, tariffTemperature);
await expect(tariffTemperature).toHaveCount(0);
await deleteTariff(modal, tariffSolar, 1);
await expect(tariffSolar).toHaveCount(1);
await deleteTariff(modal, tariffSolar, 0);
@ -235,6 +257,12 @@ grid:
// final state: both add buttons visible again
await expect(addTariff).toBeVisible();
await expect(addForecast).toBeVisible();
// deletes must not leave stale refs behind that break the next start
await restart();
await page.reload();
await expect(addTariff).toBeVisible();
await expect(addForecast).toBeVisible();
});
test("currency change", async ({ page }) => {

View file

@ -51,3 +51,19 @@ tariffs:
co2:
type: fixed
price: 300
temperature:
type: custom
tariff: temperature
forecast:
source: js
script: |
var now = Date.now();
var rates = [];
for (var i = 0; i < 48; i++) {
rates.push({
start: new Date(now + i * 3600000).toISOString(),
end: new Date(now + (i + 1) * 3600000).toISOString(),
value: 15.5
});
}
JSON.stringify(rates);