From 9cc16f3382edf2ee4fdf8d15b3292b908e9667a2 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Mon, 14 Sep 2026 20:44:38 +0200 Subject: [PATCH] Tariffs: split price list into grid and feed-in via template usages --- src/components/lists/TariffsList.astro | 28 +++++++++++++------ src/content.config.ts | 1 + src/utils/devices.ts | 7 ++++- .../bkw-dynamic-feed-in-remuneration.yaml | 1 + .../ckw-netz-home-business-dynamic.yaml | 1 + templates/nightly/de/tariff/ekz.yaml | 1 + ...itatswerke-schonau-okostrom-dynamisch.yaml | 1 + .../de/tariff/groupe-e-vario-plus.yaml | 1 + .../de/tariff/octopus-energy-germany.yaml | 1 + templates/nightly/de/tariff/ostrom.yaml | 1 + .../de/tariff/smartenergy-smartcontrol.yaml | 1 + templates/nightly/de/tariff/tibber.yaml | 1 + .../bkw-dynamic-feed-in-remuneration.yaml | 1 + .../ckw-netz-home-business-dynamic.yaml | 1 + templates/nightly/en/tariff/ekz.yaml | 1 + ...itatswerke-schonau-okostrom-dynamisch.yaml | 1 + .../en/tariff/groupe-e-vario-plus.yaml | 1 + .../en/tariff/octopus-energy-germany.yaml | 1 + templates/nightly/en/tariff/ostrom.yaml | 1 + .../en/tariff/smartenergy-smartcontrol.yaml | 1 + templates/nightly/en/tariff/tibber.yaml | 1 + 21 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/components/lists/TariffsList.astro b/src/components/lists/TariffsList.astro index 4c00d758a..f13ffa973 100644 --- a/src/components/lists/TariffsList.astro +++ b/src/components/lists/TariffsList.astro @@ -30,34 +30,44 @@ const description = ? "Dynamische Stromtarife sowie Anbieter für CO₂-, PV- und Temperaturvorhersagen." : "Dynamic electricity tariffs and CO₂, solar, and temperature forecast providers."; -function bucketFor(d: any): "price" | "co2" | "solar" | "temperature" { - const group = d.data.product.group ?? ""; - return TARIFF_GROUPS[group] ?? "price"; -} +type Bucket = "price" | "feedin" | "co2" | "solar" | "temperature"; -const buckets: Record<"price" | "co2" | "solar" | "temperature", any[]> = { +const buckets: Record = { price: [], + feedin: [], co2: [], solar: [], temperature: [], }; -for (const d of devices) buckets[bucketFor(d)].push(d); +for (const d of devices) { + const group = TARIFF_GROUPS[d.data.product.group ?? ""] ?? "price"; + if (group !== "price") { + buckets[group].push(d); + continue; + } + // price templates without usages fit both directions + const usages: string[] = d.data.usages ?? []; + if (usages.length === 0 || usages.includes("grid")) buckets.price.push(d); + if (usages.length === 0 || usages.includes("feedin")) buckets.feedin.push(d); +} const sectionLabels = lang === "de" ? { - price: { id: "price", title: "Strompreise" }, + price: { id: "price", title: "Netzbezugstarife" }, + feedin: { id: "feedin", title: "Einspeisetarife" }, co2: { id: "co2", title: "CO₂-Vorhersagen" }, solar: { id: "solar", title: "Solar-Vorhersagen" }, temperature: { id: "temperature", title: "Temperaturvorhersagen" }, } : { - price: { id: "price", title: "Electricity prices" }, + price: { id: "price", title: "Grid tariffs" }, + feedin: { id: "feedin", title: "Feed-in tariffs" }, co2: { id: "co2", title: "CO₂ forecasts" }, solar: { id: "solar", title: "Solar forecasts" }, temperature: { id: "temperature", title: "Temperature forecasts" }, }; -const sectionOrder = ["price", "co2", "solar", "temperature"] as const; +const sectionOrder = ["price", "feedin", "co2", "solar", "temperature"] as const; const headings = [ ...(lang === "de" diff --git a/src/content.config.ts b/src/content.config.ts index 4ab8de36a..f26b66069 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -73,6 +73,7 @@ const deviceSchema = z.object({ requirements: z.array(z.string()).optional(), caveats: z.array(caveatSchema).optional(), countries: z.array(z.string()).optional(), + usages: z.array(z.string()).optional(), params: z.array(paramSchema).optional(), }); diff --git a/src/utils/devices.ts b/src/utils/devices.ts index 40fd82b42..4c3827a61 100644 --- a/src/utils/devices.ts +++ b/src/utils/devices.ts @@ -56,6 +56,7 @@ export const CODE_PREAMBLES: Record = { charge: "meters:\n - name: my_charger", aux: "meters:\n - name: my_aux", price: "tariffs:\n grid:", + feedin: "tariffs:\n feedin:", co2: "tariffs:\n co2:", solar: "tariffs:\n solar:", temperature: "tariffs:\n temperature:", @@ -129,6 +130,7 @@ export interface DeviceEntry { requirements?: string[]; caveats?: Array<{ description?: string; link?: string }>; countries?: string[]; + usages?: string[]; }; } @@ -408,7 +410,10 @@ export function buildCodeBlocks( } if (type === "tariff") { const groupKey = TARIFF_GROUPS[entry.data.product.group ?? ""] ?? "price"; - const preamble = CODE_PREAMBLES[groupKey]; + const usages = entry.data.usages ?? []; + const feedinOnly = + groupKey === "price" && usages.length === 1 && usages[0] === "feedin"; + const preamble = CODE_PREAMBLES[feedinOnly ? "feedin" : groupKey]; const list = groupKey === "solar"; return render.map((r) => { const src = r.advanced ?? r.default; diff --git a/templates/nightly/de/tariff/bkw-dynamic-feed-in-remuneration.yaml b/templates/nightly/de/tariff/bkw-dynamic-feed-in-remuneration.yaml index d439d82c2..dfe75c538 100644 --- a/templates/nightly/de/tariff/bkw-dynamic-feed-in-remuneration.yaml +++ b/templates/nightly/de/tariff/bkw-dynamic-feed-in-remuneration.yaml @@ -5,6 +5,7 @@ product: description: Dynamische Abnahmevergütung group: Dynamischer Strompreis countries: ["CH"] +usages: ["feedin"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/ckw-netz-home-business-dynamic.yaml b/templates/nightly/de/tariff/ckw-netz-home-business-dynamic.yaml index 1a44ef061..6a8c23f08 100644 --- a/templates/nightly/de/tariff/ckw-netz-home-business-dynamic.yaml +++ b/templates/nightly/de/tariff/ckw-netz-home-business-dynamic.yaml @@ -5,6 +5,7 @@ product: description: Netz Home/Business dynamic group: Dynamischer Strompreis countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/ekz.yaml b/templates/nightly/de/tariff/ekz.yaml index 8a2a5a1d4..7757c3081 100644 --- a/templates/nightly/de/tariff/ekz.yaml +++ b/templates/nightly/de/tariff/ekz.yaml @@ -4,6 +4,7 @@ product: brand: EKZ group: Dynamischer Strompreis countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml b/templates/nightly/de/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml index c245f6e2f..c5aa216c4 100644 --- a/templates/nightly/de/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml +++ b/templates/nightly/de/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml @@ -5,6 +5,7 @@ product: description: Ökostrom Dynamisch group: Dynamischer Strompreis countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] description: | Ein API-Key kann unter der E-Mail-Adresse api@ews-schoenau.de erfragt werden. diff --git a/templates/nightly/de/tariff/groupe-e-vario-plus.yaml b/templates/nightly/de/tariff/groupe-e-vario-plus.yaml index 84b15713e..1796030c6 100644 --- a/templates/nightly/de/tariff/groupe-e-vario-plus.yaml +++ b/templates/nightly/de/tariff/groupe-e-vario-plus.yaml @@ -5,6 +5,7 @@ product: description: Vario Plus group: Dynamischer Strompreis countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/octopus-energy-germany.yaml b/templates/nightly/de/tariff/octopus-energy-germany.yaml index 759ad766f..6bc1cf451 100644 --- a/templates/nightly/de/tariff/octopus-energy-germany.yaml +++ b/templates/nightly/de/tariff/octopus-energy-germany.yaml @@ -5,6 +5,7 @@ product: description: Deutschland group: Dynamischer Strompreis countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/ostrom.yaml b/templates/nightly/de/tariff/ostrom.yaml index ee8bcbaa1..2f839e700 100644 --- a/templates/nightly/de/tariff/ostrom.yaml +++ b/templates/nightly/de/tariff/ostrom.yaml @@ -4,6 +4,7 @@ product: brand: Ostrom group: Dynamischer Strompreis countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] description: | Erzeuge einen 'Production Client' im Ostrom-Entwicklerportal: [developer.ostrom-api.io](https://developer.ostrom-api.io/) diff --git a/templates/nightly/de/tariff/smartenergy-smartcontrol.yaml b/templates/nightly/de/tariff/smartenergy-smartcontrol.yaml index ae3d9e100..2e43896f6 100644 --- a/templates/nightly/de/tariff/smartenergy-smartcontrol.yaml +++ b/templates/nightly/de/tariff/smartenergy-smartcontrol.yaml @@ -5,6 +5,7 @@ product: description: smartCONTROL group: Dynamischer Strompreis countries: ["AT"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/de/tariff/tibber.yaml b/templates/nightly/de/tariff/tibber.yaml index 05576c1f7..41dc95c42 100644 --- a/templates/nightly/de/tariff/tibber.yaml +++ b/templates/nightly/de/tariff/tibber.yaml @@ -4,6 +4,7 @@ product: brand: Tibber group: Dynamischer Strompreis countries: ["NO", "SE", "DE", "NL"] +usages: ["grid"] requirements: ["skiptest"] description: | Hol dir deinen API-Token aus dem Tibber-Entwicklerportal: [developer.tibber.com](https://developer.tibber.com/) diff --git a/templates/nightly/en/tariff/bkw-dynamic-feed-in-remuneration.yaml b/templates/nightly/en/tariff/bkw-dynamic-feed-in-remuneration.yaml index b80b4b570..84c59e8bd 100644 --- a/templates/nightly/en/tariff/bkw-dynamic-feed-in-remuneration.yaml +++ b/templates/nightly/en/tariff/bkw-dynamic-feed-in-remuneration.yaml @@ -5,6 +5,7 @@ product: description: Dynamic feed-in remuneration group: Dynamic electricity price countries: ["CH"] +usages: ["feedin"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/ckw-netz-home-business-dynamic.yaml b/templates/nightly/en/tariff/ckw-netz-home-business-dynamic.yaml index 39da151d5..114616a93 100644 --- a/templates/nightly/en/tariff/ckw-netz-home-business-dynamic.yaml +++ b/templates/nightly/en/tariff/ckw-netz-home-business-dynamic.yaml @@ -5,6 +5,7 @@ product: description: Netz Home/Business dynamic group: Dynamic electricity price countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/ekz.yaml b/templates/nightly/en/tariff/ekz.yaml index 461a67372..52fd37ed1 100644 --- a/templates/nightly/en/tariff/ekz.yaml +++ b/templates/nightly/en/tariff/ekz.yaml @@ -4,6 +4,7 @@ product: brand: EKZ group: Dynamic electricity price countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml b/templates/nightly/en/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml index 0fd9eb1d0..9be162889 100644 --- a/templates/nightly/en/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml +++ b/templates/nightly/en/tariff/ews-elektrizitatswerke-schonau-okostrom-dynamisch.yaml @@ -5,6 +5,7 @@ product: description: Ökostrom Dynamisch group: Dynamic electricity price countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] description: | You can request an API key at api@ews-schoenau.de diff --git a/templates/nightly/en/tariff/groupe-e-vario-plus.yaml b/templates/nightly/en/tariff/groupe-e-vario-plus.yaml index 722054a07..d61446eae 100644 --- a/templates/nightly/en/tariff/groupe-e-vario-plus.yaml +++ b/templates/nightly/en/tariff/groupe-e-vario-plus.yaml @@ -5,6 +5,7 @@ product: description: Vario Plus group: Dynamic electricity price countries: ["CH"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/octopus-energy-germany.yaml b/templates/nightly/en/tariff/octopus-energy-germany.yaml index f1ac2260a..d1f5251e1 100644 --- a/templates/nightly/en/tariff/octopus-energy-germany.yaml +++ b/templates/nightly/en/tariff/octopus-energy-germany.yaml @@ -5,6 +5,7 @@ product: description: Germany group: Dynamic electricity price countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/ostrom.yaml b/templates/nightly/en/tariff/ostrom.yaml index e832cdc28..66d0fb729 100644 --- a/templates/nightly/en/tariff/ostrom.yaml +++ b/templates/nightly/en/tariff/ostrom.yaml @@ -4,6 +4,7 @@ product: brand: Ostrom group: Dynamic electricity price countries: ["DE"] +usages: ["grid"] requirements: ["skiptest"] description: | Create a 'Production Client' in the Ostrom developer portal: [developer.ostrom-api.io](https://developer.ostrom-api.io/) diff --git a/templates/nightly/en/tariff/smartenergy-smartcontrol.yaml b/templates/nightly/en/tariff/smartenergy-smartcontrol.yaml index e676c7662..4ee0adc51 100644 --- a/templates/nightly/en/tariff/smartenergy-smartcontrol.yaml +++ b/templates/nightly/en/tariff/smartenergy-smartcontrol.yaml @@ -5,6 +5,7 @@ product: description: smartCONTROL group: Dynamic electricity price countries: ["AT"] +usages: ["grid"] requirements: ["skiptest"] render: - default: | diff --git a/templates/nightly/en/tariff/tibber.yaml b/templates/nightly/en/tariff/tibber.yaml index b67503708..9d777c61c 100644 --- a/templates/nightly/en/tariff/tibber.yaml +++ b/templates/nightly/en/tariff/tibber.yaml @@ -4,6 +4,7 @@ product: brand: Tibber group: Dynamic electricity price countries: ["NO", "SE", "DE", "NL"] +usages: ["grid"] requirements: ["skiptest"] description: | Get your API token from the Tibber developer portal: [developer.tibber.com](https://developer.tibber.com/)