feat(sensors): add Energy Dashboard price sensor and period duration sensors

Added dedicated sensor for Home Assistant's Energy Dashboard integration and
new sensors to track total period duration for best/peak price periods.

New Sensors:
- current_interval_price_major: Shows price in major currency (EUR/kWh, NOK/kWh)
  instead of minor units (ct/kWh, øre/kWh) for Energy Dashboard compatibility
- best_price_period_duration: Total length of current/next best price period
- peak_price_period_duration: Total length of current/next peak price period

Changes:
- sensor/definitions.py: Added 3 new sensor definitions with proper device_class,
  state_class, and suggested_display_precision
- sensor/core.py: Extended native_unit_of_measurement property to return major
  currency unit for Energy Dashboard sensor while keeping minor units for others
- sensor/core.py: Added _calc_period_duration() method to calculate period lengths
- sensor/core.py: Added handler mappings for new duration sensors
- const.py: Imported format_price_unit_major() for currency formatting
- translations/*.json: Added entity names for all 5 languages (de, en, nb, nl, sv)
- custom_translations/*.json: Added descriptions, long_descriptions, and usage_tips
  for all new sensors in all 5 languages

Technical Details:
- Energy Dashboard sensor uses 4 decimal precision (0.2534 EUR/kWh) vs 2 decimals
  for regular price sensors (25.34 ct/kWh)
- Duration sensors return minutes (UnitOfTime.MINUTES) with 0 decimal precision
- Duration sensors disabled by default (less commonly needed than end time)
- All MONETARY sensors now have explicit state_class=SensorStateClass.TOTAL
- All ENUM/TIMESTAMP sensors have explicit state_class=None for clarity

Impact: Users can now add electricity prices to Energy Dashboard for automatic
cost calculation. Duration sensors help users plan appliance usage by showing
how long cheap/expensive periods last. All price statistics now properly tracked
by Home Assistant's recorder.
This commit is contained in:
Julian Pawlowski 2025-11-15 20:38:21 +00:00
parent 9c00d985c8
commit d06ae63075
12 changed files with 264 additions and 3 deletions

View file

@ -5,6 +5,11 @@
"long_description": "Zeigt den aktuellen Preis pro kWh von deinem Tibber-Abonnement an", "long_description": "Zeigt den aktuellen Preis pro kWh von deinem Tibber-Abonnement an",
"usage_tips": "Nutze dies, um Preise zu verfolgen oder Automatisierungen zu erstellen, die bei günstigem Strom ausgeführt werden" "usage_tips": "Nutze dies, um Preise zu verfolgen oder Automatisierungen zu erstellen, die bei günstigem Strom ausgeführt werden"
}, },
"current_interval_price_major": {
"description": "Aktueller Strompreis in Hauptwährung (EUR/kWh, NOK/kWh, etc.) für Energie-Dashboard",
"long_description": "Zeigt den aktuellen Preis pro kWh in Hauptwährungseinheiten an (z.B. EUR/kWh statt ct/kWh, NOK/kWh statt øre/kWh). Dieser Sensor ist speziell für die Verwendung mit dem Energie-Dashboard von Home Assistant konzipiert, das Preise in Standard-Währungseinheiten benötigt.",
"usage_tips": "Verwende diesen Sensor beim Konfigurieren des Energie-Dashboards unter Einstellungen → Dashboards → Energie. Wähle diesen Sensor als 'Entität mit dem aktuellen Preis' aus, um deine Energiekosten automatisch zu berechnen. Das Energie-Dashboard multipliziert deinen Energieverbrauch (kWh) mit diesem Preis, um die Gesamtkosten anzuzeigen."
},
"next_interval_price": { "next_interval_price": {
"description": "Der Strompreis für das nächste 15-Minuten-Intervall pro kWh", "description": "Der Strompreis für das nächste 15-Minuten-Intervall pro kWh",
"long_description": "Zeigt den Preis für das nächste 15-Minuten-Intervall von deinem Tibber-Abonnement an", "long_description": "Zeigt den Preis für das nächste 15-Minuten-Intervall von deinem Tibber-Abonnement an",
@ -289,6 +294,11 @@
"long_description": "Zeigt den Endzeitstempel der aktuellen günstigen Periode wenn aktiv, oder das Ende der nächsten Periode wenn keine Periode aktiv ist. Zeigt immer eine nützliche Zeitreferenz zur Planung. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.", "long_description": "Zeigt den Endzeitstempel der aktuellen günstigen Periode wenn aktiv, oder das Ende der nächsten Periode wenn keine Periode aktiv ist. Zeigt immer eine nützliche Zeitreferenz zur Planung. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.",
"usage_tips": "Nutze dies, um einen Countdown wie 'Günstige Periode endet in 2 Stunden' (wenn aktiv) oder 'Nächste günstige Periode endet um 14:00' (wenn inaktiv) anzuzeigen. Home Assistant zeigt automatisch relative Zeit für Zeitstempel-Sensoren an." "usage_tips": "Nutze dies, um einen Countdown wie 'Günstige Periode endet in 2 Stunden' (wenn aktiv) oder 'Nächste günstige Periode endet um 14:00' (wenn inaktiv) anzuzeigen. Home Assistant zeigt automatisch relative Zeit für Zeitstempel-Sensoren an."
}, },
"best_price_period_duration": {
"description": "Gesamtlänge der aktuellen oder nächsten günstigen Periode in Minuten",
"long_description": "Zeigt, wie lange die günstige Periode insgesamt dauert. Während einer aktiven Periode zeigt dies die Dauer der aktuellen Periode. Wenn keine Periode aktiv ist, zeigt dies die Dauer der nächsten kommenden Periode. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.",
"usage_tips": "Nützlich für Planung: 'Die nächste günstige Periode dauert 90 Minuten' oder 'Aktuelle günstige Periode ist 120 Minuten lang'. Kombiniere mit remaining_minutes, um zu berechnen, wann langlaufende Geräte gestartet werden sollten."
},
"best_price_remaining_minutes": { "best_price_remaining_minutes": {
"description": "Verbleibende Minuten in aktueller günstiger Periode (0 wenn inaktiv)", "description": "Verbleibende Minuten in aktueller günstiger Periode (0 wenn inaktiv)",
"long_description": "Zeigt, wie viele Minuten in der aktuellen günstigen Periode noch verbleiben. Gibt 0 zurück, wenn keine Periode aktiv ist. Aktualisiert sich jede Minute. Prüfe binary_sensor.best_price_period um zu sehen, ob eine Periode aktuell aktiv ist.", "long_description": "Zeigt, wie viele Minuten in der aktuellen günstigen Periode noch verbleiben. Gibt 0 zurück, wenn keine Periode aktiv ist. Aktualisiert sich jede Minute. Prüfe binary_sensor.best_price_period um zu sehen, ob eine Periode aktuell aktiv ist.",
@ -314,6 +324,11 @@
"long_description": "Zeigt den Endzeitstempel der aktuellen teuren Periode wenn aktiv, oder das Ende der nächsten Periode wenn keine Periode aktiv ist. Zeigt immer eine nützliche Zeitreferenz zur Planung. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.", "long_description": "Zeigt den Endzeitstempel der aktuellen teuren Periode wenn aktiv, oder das Ende der nächsten Periode wenn keine Periode aktiv ist. Zeigt immer eine nützliche Zeitreferenz zur Planung. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.",
"usage_tips": "Nutze dies, um 'Teure Periode endet in 1 Stunde' (wenn aktiv) oder 'Nächste teure Periode endet um 18:00' (wenn inaktiv) anzuzeigen. Kombiniere mit Automatisierungen, um Betrieb nach Spitze fortzusetzen." "usage_tips": "Nutze dies, um 'Teure Periode endet in 1 Stunde' (wenn aktiv) oder 'Nächste teure Periode endet um 18:00' (wenn inaktiv) anzuzeigen. Kombiniere mit Automatisierungen, um Betrieb nach Spitze fortzusetzen."
}, },
"peak_price_period_duration": {
"description": "Gesamtlänge der aktuellen oder nächsten teuren Periode in Minuten",
"long_description": "Zeigt, wie lange die teure Periode insgesamt dauert. Während einer aktiven Periode zeigt dies die Dauer der aktuellen Periode. Wenn keine Periode aktiv ist, zeigt dies die Dauer der nächsten kommenden Periode. Gibt nur 'Unbekannt' zurück, wenn keine Perioden konfiguriert sind.",
"usage_tips": "Nützlich für Planung: 'Die nächste teure Periode dauert 60 Minuten' oder 'Aktuelle Spitze ist 90 Minuten lang'. Kombiniere mit remaining_minutes, um zu entscheiden, ob die Spitze abgewartet oder der Betrieb fortgesetzt werden soll."
},
"peak_price_remaining_minutes": { "peak_price_remaining_minutes": {
"description": "Verbleibende Minuten in aktueller teurer Periode (0 wenn inaktiv)", "description": "Verbleibende Minuten in aktueller teurer Periode (0 wenn inaktiv)",
"long_description": "Zeigt, wie viele Minuten in der aktuellen teuren Periode noch verbleiben. Gibt 0 zurück, wenn keine Periode aktiv ist. Aktualisiert sich jede Minute. Prüfe binary_sensor.peak_price_period um zu sehen, ob eine Periode aktuell aktiv ist.", "long_description": "Zeigt, wie viele Minuten in der aktuellen teuren Periode noch verbleiben. Gibt 0 zurück, wenn keine Periode aktiv ist. Aktualisiert sich jede Minute. Prüfe binary_sensor.peak_price_period um zu sehen, ob eine Periode aktuell aktiv ist.",

View file

@ -5,6 +5,11 @@
"long_description": "Shows the current price per kWh from your Tibber subscription", "long_description": "Shows the current price per kWh from your Tibber subscription",
"usage_tips": "Use this to track prices or to create automations that run when electricity is cheap" "usage_tips": "Use this to track prices or to create automations that run when electricity is cheap"
}, },
"current_interval_price_major": {
"description": "Current electricity price in major currency (EUR/kWh, NOK/kWh, etc.) for Energy Dashboard",
"long_description": "Shows the current price per kWh in major currency units (e.g., EUR/kWh instead of ct/kWh, NOK/kWh instead of øre/kWh). This sensor is specifically designed for use with Home Assistant's Energy Dashboard, which requires prices in standard currency units.",
"usage_tips": "Use this sensor when configuring the Energy Dashboard under Settings → Dashboards → Energy. Select this sensor as the 'Entity with current price' to automatically calculate your energy costs. The Energy Dashboard multiplies your energy consumption (kWh) by this price to show total costs."
},
"next_interval_price": { "next_interval_price": {
"description": "The next interval electricity price per kWh", "description": "The next interval electricity price per kWh",
"long_description": "Shows the price for the next 15-minute interval from your Tibber subscription", "long_description": "Shows the price for the next 15-minute interval from your Tibber subscription",
@ -289,6 +294,11 @@
"long_description": "Shows the end timestamp of the current best price period when active, or the end of the next period when no period is active. Always shows a useful time reference for planning. Returns 'Unknown' only when no periods are configured.", "long_description": "Shows the end timestamp of the current best price period when active, or the end of the next period when no period is active. Always shows a useful time reference for planning. Returns 'Unknown' only when no periods are configured.",
"usage_tips": "Use this to display a countdown like 'Cheap period ends in 2 hours' (when active) or 'Next cheap period ends at 14:00' (when inactive). Home Assistant automatically shows relative time for timestamp sensors." "usage_tips": "Use this to display a countdown like 'Cheap period ends in 2 hours' (when active) or 'Next cheap period ends at 14:00' (when inactive). Home Assistant automatically shows relative time for timestamp sensors."
}, },
"best_price_period_duration": {
"description": "Total length of current or next best price period in minutes",
"long_description": "Shows how long the best price period lasts in total. During an active period, shows the duration of the current period. When no period is active, shows the duration of the next upcoming period. Returns 'Unknown' only when no periods are configured.",
"usage_tips": "Useful for planning: 'The next cheap period lasts 90 minutes' or 'Current cheap period is 120 minutes long'. Combine with remaining_minutes to calculate when to start long-running appliances."
},
"best_price_remaining_minutes": { "best_price_remaining_minutes": {
"description": "Minutes remaining in current best price period (0 when inactive)", "description": "Minutes remaining in current best price period (0 when inactive)",
"long_description": "Shows how many minutes are left in the current best price period. Returns 0 when no period is active. Updates every minute. Check binary_sensor.best_price_period to see if a period is currently active.", "long_description": "Shows how many minutes are left in the current best price period. Returns 0 when no period is active. Updates every minute. Check binary_sensor.best_price_period to see if a period is currently active.",
@ -314,6 +324,11 @@
"long_description": "Shows the end timestamp of the current peak price period when active, or the end of the next period when no period is active. Always shows a useful time reference for planning. Returns 'Unknown' only when no periods are configured.", "long_description": "Shows the end timestamp of the current peak price period when active, or the end of the next period when no period is active. Always shows a useful time reference for planning. Returns 'Unknown' only when no periods are configured.",
"usage_tips": "Use this to display 'Expensive period ends in 1 hour' (when active) or 'Next expensive period ends at 18:00' (when inactive). Combine with automations to resume operations after peak." "usage_tips": "Use this to display 'Expensive period ends in 1 hour' (when active) or 'Next expensive period ends at 18:00' (when inactive). Combine with automations to resume operations after peak."
}, },
"peak_price_period_duration": {
"description": "Total length of current or next peak price period in minutes",
"long_description": "Shows how long the peak price period lasts in total. During an active period, shows the duration of the current period. When no period is active, shows the duration of the next upcoming period. Returns 'Unknown' only when no periods are configured.",
"usage_tips": "Useful for planning: 'The next expensive period lasts 60 minutes' or 'Current peak is 90 minutes long'. Combine with remaining_minutes to decide whether to wait out the peak or proceed with operations."
},
"peak_price_remaining_minutes": { "peak_price_remaining_minutes": {
"description": "Minutes remaining in current peak price period (0 when inactive)", "description": "Minutes remaining in current peak price period (0 when inactive)",
"long_description": "Shows how many minutes are left in the current peak price period. Returns 0 when no period is active. Updates every minute. Check binary_sensor.peak_price_period to see if a period is currently active.", "long_description": "Shows how many minutes are left in the current peak price period. Returns 0 when no period is active. Updates every minute. Check binary_sensor.peak_price_period to see if a period is currently active.",

View file

@ -5,6 +5,11 @@
"long_description": "Viser nåværende pris per kWh fra ditt Tibber-abonnement", "long_description": "Viser nåværende pris per kWh fra ditt Tibber-abonnement",
"usage_tips": "Bruk dette til å spore priser eller lage automatiseringer som kjører når strøm er billig" "usage_tips": "Bruk dette til å spore priser eller lage automatiseringer som kjører når strøm er billig"
}, },
"current_interval_price_major": {
"description": "Nåværende elektrisitetspris i hovedvaluta (EUR/kWh, NOK/kWh, osv.) for Energi-dashboard",
"long_description": "Viser nåværende pris per kWh i hovedvalutaenheter (f.eks. EUR/kWh i stedet for ct/kWh, NOK/kWh i stedet for øre/kWh). Denne sensoren er spesielt designet for bruk med Home Assistants Energi-dashboard, som krever priser i standard valutaenheter.",
"usage_tips": "Bruk denne sensoren når du konfigurerer Energi-dashboardet under Innstillinger → Dashbord → Energi. Velg denne sensoren som 'Entitet med nåværende pris' for automatisk å beregne energikostnadene. Energi-dashboardet multipliserer energiforbruket ditt (kWh) med denne prisen for å vise totale kostnader."
},
"next_interval_price": { "next_interval_price": {
"description": "Neste intervalls elektrisitetspris per kWh", "description": "Neste intervalls elektrisitetspris per kWh",
"long_description": "Viser prisen for det neste 15-minutters intervallet fra ditt Tibber-abonnement", "long_description": "Viser prisen for det neste 15-minutters intervallet fra ditt Tibber-abonnement",
@ -333,6 +338,16 @@
"description": "Minutter til neste dyrperiode starter (0 ved overgang)", "description": "Minutter til neste dyrperiode starter (0 ved overgang)",
"long_description": "Viser minutter til neste dyrperiode starter. Under en aktiv periode viser dette tiden til perioden ETTER den gjeldende. Returnerer 0 under korte overgangsmomenter. Oppdateres hvert minutt.", "long_description": "Viser minutter til neste dyrperiode starter. Under en aktiv periode viser dette tiden til perioden ETTER den gjeldende. Returnerer 0 under korte overgangsmomenter. Oppdateres hvert minutt.",
"usage_tips": "Forebyggende automatisering: 'Hvis next_in_minutes > 0 OG next_in_minutes < 10, fullfør gjeldende ladesyklus nå før prisene øker'." "usage_tips": "Forebyggende automatisering: 'Hvis next_in_minutes > 0 OG next_in_minutes < 10, fullfør gjeldende ladesyklus nå før prisene øker'."
},
"best_price_period_duration": {
"description": "Total varighet av gjeldende eller neste billigperiode i minutter",
"long_description": "Viser den totale varigheten av billigperioden i minutter. Under en aktiv periode viser dette hele varigheten av gjeldende periode. Når ingen periode er aktiv, viser dette varigheten av neste kommende periode. Eksempel: '90 minutter' for en 1,5-timers periode.",
"usage_tips": "Kombiner med remaining_minutes for å planlegge oppgaver: 'Hvis duration = 120 OG remaining_minutes > 90, start vaskemaskin (nok tid til å fullføre)'. Nyttig for å forstå om perioder er lange nok for strømkrevende oppgaver."
},
"peak_price_period_duration": {
"description": "Total varighet av gjeldende eller neste dyrperiode i minutter",
"long_description": "Viser den totale varigheten av dyrperioden i minutter. Under en aktiv periode viser dette hele varigheten av gjeldende periode. Når ingen periode er aktiv, viser dette varigheten av neste kommende periode. Eksempel: '60 minutter' for en 1-times periode.",
"usage_tips": "Bruk til å planlegge energibesparelsestiltak: 'Hvis duration > 120, reduser varmetemperatur mer aggressivt (lang dyr periode)'. Hjelper med å vurdere hvor mye energiforbruk må reduseres."
} }
}, },
"binary_sensor": { "binary_sensor": {

View file

@ -5,6 +5,11 @@
"long_description": "Toont de huidige prijs per kWh van uw Tibber-abonnement", "long_description": "Toont de huidige prijs per kWh van uw Tibber-abonnement",
"usage_tips": "Gebruik dit om prijzen bij te houden of om automatiseringen te maken die worden uitgevoerd wanneer elektriciteit goedkoop is" "usage_tips": "Gebruik dit om prijzen bij te houden of om automatiseringen te maken die worden uitgevoerd wanneer elektriciteit goedkoop is"
}, },
"current_interval_price_major": {
"description": "Huidige elektriciteitsprijs in hoofdvaluta (EUR/kWh, NOK/kWh, enz.) voor Energie-dashboard",
"long_description": "Toont de huidige prijs per kWh in hoofdvaluta-eenheden (bijv. EUR/kWh in plaats van ct/kWh, NOK/kWh in plaats van øre/kWh). Deze sensor is speciaal ontworpen voor gebruik met het Energie-dashboard van Home Assistant, dat prijzen in standaard valuta-eenheden vereist.",
"usage_tips": "Gebruik deze sensor bij het configureren van het Energie-dashboard onder Instellingen → Dashboards → Energie. Selecteer deze sensor als 'Entiteit met huidige prijs' om automatisch je energiekosten te berekenen. Het Energie-dashboard vermenigvuldigt je energieverbruik (kWh) met deze prijs om totale kosten weer te geven."
},
"next_interval_price": { "next_interval_price": {
"description": "De volgende interval elektriciteitsprijs per kWh", "description": "De volgende interval elektriciteitsprijs per kWh",
"long_description": "Toont de prijs voor het volgende 15-minuten interval van uw Tibber-abonnement", "long_description": "Toont de prijs voor het volgende 15-minuten interval van uw Tibber-abonnement",
@ -333,6 +338,16 @@
"description": "Minuten tot volgende dure periode begint (0 bij overgang)", "description": "Minuten tot volgende dure periode begint (0 bij overgang)",
"long_description": "Toont minuten tot de volgende dure periode begint. Tijdens een actieve periode toont dit de tijd tot de periode NA de huidige. Geeft 0 terug tijdens korte overgangsmomenten. Werkt elke minuut bij.", "long_description": "Toont minuten tot de volgende dure periode begint. Tijdens een actieve periode toont dit de tijd tot de periode NA de huidige. Geeft 0 terug tijdens korte overgangsmomenten. Werkt elke minuut bij.",
"usage_tips": "Preventieve automatisering: 'Als next_in_minutes > 0 EN next_in_minutes < 10, voltooi huidige laadcyclus nu voordat prijzen stijgen'." "usage_tips": "Preventieve automatisering: 'Als next_in_minutes > 0 EN next_in_minutes < 10, voltooi huidige laadcyclus nu voordat prijzen stijgen'."
},
"best_price_period_duration": {
"description": "Totale duur van huidige of volgende goedkope periode in minuten",
"long_description": "Toont de totale duur van de goedkope periode in minuten. Tijdens een actieve periode toont dit de volledige lengte van de huidige periode. Wanneer geen periode actief is, toont dit de duur van de volgende komende periode. Voorbeeld: '90 minuten' voor een 1,5-uur periode.",
"usage_tips": "Combineer met remaining_minutes voor taakplanning: 'Als duration = 120 EN remaining_minutes > 90, start wasmachine (genoeg tijd om te voltooien)'. Nuttig om te begrijpen of periodes lang genoeg zijn voor energie-intensieve taken."
},
"peak_price_period_duration": {
"description": "Totale duur van huidige of volgende dure periode in minuten",
"long_description": "Toont de totale duur van de dure periode in minuten. Tijdens een actieve periode toont dit de volledige lengte van de huidige periode. Wanneer geen periode actief is, toont dit de duur van de volgende komende periode. Voorbeeld: '60 minuten' voor een 1-uur periode.",
"usage_tips": "Gebruik om energiebesparende maatregelen te plannen: 'Als duration > 120, verlaag verwarmingstemperatuur agressiever (lange dure periode)'. Helpt bij het inschatten hoeveel energieverbruik moet worden verminderd."
} }
}, },
"binary_sensor": { "binary_sensor": {

View file

@ -5,6 +5,11 @@
"long_description": "Visar nuvarande pris per kWh från ditt Tibber-abonnemang", "long_description": "Visar nuvarande pris per kWh från ditt Tibber-abonnemang",
"usage_tips": "Använd detta för att spåra priser eller skapa automationer som körs när el är billig" "usage_tips": "Använd detta för att spåra priser eller skapa automationer som körs när el är billig"
}, },
"current_interval_price_major": {
"description": "Nuvarande elpris i huvudvaluta (EUR/kWh, NOK/kWh, osv.) för Energipanelen",
"long_description": "Visar nuvarande pris per kWh i huvudvaluta-enheter (t.ex. EUR/kWh istället för ct/kWh, NOK/kWh istället för øre/kWh). Denna sensor är speciellt utformad för användning med Home Assistants Energipanel, som kräver priser i standardvalutaenheter.",
"usage_tips": "Använd denna sensor när du konfigurerar Energipanelen under Inställningar → Instrumentpaneler → Energi. Välj denna sensor som 'Entitet med nuvarande pris' för att automatiskt beräkna dina energikostnader. Energipanelen multiplicerar din energiförbrukning (kWh) med detta pris för att visa totala kostnader."
},
"next_interval_price": { "next_interval_price": {
"description": "Nästa intervalls elpris per kWh", "description": "Nästa intervalls elpris per kWh",
"long_description": "Visar priset för nästa 15-minuters intervall från ditt Tibber-abonnemang", "long_description": "Visar priset för nästa 15-minuters intervall från ditt Tibber-abonnemang",
@ -333,6 +338,16 @@
"description": "Minuter tills nästa dyrperiod startar (0 vid övergång)", "description": "Minuter tills nästa dyrperiod startar (0 vid övergång)",
"long_description": "Visar minuter tills nästa dyrperiod startar. Under en aktiv period visar detta tiden till perioden EFTER den nuvarande. Returnerar 0 under korta övergångsmoment. Uppdateras varje minut.", "long_description": "Visar minuter tills nästa dyrperiod startar. Under en aktiv period visar detta tiden till perioden EFTER den nuvarande. Returnerar 0 under korta övergångsmoment. Uppdateras varje minut.",
"usage_tips": "Förebyggande automation: 'Om next_in_minutes > 0 OCH next_in_minutes < 10, slutför nuvarande laddcykel nu innan priserna ökar'." "usage_tips": "Förebyggande automation: 'Om next_in_minutes > 0 OCH next_in_minutes < 10, slutför nuvarande laddcykel nu innan priserna ökar'."
},
"best_price_period_duration": {
"description": "Total längd på nuvarande eller nästa billigperiod i minuter",
"long_description": "Visar den totala längden på billigperioden i minuter. Under en aktiv period visar detta hela längden av nuvarande period. När ingen period är aktiv visar detta längden på nästa kommande period. Exempel: '90 minuter' för en 1,5-timmars period.",
"usage_tips": "Kombinera med remaining_minutes för att planera uppgifter: 'Om duration = 120 OCH remaining_minutes > 90, starta tvättmaskin (tillräckligt med tid för att slutföra)'. Användbart för att förstå om perioder är tillräckligt långa för energikrävande uppgifter."
},
"peak_price_period_duration": {
"description": "Total längd på nuvarande eller nästa dyrperiod i minuter",
"long_description": "Visar den totala längden på dyrperioden i minuter. Under en aktiv period visar detta hela längden av nuvarande period. När ingen period är aktiv visar detta längden på nästa kommande period. Exempel: '60 minuter' för en 1-timmars period.",
"usage_tips": "Använd för att planera energisparåtgärder: 'Om duration > 120, minska värmetemperatur mer aggressivt (lång dyr period)'. Hjälper till att bedöma hur mycket energiförbrukning måste minskas."
} }
}, },
"binary_sensor": { "binary_sensor": {

View file

@ -30,6 +30,7 @@ from custom_components.tibber_prices.const import (
DEFAULT_PRICE_TREND_THRESHOLD_RISING, DEFAULT_PRICE_TREND_THRESHOLD_RISING,
DOMAIN, DOMAIN,
async_get_entity_description, async_get_entity_description,
format_price_unit_major,
format_price_unit_minor, format_price_unit_minor,
get_entity_description, get_entity_description,
) )
@ -175,6 +176,9 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
"current_interval_price": lambda: self._get_interval_value( "current_interval_price": lambda: self._get_interval_value(
interval_offset=0, value_type="price", in_euro=False interval_offset=0, value_type="price", in_euro=False
), ),
"current_interval_price_major": lambda: self._get_interval_value(
interval_offset=0, value_type="price", in_euro=True
),
"next_interval_price": lambda: self._get_interval_value( "next_interval_price": lambda: self._get_interval_value(
interval_offset=1, value_type="price", in_euro=False interval_offset=1, value_type="price", in_euro=False
), ),
@ -279,6 +283,9 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
"best_price_end_time": lambda: self._get_period_timing_value( "best_price_end_time": lambda: self._get_period_timing_value(
period_type="best_price", value_type="end_time" period_type="best_price", value_type="end_time"
), ),
"best_price_period_duration": lambda: self._get_period_timing_value(
period_type="best_price", value_type="period_duration"
),
"best_price_remaining_minutes": lambda: self._get_period_timing_value( "best_price_remaining_minutes": lambda: self._get_period_timing_value(
period_type="best_price", value_type="remaining_minutes" period_type="best_price", value_type="remaining_minutes"
), ),
@ -295,6 +302,9 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
"peak_price_end_time": lambda: self._get_period_timing_value( "peak_price_end_time": lambda: self._get_period_timing_value(
period_type="peak_price", value_type="end_time" period_type="peak_price", value_type="end_time"
), ),
"peak_price_period_duration": lambda: self._get_period_timing_value(
period_type="peak_price", value_type="period_duration"
),
"peak_price_remaining_minutes": lambda: self._get_period_timing_value( "peak_price_remaining_minutes": lambda: self._get_period_timing_value(
period_type="peak_price", value_type="remaining_minutes" period_type="peak_price", value_type="remaining_minutes"
), ),
@ -1059,6 +1069,7 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
"end_time": lambda: ( "end_time": lambda: (
current_period.get("end") if current_period else (next_period.get("end") if next_period else None) current_period.get("end") if current_period else (next_period.get("end") if next_period else None)
), ),
"period_duration": lambda: self._calc_period_duration(current_period, next_period),
"next_start_time": lambda: next_period.get("start") if next_period else None, "next_start_time": lambda: next_period.get("start") if next_period else None,
"remaining_minutes": lambda: (self._calc_remaining_minutes(current_period, now) if current_period else 0), "remaining_minutes": lambda: (self._calc_remaining_minutes(current_period, now) if current_period else 0),
"progress": lambda: self._calc_progress_with_grace_period(current_period, previous_period, now), "progress": lambda: self._calc_progress_with_grace_period(current_period, previous_period, now),
@ -1133,6 +1144,33 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
delta = start - now delta = start - now
return max(0, delta.total_seconds() / 60) return max(0, delta.total_seconds() / 60)
def _calc_period_duration(self, current_period: dict | None, next_period: dict | None) -> float | None:
"""
Calculate total duration of active or next period in minutes.
Returns duration of current period if active, otherwise duration of next period.
This gives users a consistent view of period length regardless of timing.
Args:
current_period: Currently active period (if any)
next_period: Next upcoming period (if any)
Returns:
Duration in minutes, or None if no periods available
"""
period = current_period or next_period
if not period:
return None
start = period.get("start")
end = period.get("end")
if not start or not end:
return None
duration = (end - start).total_seconds() / 60
return max(0, duration)
def _calc_progress(self, period: dict, now: datetime) -> float: def _calc_progress(self, period: dict, now: datetime) -> float:
"""Calculate progress percentage (0-100) of current period.""" """Calculate progress percentage (0-100) of current period."""
start = period.get("start") start = period.get("start")
@ -1211,6 +1249,12 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
if self.coordinator.data: if self.coordinator.data:
price_info = self.coordinator.data.get("priceInfo", {}) price_info = self.coordinator.data.get("priceInfo", {})
currency = price_info.get("currency") currency = price_info.get("currency")
# Use major currency unit for Energy Dashboard sensor
if self.entity_description.key == "current_interval_price_major":
return format_price_unit_major(currency)
# Use minor currency unit for all other price sensors
return format_price_unit_minor(currency) return format_price_unit_minor(currency)
# For all other sensors, use unit from entity description # For all other sensors, use unit from entity description

View file

@ -21,6 +21,7 @@ from __future__ import annotations
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
SensorEntityDescription, SensorEntityDescription,
SensorStateClass,
) )
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime
@ -56,14 +57,25 @@ INTERVAL_PRICE_SENSORS = (
name="Current Electricity Price", name="Current Electricity Price",
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=2, suggested_display_precision=2,
), ),
SensorEntityDescription(
key="current_interval_price_major",
translation_key="current_interval_price_major",
name="Current Electricity Price (Energy Dashboard)",
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level
device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None for Energy Dashboard
suggested_display_precision=4, # More precision for major currency (e.g., 0.2534 EUR/kWh)
),
SensorEntityDescription( SensorEntityDescription(
key="next_interval_price", key="next_interval_price",
translation_key="next_interval_price", translation_key="next_interval_price",
name="Next Price", name="Next Price",
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=2, suggested_display_precision=2,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -72,6 +84,7 @@ INTERVAL_PRICE_SENSORS = (
name="Previous Electricity Price", name="Previous Electricity Price",
icon="mdi:cash-refund", # Static: arrow back indicates "past" icon="mdi:cash-refund", # Static: arrow back indicates "past"
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
suggested_display_precision=2, suggested_display_precision=2,
), ),
@ -87,6 +100,7 @@ INTERVAL_LEVEL_SENSORS = (
name="Current Price Level", name="Current Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -95,6 +109,7 @@ INTERVAL_LEVEL_SENSORS = (
name="Next Price Level", name="Next Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -104,6 +119,7 @@ INTERVAL_LEVEL_SENSORS = (
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
) )
@ -118,6 +134,7 @@ INTERVAL_RATING_SENSORS = (
name="Current Price Rating", name="Current Price Rating",
icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -126,6 +143,7 @@ INTERVAL_RATING_SENSORS = (
name="Next Price Rating", name="Next Price Rating",
icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -135,6 +153,7 @@ INTERVAL_RATING_SENSORS = (
icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value icon="mdi:thumbs-up-down", # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on rating value
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
) )
@ -152,6 +171,7 @@ ROLLING_HOUR_PRICE_SENSORS = (
name="Current Hour Average Price", name="Current Hour Average Price",
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on aggregated price level icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on aggregated price level
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -160,6 +180,7 @@ ROLLING_HOUR_PRICE_SENSORS = (
name="Next Hour Average Price", name="Next Hour Average Price",
icon="mdi:cash-fast", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on aggregated price level icon="mdi:cash-fast", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on aggregated price level
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
) )
@ -174,6 +195,7 @@ ROLLING_HOUR_LEVEL_SENSORS = (
name="Current Hour Price Level", name="Current Hour Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on aggregated level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on aggregated level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -182,6 +204,7 @@ ROLLING_HOUR_LEVEL_SENSORS = (
name="Next Hour Price Level", name="Next Hour Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on aggregated level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on aggregated level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
) )
@ -197,6 +220,7 @@ ROLLING_HOUR_RATING_SENSORS = (
# Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on aggregated rating value # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on aggregated rating value
icon="mdi:thumbs-up-down", icon="mdi:thumbs-up-down",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -206,6 +230,7 @@ ROLLING_HOUR_RATING_SENSORS = (
# Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on aggregated rating value # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on aggregated rating value
icon="mdi:thumbs-up-down", icon="mdi:thumbs-up-down",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
) )
@ -222,6 +247,7 @@ DAILY_STAT_SENSORS = (
name="Today's Lowest Price", name="Today's Lowest Price",
icon="mdi:arrow-collapse-down", icon="mdi:arrow-collapse-down",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -230,6 +256,7 @@ DAILY_STAT_SENSORS = (
name="Today's Highest Price", name="Today's Highest Price",
icon="mdi:arrow-collapse-up", icon="mdi:arrow-collapse-up",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -238,6 +265,7 @@ DAILY_STAT_SENSORS = (
name="Today's Average Price", name="Today's Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -246,6 +274,7 @@ DAILY_STAT_SENSORS = (
name="Tomorrow's Lowest Price", name="Tomorrow's Lowest Price",
icon="mdi:arrow-collapse-down", icon="mdi:arrow-collapse-down",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -254,6 +283,7 @@ DAILY_STAT_SENSORS = (
name="Tomorrow's Highest Price", name="Tomorrow's Highest Price",
icon="mdi:arrow-collapse-up", icon="mdi:arrow-collapse-up",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -262,6 +292,7 @@ DAILY_STAT_SENSORS = (
name="Tomorrow's Average Price", name="Tomorrow's Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
) )
@ -276,6 +307,7 @@ DAILY_LEVEL_SENSORS = (
name="Yesterday's Price Level", name="Yesterday's Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -285,6 +317,7 @@ DAILY_LEVEL_SENSORS = (
name="Today's Price Level", name="Today's Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -293,6 +326,7 @@ DAILY_LEVEL_SENSORS = (
name="Tomorrow's Price Level", name="Tomorrow's Price Level",
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on daily level value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"], options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
), ),
) )
@ -308,6 +342,7 @@ DAILY_RATING_SENSORS = (
# Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value
icon="mdi:thumbs-up-down", icon="mdi:thumbs-up-down",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -318,6 +353,7 @@ DAILY_RATING_SENSORS = (
# Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value
icon="mdi:thumbs-up-down", icon="mdi:thumbs-up-down",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -327,6 +363,7 @@ DAILY_RATING_SENSORS = (
# Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value # Dynamic: shows thumbs-up/thumbs-up-down/thumbs-down based on daily rating value
icon="mdi:thumbs-up-down", icon="mdi:thumbs-up-down",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "normal", "high"], options=["low", "normal", "high"],
), ),
) )
@ -343,6 +380,7 @@ WINDOW_24H_SENSORS = (
name="Trailing 24h Average Price", name="Trailing 24h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
suggested_display_precision=1, suggested_display_precision=1,
), ),
@ -352,6 +390,7 @@ WINDOW_24H_SENSORS = (
name="Leading 24h Average Price", name="Leading 24h Average Price",
icon="mdi:chart-line-variant", icon="mdi:chart-line-variant",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -360,6 +399,7 @@ WINDOW_24H_SENSORS = (
name="Trailing 24h Minimum Price", name="Trailing 24h Minimum Price",
icon="mdi:arrow-collapse-down", icon="mdi:arrow-collapse-down",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
suggested_display_precision=1, suggested_display_precision=1,
), ),
@ -369,6 +409,7 @@ WINDOW_24H_SENSORS = (
name="Trailing 24h Maximum Price", name="Trailing 24h Maximum Price",
icon="mdi:arrow-collapse-up", icon="mdi:arrow-collapse-up",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
suggested_display_precision=1, suggested_display_precision=1,
), ),
@ -378,6 +419,7 @@ WINDOW_24H_SENSORS = (
name="Leading 24h Minimum Price", name="Leading 24h Minimum Price",
icon="mdi:arrow-collapse-down", icon="mdi:arrow-collapse-down",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -386,6 +428,7 @@ WINDOW_24H_SENSORS = (
name="Leading 24h Maximum Price", name="Leading 24h Maximum Price",
icon="mdi:arrow-collapse-up", icon="mdi:arrow-collapse-up",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
), ),
) )
@ -403,6 +446,7 @@ FUTURE_AVG_SENSORS = (
name="Next 1h Average Price", name="Next 1h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -412,6 +456,7 @@ FUTURE_AVG_SENSORS = (
name="Next 2h Average Price", name="Next 2h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -421,6 +466,7 @@ FUTURE_AVG_SENSORS = (
name="Next 3h Average Price", name="Next 3h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -430,6 +476,7 @@ FUTURE_AVG_SENSORS = (
name="Next 4h Average Price", name="Next 4h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -439,6 +486,7 @@ FUTURE_AVG_SENSORS = (
name="Next 5h Average Price", name="Next 5h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -449,6 +497,7 @@ FUTURE_AVG_SENSORS = (
name="Next 6h Average Price", name="Next 6h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -458,6 +507,7 @@ FUTURE_AVG_SENSORS = (
name="Next 8h Average Price", name="Next 8h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -467,6 +517,7 @@ FUTURE_AVG_SENSORS = (
name="Next 12h Average Price", name="Next 12h Average Price",
icon="mdi:chart-line", icon="mdi:chart-line",
device_class=SensorDeviceClass.MONETARY, device_class=SensorDeviceClass.MONETARY,
state_class=SensorStateClass.TOTAL, # MONETARY requires TOTAL or None
suggested_display_precision=1, suggested_display_precision=1,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -480,6 +531,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (1h)", name="Price Trend (1h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -489,6 +541,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (2h)", name="Price Trend (2h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -498,6 +551,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (3h)", name="Price Trend (3h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -507,6 +561,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (4h)", name="Price Trend (4h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -516,6 +571,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (5h)", name="Price Trend (5h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=True, entity_registry_enabled_default=True,
), ),
@ -526,6 +582,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (6h)", name="Price Trend (6h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -535,6 +592,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (8h)", name="Price Trend (8h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -544,6 +602,7 @@ FUTURE_TREND_SENSORS = (
name="Price Trend (12h)", name="Price Trend (12h)",
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["rising", "falling", "stable"], options=["rising", "falling", "stable"],
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
@ -564,6 +623,7 @@ VOLATILITY_SENSORS = (
# Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level # Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level
icon="mdi:chart-bell-curve-cumulative", icon="mdi:chart-bell-curve-cumulative",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "moderate", "high", "very_high"], options=["low", "moderate", "high", "very_high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -573,6 +633,7 @@ VOLATILITY_SENSORS = (
# Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level # Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level
icon="mdi:chart-bell-curve-cumulative", icon="mdi:chart-bell-curve-cumulative",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "moderate", "high", "very_high"], options=["low", "moderate", "high", "very_high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -582,6 +643,7 @@ VOLATILITY_SENSORS = (
# Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level # Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level
icon="mdi:chart-bell-curve-cumulative", icon="mdi:chart-bell-curve-cumulative",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "moderate", "high", "very_high"], options=["low", "moderate", "high", "very_high"],
), ),
SensorEntityDescription( SensorEntityDescription(
@ -591,6 +653,7 @@ VOLATILITY_SENSORS = (
# Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level # Dynamic: shows chart-bell-curve/chart-gantt/finance based on volatility level
icon="mdi:chart-bell-curve-cumulative", icon="mdi:chart-bell-curve-cumulative",
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
state_class=None, # Enum values: no statistics
options=["low", "moderate", "high", "very_high"], options=["low", "moderate", "high", "very_high"],
), ),
) )
@ -619,6 +682,18 @@ BEST_PRICE_TIMING_SENSORS = (
name="Best Price Period End", name="Best Price Period End",
icon="mdi:clock-end", icon="mdi:clock-end",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=None, # Timestamps: no statistics
),
SensorEntityDescription(
key="best_price_period_duration",
translation_key="best_price_period_duration",
name="Best Price Period Duration",
icon="mdi:timer",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Changes with each period: no statistics
suggested_display_precision=0,
entity_registry_enabled_default=False,
), ),
SensorEntityDescription( SensorEntityDescription(
key="best_price_remaining_minutes", key="best_price_remaining_minutes",
@ -626,6 +701,7 @@ BEST_PRICE_TIMING_SENSORS = (
name="Best Price Remaining Time", name="Best Price Remaining Time",
icon="mdi:timer-sand", icon="mdi:timer-sand",
native_unit_of_measurement=UnitOfTime.MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Countdown timer: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -634,6 +710,7 @@ BEST_PRICE_TIMING_SENSORS = (
name="Best Price Progress", name="Best Price Progress",
icon="mdi:percent", # Dynamic: mdi:percent-0 to mdi:percent-100 icon="mdi:percent", # Dynamic: mdi:percent-0 to mdi:percent-100
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
state_class=None, # Progress counter: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -642,6 +719,7 @@ BEST_PRICE_TIMING_SENSORS = (
name="Best Price Next Period Start", name="Best Price Next Period Start",
icon="mdi:clock-start", icon="mdi:clock-start",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=None, # Timestamps: no statistics
), ),
SensorEntityDescription( SensorEntityDescription(
key="best_price_next_in_minutes", key="best_price_next_in_minutes",
@ -649,6 +727,7 @@ BEST_PRICE_TIMING_SENSORS = (
name="Best Price Starts In", name="Best Price Starts In",
icon="mdi:timer-outline", icon="mdi:timer-outline",
native_unit_of_measurement=UnitOfTime.MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Countdown timer: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
) )
@ -660,6 +739,18 @@ PEAK_PRICE_TIMING_SENSORS = (
name="Peak Price Period End", name="Peak Price Period End",
icon="mdi:clock-end", icon="mdi:clock-end",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=None, # Timestamps: no statistics
),
SensorEntityDescription(
key="peak_price_period_duration",
translation_key="peak_price_period_duration",
name="Peak Price Period Duration",
icon="mdi:timer",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Changes with each period: no statistics
suggested_display_precision=0,
entity_registry_enabled_default=False,
), ),
SensorEntityDescription( SensorEntityDescription(
key="peak_price_remaining_minutes", key="peak_price_remaining_minutes",
@ -667,6 +758,7 @@ PEAK_PRICE_TIMING_SENSORS = (
name="Peak Price Remaining Time", name="Peak Price Remaining Time",
icon="mdi:timer-sand", icon="mdi:timer-sand",
native_unit_of_measurement=UnitOfTime.MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Countdown timer: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -675,6 +767,7 @@ PEAK_PRICE_TIMING_SENSORS = (
name="Peak Price Progress", name="Peak Price Progress",
icon="mdi:percent", # Dynamic: mdi:percent-0 to mdi:percent-100 icon="mdi:percent", # Dynamic: mdi:percent-0 to mdi:percent-100
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
state_class=None, # Progress counter: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -683,6 +776,7 @@ PEAK_PRICE_TIMING_SENSORS = (
name="Peak Price Next Period Start", name="Peak Price Next Period Start",
icon="mdi:clock-start", icon="mdi:clock-start",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=None, # Timestamps: no statistics
), ),
SensorEntityDescription( SensorEntityDescription(
key="peak_price_next_in_minutes", key="peak_price_next_in_minutes",
@ -690,6 +784,7 @@ PEAK_PRICE_TIMING_SENSORS = (
name="Peak Price Starts In", name="Peak Price Starts In",
icon="mdi:timer-outline", icon="mdi:timer-outline",
native_unit_of_measurement=UnitOfTime.MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
state_class=None, # Countdown timer: no statistics
suggested_display_precision=0, suggested_display_precision=0,
), ),
) )
@ -704,6 +799,7 @@ DIAGNOSTIC_SENSORS = (
name="Data Expiration", name="Data Expiration",
icon="mdi:clock-check", icon="mdi:clock-check",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=None, # Timestamps: no statistics
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
), ),
SensorEntityDescription( SensorEntityDescription(
@ -711,6 +807,7 @@ DIAGNOSTIC_SENSORS = (
translation_key="price_forecast", translation_key="price_forecast",
name="Price Forecast", name="Price Forecast",
icon="mdi:chart-line", icon="mdi:chart-line",
state_class=None, # Text/status value: no statistics
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
), ),
) )

View file

@ -186,11 +186,14 @@
"current_interval_price": { "current_interval_price": {
"name": "Aktueller Strompreis" "name": "Aktueller Strompreis"
}, },
"current_interval_price_major": {
"name": "Aktueller Strompreis (Energie-Dashboard)"
},
"next_interval_price": { "next_interval_price": {
"name": "Nächster Preis" "name": "Nächster Strompreis"
}, },
"previous_interval_price": { "previous_interval_price": {
"name": "Vorheriger Preis" "name": "Vorheriger Strompreis"
}, },
"current_hour_average_price": { "current_hour_average_price": {
"name": "Aktueller Stunden-Durchschnittspreis" "name": "Aktueller Stunden-Durchschnittspreis"
@ -514,6 +517,9 @@
"best_price_end_time": { "best_price_end_time": {
"name": "Günstige Periode endet" "name": "Günstige Periode endet"
}, },
"best_price_period_duration": {
"name": "Günstige Periode Dauer"
},
"best_price_remaining_minutes": { "best_price_remaining_minutes": {
"name": "Günstige Periode verbleibend" "name": "Günstige Periode verbleibend"
}, },
@ -529,6 +535,9 @@
"peak_price_end_time": { "peak_price_end_time": {
"name": "Teure Periode endet" "name": "Teure Periode endet"
}, },
"peak_price_period_duration": {
"name": "Teure Periode Dauer"
},
"peak_price_remaining_minutes": { "peak_price_remaining_minutes": {
"name": "Teure Periode verbleibend" "name": "Teure Periode verbleibend"
}, },

View file

@ -182,8 +182,11 @@
"current_interval_price": { "current_interval_price": {
"name": "Current Electricity Price" "name": "Current Electricity Price"
}, },
"current_interval_price_major": {
"name": "Current Electricity Price (Energy Dashboard)"
},
"next_interval_price": { "next_interval_price": {
"name": "Next Price" "name": "Next Electricity Price"
}, },
"previous_interval_price": { "previous_interval_price": {
"name": "Previous Electricity Price" "name": "Previous Electricity Price"
@ -510,6 +513,9 @@
"best_price_end_time": { "best_price_end_time": {
"name": "Best Price Period End" "name": "Best Price Period End"
}, },
"best_price_period_duration": {
"name": "Best Price Period Duration"
},
"best_price_remaining_minutes": { "best_price_remaining_minutes": {
"name": "Best Price Remaining Time" "name": "Best Price Remaining Time"
}, },
@ -525,6 +531,9 @@
"peak_price_end_time": { "peak_price_end_time": {
"name": "Peak Price Period End" "name": "Peak Price Period End"
}, },
"peak_price_period_duration": {
"name": "Peak Price Period Duration"
},
"peak_price_remaining_minutes": { "peak_price_remaining_minutes": {
"name": "Peak Price Remaining Time" "name": "Peak Price Remaining Time"
}, },

View file

@ -182,6 +182,9 @@
"current_interval_price": { "current_interval_price": {
"name": "Nåværende strømpris" "name": "Nåværende strømpris"
}, },
"current_interval_price_major": {
"name": "Nåværende strømpris (Energi-dashboard)"
},
"next_interval_price": { "next_interval_price": {
"name": "Neste pris" "name": "Neste pris"
}, },
@ -537,6 +540,12 @@
"peak_price_next_in_minutes": { "peak_price_next_in_minutes": {
"name": "Topprisperiode starter om" "name": "Topprisperiode starter om"
}, },
"best_price_period_duration": {
"name": "Billigperiode varighet"
},
"peak_price_period_duration": {
"name": "Topprisperiode varighet"
},
"price_forecast": { "price_forecast": {
"name": "Prisprognose" "name": "Prisprognose"
} }

View file

@ -182,6 +182,9 @@
"current_interval_price": { "current_interval_price": {
"name": "Huidige elektriciteitsprijs" "name": "Huidige elektriciteitsprijs"
}, },
"current_interval_price_major": {
"name": "Huidige elektriciteitsprijs (Energie-dashboard)"
},
"next_interval_price": { "next_interval_price": {
"name": "Volgende prijs" "name": "Volgende prijs"
}, },
@ -537,6 +540,12 @@
"peak_price_next_in_minutes": { "peak_price_next_in_minutes": {
"name": "Piekprijsperiode start over" "name": "Piekprijsperiode start over"
}, },
"best_price_period_duration": {
"name": "Goedkope periode duur"
},
"peak_price_period_duration": {
"name": "Piekprijsperiode duur"
},
"price_forecast": { "price_forecast": {
"name": "Prijsprognose" "name": "Prijsprognose"
} }

View file

@ -182,6 +182,9 @@
"current_interval_price": { "current_interval_price": {
"name": "Nuvarande elpris" "name": "Nuvarande elpris"
}, },
"current_interval_price_major": {
"name": "Nuvarande elpris (Energipanel)"
},
"next_interval_price": { "next_interval_price": {
"name": "Nästa pris" "name": "Nästa pris"
}, },
@ -537,6 +540,12 @@
"peak_price_next_in_minutes": { "peak_price_next_in_minutes": {
"name": "Topprisperiod startar om" "name": "Topprisperiod startar om"
}, },
"best_price_period_duration": {
"name": "Billigperiod varaktighet"
},
"peak_price_period_duration": {
"name": "Topprisperiod varaktighet"
},
"price_forecast": { "price_forecast": {
"name": "Prisprognos" "name": "Prisprognos"
} }