mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-30 13:23:41 +00:00
feat(sensors): add timestamp attributes and enhance icon system
Added timestamp attributes to all sensors and enhanced the dynamic icon
system for comprehensive price sensor coverage with rolling hour support.
TIMESTAMP ATTRIBUTES:
Core Changes:
- sensor/attributes.py:
* Enhanced add_average_price_attributes() to track extreme intervals
for min/max sensors and add appropriate timestamps
* Added _update_extreme_interval() helper to reduce complexity
* Extended add_volatility_type_attributes() with timestamp logic for
all 4 volatility types (today/tomorrow/today_tomorrow/next_24h)
* Fixed current_interval_price timestamp assignment (use interval_data)
Timestamp Logic:
- Interval-based sensors: Use startsAt of specific 15-minute interval
- Min/Max sensors: Use startsAt of interval with extreme price
- Average sensors: Use startsAt of first interval in window
- Volatility sensors: Use midnight (00:00) for calendar day sensors,
current time for rolling 24h window
- Daily sensors: Already used fallback to midnight (verified)
ICON SYSTEM ENHANCEMENTS:
Major Extensions:
- entity_utils/icons.py:
* Created get_rolling_hour_price_level_for_icon() implementing
5-interval window aggregation matching sensor calculation logic
* Extended get_price_sensor_icon() coverage from 1 to 4 sensors:
- current_interval_price (existing)
- next_interval_price (NEW - dynamic instead of static)
- current_hour_average_price (NEW - uses rolling hour aggregation)
- next_hour_average_price (NEW - uses rolling hour aggregation)
* Added imports for aggregate_level_data and find_rolling_hour_center_index
Documentation:
- sensor/definitions.py:
* Updated 30+ sensor descriptions with detailed icon behavior comments
* Changed next_interval_price from static to dynamic icon
* Documented dynamic vs static icons for all sensor types
* Added clear icon mapping source documentation
SENSOR KEY RENAMING:
Renamed for clarity (current_hour_average → current_hour_average_price):
- sensor/core.py: Updated value getters and cached data lookup
- sensor/definitions.py: Updated entity descriptions
- sensor/attributes.py: Updated key references in attribute builders
- coordinator.py: Updated TIME_SENSITIVE_ENTITY_KEYS set
- const.py: Updated comment documentation
Translation Updates:
- custom_translations/*.json (5 files): Updated sensor keys
- translations/*.json (5 files): Updated sensor keys
Impact:
- All sensors now have timestamp attribute showing applicable time/interval
- Icon system provides richer visual feedback for more sensor types
- Consistent sensor naming improves code readability
- Users get temporal context for all sensor values
- Dynamic icons adapt to price conditions across more sensors
This commit is contained in:
parent
b32679ba75
commit
22165d038d
16 changed files with 211 additions and 81 deletions
|
|
@ -267,7 +267,7 @@ PRICE_LEVEL_COLOR_MAPPING = {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Icon mapping for current price sensors (dynamic icons based on price level)
|
# Icon mapping for current price sensors (dynamic icons based on price level)
|
||||||
# Used by current_interval_price and current_hour_average sensors
|
# Used by current_interval_price and current_hour_average_price sensors
|
||||||
# Icon shows price level (cheap/normal/expensive), icon_color reinforces with color
|
# Icon shows price level (cheap/normal/expensive), icon_color reinforces with color
|
||||||
PRICE_LEVEL_CASH_ICON_MAPPING = {
|
PRICE_LEVEL_CASH_ICON_MAPPING = {
|
||||||
PRICE_LEVEL_VERY_CHEAP: "mdi:cash-multiple", # Many coins (save a lot!)
|
PRICE_LEVEL_VERY_CHEAP: "mdi:cash-multiple", # Many coins (save a lot!)
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,8 @@ TIME_SENSITIVE_ENTITY_KEYS = frozenset(
|
||||||
"next_interval_price_level",
|
"next_interval_price_level",
|
||||||
"previous_interval_price_level",
|
"previous_interval_price_level",
|
||||||
# Rolling hour calculations (5-interval windows)
|
# Rolling hour calculations (5-interval windows)
|
||||||
"current_hour_average",
|
"current_hour_average_price",
|
||||||
"next_hour_average",
|
"next_hour_average_price",
|
||||||
"current_hour_price_level",
|
"current_hour_price_level",
|
||||||
"next_hour_price_level",
|
"next_hour_price_level",
|
||||||
# Current/next/previous price ratings
|
# Current/next/previous price ratings
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
"long_description": "Zeigt den Preis für das vorherige 15-Minuten-Intervall von deinem Tibber-Abonnement an",
|
"long_description": "Zeigt den Preis für das vorherige 15-Minuten-Intervall von deinem Tibber-Abonnement an",
|
||||||
"usage_tips": "Nutze dies, um vergangene Preisänderungen zu überprüfen oder den Preisverlauf zu verfolgen"
|
"usage_tips": "Nutze dies, um vergangene Preisänderungen zu überprüfen oder den Preisverlauf zu verfolgen"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"description": "Gleitender 5-Intervall-Durchschnittspreis pro kWh",
|
"description": "Gleitender 5-Intervall-Durchschnittspreis pro kWh",
|
||||||
"long_description": "Zeigt den durchschnittlichen Preis pro kWh berechnet aus 5 Intervallen: 2 vorherige, aktuelles und 2 nächste Intervalle (ca. 75 Minuten insgesamt). Dies bietet einen geglätteten 'Stundenpreis', der sich mit der Zeit anpasst, anstatt an feste Uhrzeiten gebunden zu sein.",
|
"long_description": "Zeigt den durchschnittlichen Preis pro kWh berechnet aus 5 Intervallen: 2 vorherige, aktuelles und 2 nächste Intervalle (ca. 75 Minuten insgesamt). Dies bietet einen geglätteten 'Stundenpreis', der sich mit der Zeit anpasst, anstatt an feste Uhrzeiten gebunden zu sein.",
|
||||||
"usage_tips": "Nutze dies für einen stabileren Preisindikator, der kurzfristige Schwankungen glättet und dennoch auf Preisänderungen reagiert. Besser als feste Stundenpreise für Verbrauchsentscheidungen."
|
"usage_tips": "Nutze dies für einen stabileren Preisindikator, der kurzfristige Schwankungen glättet und dennoch auf Preisänderungen reagiert. Besser als feste Stundenpreise für Verbrauchsentscheidungen."
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"description": "Gleitender 5-Intervall-Durchschnittspreis für nächste Stunde pro kWh",
|
"description": "Gleitender 5-Intervall-Durchschnittspreis für nächste Stunde pro kWh",
|
||||||
"long_description": "Zeigt den durchschnittlichen Preis pro kWh berechnet aus 5 Intervallen, die eine Stunde voraus zentriert sind: ungefähr Intervalle +2 bis +6 von jetzt (Minuten +30 bis +105 abdeckend). Dies bietet einen vorausschauenden geglätteten 'Stundenpreis' zur Verbrauchsplanung.",
|
"long_description": "Zeigt den durchschnittlichen Preis pro kWh berechnet aus 5 Intervallen, die eine Stunde voraus zentriert sind: ungefähr Intervalle +2 bis +6 von jetzt (Minuten +30 bis +105 abdeckend). Dies bietet einen vorausschauenden geglätteten 'Stundenpreis' zur Verbrauchsplanung.",
|
||||||
"usage_tips": "Nutze dies, um Preisänderungen in der nächsten Stunde vorherzusehen. Hilfreich für die Planung von verbrauchsintensiven Aktivitäten wie Elektrofahrzeug-Laden, Geschirrspüler oder Heizsysteme."
|
"usage_tips": "Nutze dies, um Preisänderungen in der nächsten Stunde vorherzusehen. Hilfreich für die Planung von verbrauchsintensiven Aktivitäten wie Elektrofahrzeug-Laden, Geschirrspüler oder Heizsysteme."
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
},
|
},
|
||||||
"next_avg_1h": {
|
"next_avg_1h": {
|
||||||
"description": "Durchschnittspreis für die nächste 1 Stunde (vorwärts-blickend ab nächstem Intervall)",
|
"description": "Durchschnittspreis für die nächste 1 Stunde (vorwärts-blickend ab nächstem Intervall)",
|
||||||
"long_description": "Vorwärts-blickender Durchschnitt: Zeigt den Durchschnitt der nächsten 4 Intervalle (1 Stunde) beginnend ab dem NÄCHSTEN 15-Minuten-Intervall (aktuelles nicht inkludiert). Unterscheidet sich von current_hour_average, das vergangene Intervalle einbezieht. Nutze dies für absolute Preisschwellen-Planung.",
|
"long_description": "Vorwärts-blickender Durchschnitt: Zeigt den Durchschnitt der nächsten 4 Intervalle (1 Stunde) beginnend ab dem NÄCHSTEN 15-Minuten-Intervall (aktuelles nicht inkludiert). Unterscheidet sich von current_hour_average_price, das vergangene Intervalle einbezieht. Nutze dies für absolute Preisschwellen-Planung.",
|
||||||
"usage_tips": "Absolute Preisschwelle: Starte Geräte nur, wenn der Durchschnitt unter deinem maximal akzeptablen Preis bleibt (z.B. unter 0,25 EUR/kWh). Kombiniere mit Trend-Sensor für optimales Timing. Hinweis: Dies ist KEIN Ersatz für Stundenpreise - nutze current_hour_average dafür."
|
"usage_tips": "Absolute Preisschwelle: Starte Geräte nur, wenn der Durchschnitt unter deinem maximal akzeptablen Preis bleibt (z.B. unter 0,25 EUR/kWh). Kombiniere mit Trend-Sensor für optimales Timing. Hinweis: Dies ist KEIN Ersatz für Stundenpreise - nutze current_hour_average_price dafür."
|
||||||
},
|
},
|
||||||
"next_avg_2h": {
|
"next_avg_2h": {
|
||||||
"description": "Durchschnittspreis für die nächsten 2 Stunden",
|
"description": "Durchschnittspreis für die nächsten 2 Stunden",
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
"long_description": "Shows the price for the previous 15-minute interval from your Tibber subscription",
|
"long_description": "Shows the price for the previous 15-minute interval from your Tibber subscription",
|
||||||
"usage_tips": "Use this to review past price changes or track price history"
|
"usage_tips": "Use this to review past price changes or track price history"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"description": "Rolling 5-interval average price per kWh",
|
"description": "Rolling 5-interval average price per kWh",
|
||||||
"long_description": "Shows the average price per kWh calculated from 5 intervals: 2 previous, current, and 2 next intervals (approximately 75 minutes total). This provides a smoothed 'hour price' that adapts as time moves, rather than being fixed to clock hours.",
|
"long_description": "Shows the average price per kWh calculated from 5 intervals: 2 previous, current, and 2 next intervals (approximately 75 minutes total). This provides a smoothed 'hour price' that adapts as time moves, rather than being fixed to clock hours.",
|
||||||
"usage_tips": "Use this for a more stable price indicator that smooths out short-term fluctuations while still being responsive to price changes. Better than fixed hourly prices for making consumption decisions."
|
"usage_tips": "Use this for a more stable price indicator that smooths out short-term fluctuations while still being responsive to price changes. Better than fixed hourly prices for making consumption decisions."
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"description": "Rolling 5-interval average price for next hour per kWh",
|
"description": "Rolling 5-interval average price for next hour per kWh",
|
||||||
"long_description": "Shows the average price per kWh calculated from 5 intervals centered one hour ahead: approximately intervals +2 through +6 from now (covering minutes +30 to +105). This provides a forward-looking smoothed 'hour price' for planning consumption.",
|
"long_description": "Shows the average price per kWh calculated from 5 intervals centered one hour ahead: approximately intervals +2 through +6 from now (covering minutes +30 to +105). This provides a forward-looking smoothed 'hour price' for planning consumption.",
|
||||||
"usage_tips": "Use this to anticipate price changes in the next hour. Helpful for scheduling high-consumption activities like charging electric vehicles, running dishwashers, or heating systems."
|
"usage_tips": "Use this to anticipate price changes in the next hour. Helpful for scheduling high-consumption activities like charging electric vehicles, running dishwashers, or heating systems."
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
},
|
},
|
||||||
"next_avg_1h": {
|
"next_avg_1h": {
|
||||||
"description": "Average price for the next 1 hour (forward-only from next interval)",
|
"description": "Average price for the next 1 hour (forward-only from next interval)",
|
||||||
"long_description": "Forward-looking average: Shows average of next 4 intervals (1 hour) starting from the NEXT 15-minute interval (not including current). Different from current_hour_average which includes past intervals. Use for absolute price threshold planning.",
|
"long_description": "Forward-looking average: Shows average of next 4 intervals (1 hour) starting from the NEXT 15-minute interval (not including current). Different from current_hour_average_price which includes past intervals. Use for absolute price threshold planning.",
|
||||||
"usage_tips": "Absolute price threshold: Only start appliances when average stays below your maximum acceptable price (e.g., below 0.25 EUR/kWh). Combine with trend sensor for optimal timing. Note: This is NOT a replacement for hourly prices - use current_hour_average for that."
|
"usage_tips": "Absolute price threshold: Only start appliances when average stays below your maximum acceptable price (e.g., below 0.25 EUR/kWh). Combine with trend sensor for optimal timing. Note: This is NOT a replacement for hourly prices - use current_hour_average_price for that."
|
||||||
},
|
},
|
||||||
"next_avg_2h": {
|
"next_avg_2h": {
|
||||||
"description": "Average price for the next 2 hours",
|
"description": "Average price for the next 2 hours",
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
"long_description": "Viser prisen for det forrige 15-minutters intervallet fra ditt Tibber-abonnement",
|
"long_description": "Viser prisen for det forrige 15-minutters intervallet fra ditt Tibber-abonnement",
|
||||||
"usage_tips": "Bruk dette til å gjennomgå tidligere prisendringer eller spore prishistorikk"
|
"usage_tips": "Bruk dette til å gjennomgå tidligere prisendringer eller spore prishistorikk"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"description": "Rullende 5-intervalls gjennomsnittspris per kWh",
|
"description": "Rullende 5-intervalls gjennomsnittspris per kWh",
|
||||||
"long_description": "Viser gjennomsnittsprisen per kWh beregnet fra 5 intervaller: 2 foregående, nåværende og 2 neste intervaller (omtrent 75 minutter totalt). Dette gir en utjevnet 'timepris' som tilpasser seg etter hvert som tiden går, i stedet for å være fiksert til klokkeslett.",
|
"long_description": "Viser gjennomsnittsprisen per kWh beregnet fra 5 intervaller: 2 foregående, nåværende og 2 neste intervaller (omtrent 75 minutter totalt). Dette gir en utjevnet 'timepris' som tilpasser seg etter hvert som tiden går, i stedet for å være fiksert til klokkeslett.",
|
||||||
"usage_tips": "Bruk dette for en mer stabil prisindikator som jevner ut kortsiktige svingninger mens den fortsatt er responsiv til prisendringer. Bedre enn faste timepriser for å ta forbruksbeslutninger."
|
"usage_tips": "Bruk dette for en mer stabil prisindikator som jevner ut kortsiktige svingninger mens den fortsatt er responsiv til prisendringer. Bedre enn faste timepriser for å ta forbruksbeslutninger."
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"description": "Rullende 5-intervalls gjennomsnittspris for neste time per kWh",
|
"description": "Rullende 5-intervalls gjennomsnittspris for neste time per kWh",
|
||||||
"long_description": "Viser gjennomsnittsprisen per kWh beregnet fra 5 intervaller sentrert en time frem: omtrent intervallene +2 til +6 fra nå (dekker minutter +30 til +105). Dette gir en fremtidsrettet utjevnet 'timepris' for å planlegge forbruk.",
|
"long_description": "Viser gjennomsnittsprisen per kWh beregnet fra 5 intervaller sentrert en time frem: omtrent intervallene +2 til +6 fra nå (dekker minutter +30 til +105). Dette gir en fremtidsrettet utjevnet 'timepris' for å planlegge forbruk.",
|
||||||
"usage_tips": "Bruk dette til å forutse prisendringer i neste time. Nyttig for å planlegge høyforbruksaktiviteter som lading av elbiler, kjøring av oppvaskmaskiner eller varmesystemer."
|
"usage_tips": "Bruk dette til å forutse prisendringer i neste time. Nyttig for å planlegge høyforbruksaktiviteter som lading av elbiler, kjøring av oppvaskmaskiner eller varmesystemer."
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
},
|
},
|
||||||
"next_avg_1h": {
|
"next_avg_1h": {
|
||||||
"description": "Gjennomsnittspris for neste 1 time (kun fremover fra neste intervall)",
|
"description": "Gjennomsnittspris for neste 1 time (kun fremover fra neste intervall)",
|
||||||
"long_description": "Fremtidsrettet gjennomsnitt: Viser gjennomsnitt av neste 4 intervaller (1 time) fra og med NESTE 15-minutters intervall (ikke inkludert nåværende). Forskjellig fra current_hour_average som inkluderer tidligere intervaller. Bruk for planlegging med absolutt pristerskel.",
|
"long_description": "Fremtidsrettet gjennomsnitt: Viser gjennomsnitt av neste 4 intervaller (1 time) fra og med NESTE 15-minutters intervall (ikke inkludert nåværende). Forskjellig fra current_hour_average_price som inkluderer tidligere intervaller. Bruk for planlegging med absolutt pristerskel.",
|
||||||
"usage_tips": "Absolutt pristerskel: Start kun apparater når gjennomsnittet forblir under din maksimalt akseptable pris (f.eks. under 0,25 EUR/kWh). Kombiner med trendsensor for optimal timing. Merk: Dette er IKKE en erstatning for timepriser - bruk current_hour_average for det."
|
"usage_tips": "Absolutt pristerskel: Start kun apparater når gjennomsnittet forblir under din maksimalt akseptable pris (f.eks. under 0,25 EUR/kWh). Kombiner med trendsensor for optimal timing. Merk: Dette er IKKE en erstatning for timepriser - bruk current_hour_average_price for det."
|
||||||
},
|
},
|
||||||
"next_avg_2h": {
|
"next_avg_2h": {
|
||||||
"description": "Gjennomsnittspris for neste 2 timer",
|
"description": "Gjennomsnittspris for neste 2 timer",
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
"long_description": "Toont de prijs voor het vorige 15-minuten interval van uw Tibber-abonnement",
|
"long_description": "Toont de prijs voor het vorige 15-minuten interval van uw Tibber-abonnement",
|
||||||
"usage_tips": "Gebruik dit om eerdere prijswijzigingen te bekijken of prijsgeschiedenis bij te houden"
|
"usage_tips": "Gebruik dit om eerdere prijswijzigingen te bekijken of prijsgeschiedenis bij te houden"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"description": "Voortschrijdend 5-interval gemiddelde prijs per kWh",
|
"description": "Voortschrijdend 5-interval gemiddelde prijs per kWh",
|
||||||
"long_description": "Toont de gemiddelde prijs per kWh berekend uit 5 intervallen: 2 vorige, huidige en 2 volgende intervallen (ongeveer 75 minuten totaal). Dit biedt een vloeiende 'uurprijs' die zich aanpast naarmate de tijd verstrijkt, in plaats van vast te zitten aan klokuren.",
|
"long_description": "Toont de gemiddelde prijs per kWh berekend uit 5 intervallen: 2 vorige, huidige en 2 volgende intervallen (ongeveer 75 minuten totaal). Dit biedt een vloeiende 'uurprijs' die zich aanpast naarmate de tijd verstrijkt, in plaats van vast te zitten aan klokuren.",
|
||||||
"usage_tips": "Gebruik dit voor een stabielere prijsindicator die korte schommelingen afvlakt terwijl deze nog steeds reageert op prijswijzigingen. Beter dan vaste uurprijzen voor verbruiksbeslissingen."
|
"usage_tips": "Gebruik dit voor een stabielere prijsindicator die korte schommelingen afvlakt terwijl deze nog steeds reageert op prijswijzigingen. Beter dan vaste uurprijzen voor verbruiksbeslissingen."
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"description": "Voortschrijdend 5-interval gemiddelde prijs voor volgend uur per kWh",
|
"description": "Voortschrijdend 5-interval gemiddelde prijs voor volgend uur per kWh",
|
||||||
"long_description": "Toont de gemiddelde prijs per kWh berekend uit 5 intervallen gecentreerd één uur vooruit: ongeveer intervallen +2 tot +6 vanaf nu (dekking van minuten +30 tot +105). Dit biedt een vooruitkijkende vloeiende 'uurprijs' voor verbruiksplanning.",
|
"long_description": "Toont de gemiddelde prijs per kWh berekend uit 5 intervallen gecentreerd één uur vooruit: ongeveer intervallen +2 tot +6 vanaf nu (dekking van minuten +30 tot +105). Dit biedt een vooruitkijkende vloeiende 'uurprijs' voor verbruiksplanning.",
|
||||||
"usage_tips": "Gebruik dit om prijswijzigingen in het volgende uur te anticiperen. Handig voor het plannen van activiteiten met hoog verbruik zoals het opladen van elektrische voertuigen, het draaien van vaatwassers of verwarmingssystemen."
|
"usage_tips": "Gebruik dit om prijswijzigingen in het volgende uur te anticiperen. Handig voor het plannen van activiteiten met hoog verbruik zoals het opladen van elektrische voertuigen, het draaien van vaatwassers of verwarmingssystemen."
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
},
|
},
|
||||||
"next_avg_1h": {
|
"next_avg_1h": {
|
||||||
"description": "Gemiddelde prijs voor het volgende 1 uur (alleen vooruit vanaf volgend interval)",
|
"description": "Gemiddelde prijs voor het volgende 1 uur (alleen vooruit vanaf volgend interval)",
|
||||||
"long_description": "Vooruitkijkend gemiddelde: Toont gemiddelde van volgende 4 intervallen (1 uur) vanaf het VOLGENDE 15-minuten interval (niet inclusief huidig). Verschilt van current_hour_average die vorige intervallen omvat. Gebruik voor absolute prijsdrempelplanning.",
|
"long_description": "Vooruitkijkend gemiddelde: Toont gemiddelde van volgende 4 intervallen (1 uur) vanaf het VOLGENDE 15-minuten interval (niet inclusief huidig). Verschilt van current_hour_average_price die vorige intervallen omvat. Gebruik voor absolute prijsdrempelplanning.",
|
||||||
"usage_tips": "Absolute prijsdrempel: Start apparaten alleen wanneer het gemiddelde onder uw maximaal acceptabele prijs blijft (bijv. onder 0,25 EUR/kWh). Combineer met trendsensor voor optimale timing. Let op: Dit is GEEN vervanging voor uurprijzen - gebruik current_hour_average daarvoor."
|
"usage_tips": "Absolute prijsdrempel: Start apparaten alleen wanneer het gemiddelde onder uw maximaal acceptabele prijs blijft (bijv. onder 0,25 EUR/kWh). Combineer met trendsensor voor optimale timing. Let op: Dit is GEEN vervanging voor uurprijzen - gebruik current_hour_average_price daarvoor."
|
||||||
},
|
},
|
||||||
"next_avg_2h": {
|
"next_avg_2h": {
|
||||||
"description": "Gemiddelde prijs voor de volgende 2 uur",
|
"description": "Gemiddelde prijs voor de volgende 2 uur",
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
"long_description": "Visar priset för föregående 15-minuters intervall från ditt Tibber-abonnemang",
|
"long_description": "Visar priset för föregående 15-minuters intervall från ditt Tibber-abonnemang",
|
||||||
"usage_tips": "Använd detta för att granska tidigare prisändringar eller spåra prishistorik"
|
"usage_tips": "Använd detta för att granska tidigare prisändringar eller spåra prishistorik"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"description": "Rullande 5-intervalls genomsnittspris per kWh",
|
"description": "Rullande 5-intervalls genomsnittspris per kWh",
|
||||||
"long_description": "Visar genomsnittspriset per kWh beräknat från 5 intervaller: 2 föregående, nuvarande och 2 nästa intervaller (ungefär 75 minuter totalt). Detta ger ett utjämnat 'timpris' som anpassar sig när tiden går, istället för att vara fixerat till klockslag.",
|
"long_description": "Visar genomsnittspriset per kWh beräknat från 5 intervaller: 2 föregående, nuvarande och 2 nästa intervaller (ungefär 75 minuter totalt). Detta ger ett utjämnat 'timpris' som anpassar sig när tiden går, istället för att vara fixerat till klockslag.",
|
||||||
"usage_tips": "Använd detta för en stabilare prisindikator som jämnar ut kortsiktiga fluktuationer medan den fortfarande är responsiv till prisändringar. Bättre än fasta timpriser för konsumtionsbeslut."
|
"usage_tips": "Använd detta för en stabilare prisindikator som jämnar ut kortsiktiga fluktuationer medan den fortfarande är responsiv till prisändringar. Bättre än fasta timpriser för konsumtionsbeslut."
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"description": "Rullande 5-intervalls genomsnittspris för nästa timme per kWh",
|
"description": "Rullande 5-intervalls genomsnittspris för nästa timme per kWh",
|
||||||
"long_description": "Visar genomsnittspriset per kWh beräknat från 5 intervaller centrerade en timme framåt: ungefär intervaller +2 till +6 från nu (täcker minuter +30 till +105). Detta ger ett framåtblickande utjämnat 'timpris' för konsumtionsplanering.",
|
"long_description": "Visar genomsnittspriset per kWh beräknat från 5 intervaller centrerade en timme framåt: ungefär intervaller +2 till +6 från nu (täcker minuter +30 till +105). Detta ger ett framåtblickande utjämnat 'timpris' för konsumtionsplanering.",
|
||||||
"usage_tips": "Använd detta för att förutse prisändringar nästa timme. Användbart för att schemalägga högkonsumtionsaktiviteter som laddning av elfordon, körning av diskmaskiner eller värmesystem."
|
"usage_tips": "Använd detta för att förutse prisändringar nästa timme. Användbart för att schemalägga högkonsumtionsaktiviteter som laddning av elfordon, körning av diskmaskiner eller värmesystem."
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
},
|
},
|
||||||
"next_avg_1h": {
|
"next_avg_1h": {
|
||||||
"description": "Genomsnittspris för nästa 1 timme (endast framåt från nästa intervall)",
|
"description": "Genomsnittspris för nästa 1 timme (endast framåt från nästa intervall)",
|
||||||
"long_description": "Framåtblickande genomsnitt: Visar genomsnitt av nästa 4 intervaller (1 timme) från och med NÄSTA 15-minuters intervall (inte inklusive nuvarande). Skiljer sig från current_hour_average som inkluderar tidigare intervaller. Använd för absolut priströskelpla nering.",
|
"long_description": "Framåtblickande genomsnitt: Visar genomsnitt av nästa 4 intervaller (1 timme) från och med NÄSTA 15-minuters intervall (inte inklusive nuvarande). Skiljer sig från current_hour_average_price som inkluderar tidigare intervaller. Använd för absolut priströskelpla nering.",
|
||||||
"usage_tips": "Absolut priströskel: Starta endast apparater när genomsnittet stannar under ditt maximalt acceptabla pris (t.ex. under 0,25 EUR/kWh). Kombinera med trendsensor för optimal timing. Obs: Detta är INTE en ersättning för timpriser - använd current_hour_average för det."
|
"usage_tips": "Absolut priströskel: Starta endast apparater när genomsnittet stannar under ditt maximalt acceptabla pris (t.ex. under 0,25 EUR/kWh). Kombinera med trendsensor för optimal timing. Obs: Detta är INTE en ersättning för timpriser - använd current_hour_average_price för det."
|
||||||
},
|
},
|
||||||
"next_avg_2h": {
|
"next_avg_2h": {
|
||||||
"description": "Genomsnittspris för nästa 2 timmar",
|
"description": "Genomsnittspris för nästa 2 timmar",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ from custom_components.tibber_prices.const import (
|
||||||
VOLATILITY_ICON_MAPPING,
|
VOLATILITY_ICON_MAPPING,
|
||||||
)
|
)
|
||||||
from custom_components.tibber_prices.price_utils import find_price_data_for_interval
|
from custom_components.tibber_prices.price_utils import find_price_data_for_interval
|
||||||
|
from custom_components.tibber_prices.sensor.helpers import (
|
||||||
|
aggregate_level_data,
|
||||||
|
find_rolling_hour_center_index,
|
||||||
|
)
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -74,8 +78,9 @@ def get_price_sensor_icon(key: str, coordinator_data: dict | None) -> str | None
|
||||||
"""
|
"""
|
||||||
Get icon for current price sensors (dynamic based on price level).
|
Get icon for current price sensors (dynamic based on price level).
|
||||||
|
|
||||||
Only current_interval_price and current_hour_average have dynamic icons.
|
Dynamic icons for: current_interval_price, next_interval_price,
|
||||||
Other price sensors (next/previous) use static icons from entity description.
|
current_hour_average_price, next_hour_average_price
|
||||||
|
Other price sensors (previous interval) use static icons from entity description.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
key: Entity description key
|
key: Entity description key
|
||||||
|
|
@ -93,10 +98,21 @@ def get_price_sensor_icon(key: str, coordinator_data: dict | None) -> str | None
|
||||||
level = get_price_level_for_icon(coordinator_data, interval_offset=0)
|
level = get_price_level_for_icon(coordinator_data, interval_offset=0)
|
||||||
if level:
|
if level:
|
||||||
return PRICE_LEVEL_CASH_ICON_MAPPING.get(level.upper())
|
return PRICE_LEVEL_CASH_ICON_MAPPING.get(level.upper())
|
||||||
elif key == "current_hour_average":
|
elif key == "next_interval_price":
|
||||||
# For hour average, we cannot use this helper (needs sensor rolling hour logic)
|
# For next interval, use the next interval price level to determine icon
|
||||||
# Return None and let sensor handle it
|
level = get_price_level_for_icon(coordinator_data, interval_offset=1)
|
||||||
return None
|
if level:
|
||||||
|
return PRICE_LEVEL_CASH_ICON_MAPPING.get(level.upper())
|
||||||
|
elif key == "current_hour_average_price":
|
||||||
|
# For current hour average, use the current hour price level to determine icon
|
||||||
|
level = get_rolling_hour_price_level_for_icon(coordinator_data, hour_offset=0)
|
||||||
|
if level:
|
||||||
|
return PRICE_LEVEL_CASH_ICON_MAPPING.get(level.upper())
|
||||||
|
elif key == "next_hour_average_price":
|
||||||
|
# For next hour average, use the next hour price level to determine icon
|
||||||
|
level = get_rolling_hour_price_level_for_icon(coordinator_data, hour_offset=1)
|
||||||
|
if level:
|
||||||
|
return PRICE_LEVEL_CASH_ICON_MAPPING.get(level.upper())
|
||||||
|
|
||||||
# For all other price sensors, let entity description handle the icon
|
# For all other price sensors, let entity description handle the icon
|
||||||
return None
|
return None
|
||||||
|
|
@ -210,3 +226,54 @@ def get_price_level_for_icon(
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return interval_data["level"]
|
return interval_data["level"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_rolling_hour_price_level_for_icon(
|
||||||
|
coordinator_data: dict,
|
||||||
|
*,
|
||||||
|
hour_offset: int = 0,
|
||||||
|
) -> str | None:
|
||||||
|
"""
|
||||||
|
Get the aggregated price level for rolling hour icon determination.
|
||||||
|
|
||||||
|
Uses the same logic as the sensor platform: 5-interval rolling window
|
||||||
|
(2 before + center + 2 after) to determine the price level.
|
||||||
|
|
||||||
|
This ensures icon calculation matches the actual sensor value calculation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
coordinator_data: Coordinator data
|
||||||
|
hour_offset: Hour offset (0=current hour, 1=next hour)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Aggregated price level string or None if not found
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not coordinator_data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
price_info = coordinator_data.get("priceInfo", {})
|
||||||
|
all_prices = price_info.get("yesterday", []) + price_info.get("today", []) + price_info.get("tomorrow", [])
|
||||||
|
|
||||||
|
if not all_prices:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Find center index using the same helper function as the sensor platform
|
||||||
|
now = dt_util.now()
|
||||||
|
center_idx = find_rolling_hour_center_index(all_prices, now, hour_offset)
|
||||||
|
|
||||||
|
if center_idx is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Collect data from 5-interval window (-2, -1, 0, +1, +2) - same as sensor platform
|
||||||
|
window_data = []
|
||||||
|
for offset in range(-2, 3):
|
||||||
|
idx = center_idx + offset
|
||||||
|
if 0 <= idx < len(all_prices):
|
||||||
|
window_data.append(all_prices[idx])
|
||||||
|
|
||||||
|
if not window_data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Use the same aggregation function as the sensor platform
|
||||||
|
return aggregate_level_data(window_data)
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ def build_sensor_attributes(
|
||||||
"current_interval_price_level",
|
"current_interval_price_level",
|
||||||
"next_interval_price",
|
"next_interval_price",
|
||||||
"previous_interval_price",
|
"previous_interval_price",
|
||||||
"current_hour_average",
|
"current_hour_average_price",
|
||||||
"next_hour_average",
|
"next_hour_average_price",
|
||||||
"next_interval_price_level",
|
"next_interval_price_level",
|
||||||
"previous_interval_price_level",
|
"previous_interval_price_level",
|
||||||
"current_hour_price_level",
|
"current_hour_price_level",
|
||||||
|
|
@ -185,12 +185,12 @@ def add_current_interval_price_attributes(
|
||||||
"previous_interval_price_rating",
|
"previous_interval_price_rating",
|
||||||
]
|
]
|
||||||
next_hour_sensors = [
|
next_hour_sensors = [
|
||||||
"next_hour_average",
|
"next_hour_average_price",
|
||||||
"next_hour_price_level",
|
"next_hour_price_level",
|
||||||
"next_hour_price_rating",
|
"next_hour_price_rating",
|
||||||
]
|
]
|
||||||
current_hour_sensors = [
|
current_hour_sensors = [
|
||||||
"current_hour_average",
|
"current_hour_average_price",
|
||||||
"current_hour_price_level",
|
"current_hour_price_level",
|
||||||
"current_hour_price_rating",
|
"current_hour_price_rating",
|
||||||
]
|
]
|
||||||
|
|
@ -214,6 +214,7 @@ def add_current_interval_price_attributes(
|
||||||
attributes["timestamp"] = current_interval_data["startsAt"] if current_interval_data else None
|
attributes["timestamp"] = current_interval_data["startsAt"] if current_interval_data else None
|
||||||
else:
|
else:
|
||||||
current_interval_data = get_current_interval_data(coordinator)
|
current_interval_data = get_current_interval_data(coordinator)
|
||||||
|
interval_data = current_interval_data # Use current_interval_data as interval_data for current_interval_price
|
||||||
attributes["timestamp"] = current_interval_data["startsAt"] if current_interval_data else None
|
attributes["timestamp"] = current_interval_data["startsAt"] if current_interval_data else None
|
||||||
|
|
||||||
# Add icon_color for price sensors (based on their price level)
|
# Add icon_color for price sensors (based on their price level)
|
||||||
|
|
@ -222,7 +223,7 @@ def add_current_interval_price_attributes(
|
||||||
if interval_data and "level" in interval_data:
|
if interval_data and "level" in interval_data:
|
||||||
level = interval_data["level"]
|
level = interval_data["level"]
|
||||||
add_icon_color_attribute(attributes, key="price_level", state_value=level)
|
add_icon_color_attribute(attributes, key="price_level", state_value=level)
|
||||||
elif key in ["current_hour_average", "next_hour_average"]:
|
elif key in ["current_hour_average_price", "next_hour_average_price"]:
|
||||||
# For hour-based price sensors, get level from cached_data
|
# For hour-based price sensors, get level from cached_data
|
||||||
level = cached_data.get("rolling_hour_level")
|
level = cached_data.get("rolling_hour_level")
|
||||||
if level:
|
if level:
|
||||||
|
|
@ -454,7 +455,7 @@ def add_average_price_attributes(
|
||||||
coordinator: TibberPricesDataUpdateCoordinator,
|
coordinator: TibberPricesDataUpdateCoordinator,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Add attributes for trailing and leading average price sensors.
|
Add attributes for trailing and leading average/min/max price sensors.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
attributes: Dictionary to add attributes to
|
attributes: Dictionary to add attributes to
|
||||||
|
|
@ -485,8 +486,11 @@ def add_average_price_attributes(
|
||||||
window_start = now
|
window_start = now
|
||||||
window_end = now + timedelta(hours=24)
|
window_end = now + timedelta(hours=24)
|
||||||
|
|
||||||
# Find all intervals in the window and get first/last timestamps
|
# Find all intervals in the window
|
||||||
intervals_in_window = []
|
intervals_in_window = []
|
||||||
|
extreme_interval = None # Track interval with min/max for min/max sensors
|
||||||
|
is_min_max_sensor = "min" in key or "max" in key
|
||||||
|
|
||||||
for price_data in all_prices:
|
for price_data in all_prices:
|
||||||
starts_at = dt_util.parse_datetime(price_data["startsAt"])
|
starts_at = dt_util.parse_datetime(price_data["startsAt"])
|
||||||
if starts_at is None:
|
if starts_at is None:
|
||||||
|
|
@ -495,12 +499,49 @@ def add_average_price_attributes(
|
||||||
if window_start <= starts_at < window_end:
|
if window_start <= starts_at < window_end:
|
||||||
intervals_in_window.append(price_data)
|
intervals_in_window.append(price_data)
|
||||||
|
|
||||||
# Add timestamp attribute (first interval in the window)
|
# Track extreme interval for min/max sensors
|
||||||
|
if is_min_max_sensor:
|
||||||
|
extreme_interval = _update_extreme_interval(extreme_interval, price_data, key)
|
||||||
|
|
||||||
|
# Add timestamp attribute
|
||||||
if intervals_in_window:
|
if intervals_in_window:
|
||||||
|
# For min/max sensors: use the timestamp of the interval with extreme price
|
||||||
|
# For average sensors: use first interval in the window
|
||||||
|
if extreme_interval and is_min_max_sensor:
|
||||||
|
attributes["timestamp"] = extreme_interval.get("startsAt")
|
||||||
|
else:
|
||||||
attributes["timestamp"] = intervals_in_window[0].get("startsAt")
|
attributes["timestamp"] = intervals_in_window[0].get("startsAt")
|
||||||
|
|
||||||
attributes["interval_count"] = len(intervals_in_window)
|
attributes["interval_count"] = len(intervals_in_window)
|
||||||
|
|
||||||
|
|
||||||
|
def _update_extreme_interval(extreme_interval: dict | None, price_data: dict, key: str) -> dict:
|
||||||
|
"""
|
||||||
|
Update extreme interval for min/max sensors.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
extreme_interval: Current extreme interval or None
|
||||||
|
price_data: New price data to compare
|
||||||
|
key: Sensor key to determine if min or max
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Updated extreme interval
|
||||||
|
|
||||||
|
"""
|
||||||
|
if extreme_interval is None:
|
||||||
|
return price_data
|
||||||
|
|
||||||
|
price = price_data.get("total")
|
||||||
|
extreme_price = extreme_interval.get("total")
|
||||||
|
|
||||||
|
if price is None or extreme_price is None:
|
||||||
|
return extreme_interval
|
||||||
|
|
||||||
|
is_new_extreme = ("min" in key and price < extreme_price) or ("max" in key and price > extreme_price)
|
||||||
|
|
||||||
|
return price_data if is_new_extreme else extreme_interval
|
||||||
|
|
||||||
|
|
||||||
def add_next_avg_attributes(
|
def add_next_avg_attributes(
|
||||||
attributes: dict,
|
attributes: dict,
|
||||||
key: str,
|
key: str,
|
||||||
|
|
@ -724,7 +765,21 @@ def add_volatility_type_attributes(
|
||||||
thresholds: Volatility thresholds configuration
|
thresholds: Volatility thresholds configuration
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if volatility_type == "today_tomorrow":
|
# Add timestamp for calendar day volatility sensors (midnight of the day)
|
||||||
|
if volatility_type == "today":
|
||||||
|
today_data = price_info.get("today", [])
|
||||||
|
if today_data:
|
||||||
|
volatility_attributes["timestamp"] = today_data[0].get("startsAt")
|
||||||
|
elif volatility_type == "tomorrow":
|
||||||
|
tomorrow_data = price_info.get("tomorrow", [])
|
||||||
|
if tomorrow_data:
|
||||||
|
volatility_attributes["timestamp"] = tomorrow_data[0].get("startsAt")
|
||||||
|
elif volatility_type == "today_tomorrow":
|
||||||
|
# For combined today+tomorrow, use today's midnight
|
||||||
|
today_data = price_info.get("today", [])
|
||||||
|
if today_data:
|
||||||
|
volatility_attributes["timestamp"] = today_data[0].get("startsAt")
|
||||||
|
|
||||||
# Add breakdown for today vs tomorrow
|
# Add breakdown for today vs tomorrow
|
||||||
today_prices = [float(p["total"]) for p in price_info.get("today", []) if "total" in p]
|
today_prices = [float(p["total"]) for p in price_info.get("today", []) if "total" in p]
|
||||||
tomorrow_prices = [float(p["total"]) for p in price_info.get("tomorrow", []) if "total" in p]
|
tomorrow_prices = [float(p["total"]) for p in price_info.get("tomorrow", []) if "total" in p]
|
||||||
|
|
@ -742,7 +797,6 @@ def add_volatility_type_attributes(
|
||||||
volatility_attributes["tomorrow_spread"] = round(tomorrow_spread, 2)
|
volatility_attributes["tomorrow_spread"] = round(tomorrow_spread, 2)
|
||||||
volatility_attributes["tomorrow_volatility"] = tomorrow_vol
|
volatility_attributes["tomorrow_volatility"] = tomorrow_vol
|
||||||
volatility_attributes["interval_count_tomorrow"] = len(tomorrow_prices)
|
volatility_attributes["interval_count_tomorrow"] = len(tomorrow_prices)
|
||||||
|
|
||||||
elif volatility_type == "next_24h":
|
elif volatility_type == "next_24h":
|
||||||
# Add time window info
|
# Add time window info
|
||||||
now = dt_util.now()
|
now = dt_util.now()
|
||||||
|
|
|
||||||
|
|
@ -166,8 +166,8 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
|
||||||
"current_hour_price_level": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="level"),
|
"current_hour_price_level": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="level"),
|
||||||
"next_hour_price_level": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="level"),
|
"next_hour_price_level": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="level"),
|
||||||
# Rolling hour average (5 intervals: 2 before + current + 2 after)
|
# Rolling hour average (5 intervals: 2 before + current + 2 after)
|
||||||
"current_hour_average": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="price"),
|
"current_hour_average_price": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="price"),
|
||||||
"next_hour_average": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="price"),
|
"next_hour_average_price": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="price"),
|
||||||
"current_hour_price_rating": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="rating"),
|
"current_hour_price_rating": lambda: self._get_rolling_hour_value(hour_offset=0, value_type="rating"),
|
||||||
"next_hour_price_rating": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="rating"),
|
"next_hour_price_rating": lambda: self._get_rolling_hour_value(hour_offset=1, value_type="rating"),
|
||||||
# ================================================================
|
# ================================================================
|
||||||
|
|
@ -1105,8 +1105,8 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
|
||||||
|
|
||||||
def _get_rolling_hour_level_for_cached_data(self, key: str) -> str | None:
|
def _get_rolling_hour_level_for_cached_data(self, key: str) -> str | None:
|
||||||
"""Get rolling hour level for cached data if needed for icon color."""
|
"""Get rolling hour level for cached data if needed for icon color."""
|
||||||
if key in ["current_hour_average", "next_hour_average"]:
|
if key in ["current_hour_average_price", "next_hour_average_price"]:
|
||||||
hour_offset = 0 if key == "current_hour_average" else 1
|
hour_offset = 0 if key == "current_hour_average_price" else 1
|
||||||
result = self._get_rolling_hour_value(hour_offset=hour_offset, value_type="level")
|
result = self._get_rolling_hour_value(hour_offset=hour_offset, value_type="level")
|
||||||
return result if isinstance(result, str) else None
|
return result if isinstance(result, str) else None
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ INTERVAL_PRICE_SENSORS = (
|
||||||
key="current_interval_price",
|
key="current_interval_price",
|
||||||
translation_key="current_interval_price",
|
translation_key="current_interval_price",
|
||||||
name="Current Electricity Price",
|
name="Current Electricity Price",
|
||||||
icon="mdi:cash", # Dynamic: will show cash-multiple/plus/cash/minus/remove based on level
|
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level
|
||||||
device_class=SensorDeviceClass.MONETARY,
|
device_class=SensorDeviceClass.MONETARY,
|
||||||
suggested_display_precision=2,
|
suggested_display_precision=2,
|
||||||
),
|
),
|
||||||
|
|
@ -60,7 +60,7 @@ INTERVAL_PRICE_SENSORS = (
|
||||||
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-fast", # Static: motion lines indicate "coming soon"
|
icon="mdi:cash", # Dynamic: shows cash-multiple/plus/cash/minus/remove based on price level
|
||||||
device_class=SensorDeviceClass.MONETARY,
|
device_class=SensorDeviceClass.MONETARY,
|
||||||
suggested_display_precision=2,
|
suggested_display_precision=2,
|
||||||
),
|
),
|
||||||
|
|
@ -83,7 +83,7 @@ INTERVAL_LEVEL_SENSORS = (
|
||||||
key="current_interval_price_level",
|
key="current_interval_price_level",
|
||||||
translation_key="current_interval_price_level",
|
translation_key="current_interval_price_level",
|
||||||
name="Current Price Level",
|
name="Current Price Level",
|
||||||
icon="mdi:gauge",
|
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -91,7 +91,7 @@ INTERVAL_LEVEL_SENSORS = (
|
||||||
key="next_interval_price_level",
|
key="next_interval_price_level",
|
||||||
translation_key="next_interval_price_level",
|
translation_key="next_interval_price_level",
|
||||||
name="Next Price Level",
|
name="Next Price Level",
|
||||||
icon="mdi:gauge-empty",
|
icon="mdi:gauge", # Dynamic: shows gauge/gauge-empty/gauge-low/gauge-full based on level value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -99,7 +99,7 @@ INTERVAL_LEVEL_SENSORS = (
|
||||||
key="previous_interval_price_level",
|
key="previous_interval_price_level",
|
||||||
translation_key="previous_interval_price_level",
|
translation_key="previous_interval_price_level",
|
||||||
name="Previous Price Level",
|
name="Previous Price Level",
|
||||||
icon="mdi:gauge-empty",
|
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,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
|
|
@ -114,7 +114,7 @@ INTERVAL_RATING_SENSORS = (
|
||||||
key="current_interval_price_rating",
|
key="current_interval_price_rating",
|
||||||
translation_key="current_interval_price_rating",
|
translation_key="current_interval_price_rating",
|
||||||
name="Current Price Rating",
|
name="Current Price Rating",
|
||||||
icon="mdi:thumbs-up-down",
|
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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
),
|
),
|
||||||
|
|
@ -122,7 +122,7 @@ INTERVAL_RATING_SENSORS = (
|
||||||
key="next_interval_price_rating",
|
key="next_interval_price_rating",
|
||||||
translation_key="next_interval_price_rating",
|
translation_key="next_interval_price_rating",
|
||||||
name="Next Price Rating",
|
name="Next Price Rating",
|
||||||
icon="mdi:thumbs-up-down",
|
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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
),
|
),
|
||||||
|
|
@ -130,7 +130,7 @@ INTERVAL_RATING_SENSORS = (
|
||||||
key="previous_interval_price_rating",
|
key="previous_interval_price_rating",
|
||||||
translation_key="previous_interval_price_rating",
|
translation_key="previous_interval_price_rating",
|
||||||
name="Previous Price Rating",
|
name="Previous Price Rating",
|
||||||
icon="mdi:thumbs-up-down",
|
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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -145,18 +145,18 @@ INTERVAL_RATING_SENSORS = (
|
||||||
|
|
||||||
ROLLING_HOUR_PRICE_SENSORS = (
|
ROLLING_HOUR_PRICE_SENSORS = (
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="current_hour_average",
|
key="current_hour_average_price",
|
||||||
translation_key="current_hour_average",
|
translation_key="current_hour_average_price",
|
||||||
name="Current Hour Average Price",
|
name="Current Hour Average Price",
|
||||||
icon="mdi:cash", # Dynamic: will show cash-multiple/plus/cash/minus/remove based on 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,
|
||||||
suggested_display_precision=1,
|
suggested_display_precision=1,
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="next_hour_average",
|
key="next_hour_average_price",
|
||||||
translation_key="next_hour_average",
|
translation_key="next_hour_average_price",
|
||||||
name="Next Hour Average Price",
|
name="Next Hour Average Price",
|
||||||
icon="mdi:clock-fast", # Static: clock indicates "next time period"
|
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,
|
||||||
suggested_display_precision=1,
|
suggested_display_precision=1,
|
||||||
),
|
),
|
||||||
|
|
@ -170,7 +170,7 @@ ROLLING_HOUR_LEVEL_SENSORS = (
|
||||||
key="current_hour_price_level",
|
key="current_hour_price_level",
|
||||||
translation_key="current_hour_price_level",
|
translation_key="current_hour_price_level",
|
||||||
name="Current Hour Price Level",
|
name="Current Hour Price Level",
|
||||||
icon="mdi:gauge",
|
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,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -178,7 +178,7 @@ ROLLING_HOUR_LEVEL_SENSORS = (
|
||||||
key="next_hour_price_level",
|
key="next_hour_price_level",
|
||||||
translation_key="next_hour_price_level",
|
translation_key="next_hour_price_level",
|
||||||
name="Next Hour Price Level",
|
name="Next Hour Price Level",
|
||||||
icon="mdi:gauge-empty",
|
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,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -192,6 +192,7 @@ ROLLING_HOUR_RATING_SENSORS = (
|
||||||
key="current_hour_price_rating",
|
key="current_hour_price_rating",
|
||||||
translation_key="current_hour_price_rating",
|
translation_key="current_hour_price_rating",
|
||||||
name="Current Hour Price Rating",
|
name="Current Hour Price Rating",
|
||||||
|
# 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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -200,6 +201,7 @@ ROLLING_HOUR_RATING_SENSORS = (
|
||||||
key="next_hour_price_rating",
|
key="next_hour_price_rating",
|
||||||
translation_key="next_hour_price_rating",
|
translation_key="next_hour_price_rating",
|
||||||
name="Next Hour Price Rating",
|
name="Next Hour Price Rating",
|
||||||
|
# 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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -270,7 +272,7 @@ DAILY_LEVEL_SENSORS = (
|
||||||
key="yesterday_price_level",
|
key="yesterday_price_level",
|
||||||
translation_key="yesterday_price_level",
|
translation_key="yesterday_price_level",
|
||||||
name="Yesterday's Price Level",
|
name="Yesterday's Price Level",
|
||||||
icon="mdi:gauge",
|
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,
|
||||||
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,
|
||||||
|
|
@ -279,7 +281,7 @@ DAILY_LEVEL_SENSORS = (
|
||||||
key="today_price_level",
|
key="today_price_level",
|
||||||
translation_key="today_price_level",
|
translation_key="today_price_level",
|
||||||
name="Today's Price Level",
|
name="Today's Price Level",
|
||||||
icon="mdi:gauge",
|
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,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -287,7 +289,7 @@ DAILY_LEVEL_SENSORS = (
|
||||||
key="tomorrow_price_level",
|
key="tomorrow_price_level",
|
||||||
translation_key="tomorrow_price_level",
|
translation_key="tomorrow_price_level",
|
||||||
name="Tomorrow's Price Level",
|
name="Tomorrow's Price Level",
|
||||||
icon="mdi:gauge",
|
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,
|
||||||
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
options=["very_cheap", "cheap", "normal", "expensive", "very_expensive"],
|
||||||
),
|
),
|
||||||
|
|
@ -301,6 +303,7 @@ DAILY_RATING_SENSORS = (
|
||||||
key="yesterday_price_rating",
|
key="yesterday_price_rating",
|
||||||
translation_key="yesterday_price_rating",
|
translation_key="yesterday_price_rating",
|
||||||
name="Yesterday's Price Rating",
|
name="Yesterday's Price Rating",
|
||||||
|
# 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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -310,6 +313,7 @@ DAILY_RATING_SENSORS = (
|
||||||
key="today_price_rating",
|
key="today_price_rating",
|
||||||
translation_key="today_price_rating",
|
translation_key="today_price_rating",
|
||||||
name="Today's Price Rating",
|
name="Today's Price Rating",
|
||||||
|
# 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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -318,6 +322,7 @@ DAILY_RATING_SENSORS = (
|
||||||
key="tomorrow_price_rating",
|
key="tomorrow_price_rating",
|
||||||
translation_key="tomorrow_price_rating",
|
translation_key="tomorrow_price_rating",
|
||||||
name="Tomorrow's Price Rating",
|
name="Tomorrow's Price Rating",
|
||||||
|
# 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,
|
||||||
options=["low", "normal", "high"],
|
options=["low", "normal", "high"],
|
||||||
|
|
@ -471,7 +476,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_1h",
|
key="price_trend_1h",
|
||||||
translation_key="price_trend_1h",
|
translation_key="price_trend_1h",
|
||||||
name="Price Trend (1h)",
|
name="Price Trend (1h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
|
|
@ -480,7 +485,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_2h",
|
key="price_trend_2h",
|
||||||
translation_key="price_trend_2h",
|
translation_key="price_trend_2h",
|
||||||
name="Price Trend (2h)",
|
name="Price Trend (2h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
|
|
@ -489,7 +494,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_3h",
|
key="price_trend_3h",
|
||||||
translation_key="price_trend_3h",
|
translation_key="price_trend_3h",
|
||||||
name="Price Trend (3h)",
|
name="Price Trend (3h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
|
|
@ -498,7 +503,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_4h",
|
key="price_trend_4h",
|
||||||
translation_key="price_trend_4h",
|
translation_key="price_trend_4h",
|
||||||
name="Price Trend (4h)",
|
name="Price Trend (4h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
|
|
@ -507,7 +512,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_5h",
|
key="price_trend_5h",
|
||||||
translation_key="price_trend_5h",
|
translation_key="price_trend_5h",
|
||||||
name="Price Trend (5h)",
|
name="Price Trend (5h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
|
|
@ -517,7 +522,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_6h",
|
key="price_trend_6h",
|
||||||
translation_key="price_trend_6h",
|
translation_key="price_trend_6h",
|
||||||
name="Price Trend (6h)",
|
name="Price Trend (6h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
|
|
@ -526,7 +531,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_8h",
|
key="price_trend_8h",
|
||||||
translation_key="price_trend_8h",
|
translation_key="price_trend_8h",
|
||||||
name="Price Trend (8h)",
|
name="Price Trend (8h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
|
|
@ -535,7 +540,7 @@ FUTURE_TREND_SENSORS = (
|
||||||
key="price_trend_12h",
|
key="price_trend_12h",
|
||||||
translation_key="price_trend_12h",
|
translation_key="price_trend_12h",
|
||||||
name="Price Trend (12h)",
|
name="Price Trend (12h)",
|
||||||
icon="mdi:trending-up",
|
icon="mdi:trending-up", # Dynamic: shows trending-up/trending-down/trending-neutral based on trend value
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
options=["rising", "falling", "stable"],
|
options=["rising", "falling", "stable"],
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
|
|
@ -554,6 +559,7 @@ VOLATILITY_SENSORS = (
|
||||||
key="today_volatility",
|
key="today_volatility",
|
||||||
translation_key="today_volatility",
|
translation_key="today_volatility",
|
||||||
name="Today's Price Volatility",
|
name="Today's Price Volatility",
|
||||||
|
# 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,
|
||||||
options=["low", "moderate", "high", "very_high"],
|
options=["low", "moderate", "high", "very_high"],
|
||||||
|
|
@ -562,6 +568,7 @@ VOLATILITY_SENSORS = (
|
||||||
key="tomorrow_volatility",
|
key="tomorrow_volatility",
|
||||||
translation_key="tomorrow_volatility",
|
translation_key="tomorrow_volatility",
|
||||||
name="Tomorrow's Price Volatility",
|
name="Tomorrow's Price Volatility",
|
||||||
|
# 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,
|
||||||
options=["low", "moderate", "high", "very_high"],
|
options=["low", "moderate", "high", "very_high"],
|
||||||
|
|
@ -570,6 +577,7 @@ VOLATILITY_SENSORS = (
|
||||||
key="next_24h_volatility",
|
key="next_24h_volatility",
|
||||||
translation_key="next_24h_volatility",
|
translation_key="next_24h_volatility",
|
||||||
name="Next 24h Price Volatility",
|
name="Next 24h Price Volatility",
|
||||||
|
# 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,
|
||||||
options=["low", "moderate", "high", "very_high"],
|
options=["low", "moderate", "high", "very_high"],
|
||||||
|
|
@ -578,6 +586,7 @@ VOLATILITY_SENSORS = (
|
||||||
key="today_tomorrow_volatility",
|
key="today_tomorrow_volatility",
|
||||||
translation_key="today_tomorrow_volatility",
|
translation_key="today_tomorrow_volatility",
|
||||||
name="Today + Tomorrow Price Volatility",
|
name="Today + Tomorrow Price Volatility",
|
||||||
|
# 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,
|
||||||
options=["low", "moderate", "high", "very_high"],
|
options=["low", "moderate", "high", "very_high"],
|
||||||
|
|
|
||||||
|
|
@ -192,10 +192,10 @@
|
||||||
"previous_interval_price": {
|
"previous_interval_price": {
|
||||||
"name": "Vorheriger Preis"
|
"name": "Vorheriger Preis"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"name": "Aktueller Stunden-Durchschnittspreis"
|
"name": "Aktueller Stunden-Durchschnittspreis"
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"name": "Nächster Stunden-Durchschnittspreis"
|
"name": "Nächster Stunden-Durchschnittspreis"
|
||||||
},
|
},
|
||||||
"current_interval_price_level": {
|
"current_interval_price_level": {
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,10 @@
|
||||||
"previous_interval_price": {
|
"previous_interval_price": {
|
||||||
"name": "Previous Electricity Price"
|
"name": "Previous Electricity Price"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"name": "Current Hour Average Price"
|
"name": "Current Hour Average Price"
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"name": "Next Hour Average Price"
|
"name": "Next Hour Average Price"
|
||||||
},
|
},
|
||||||
"current_interval_price_level": {
|
"current_interval_price_level": {
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,10 @@
|
||||||
"previous_interval_price": {
|
"previous_interval_price": {
|
||||||
"name": "Forrige strømpris"
|
"name": "Forrige strømpris"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"name": "Nåværende timepris gjennomsnitt"
|
"name": "Nåværende timepris gjennomsnitt"
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"name": "Neste timepris gjennomsnitt"
|
"name": "Neste timepris gjennomsnitt"
|
||||||
},
|
},
|
||||||
"current_interval_price_level": {
|
"current_interval_price_level": {
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,10 @@
|
||||||
"previous_interval_price": {
|
"previous_interval_price": {
|
||||||
"name": "Vorige elektriciteitsprijs"
|
"name": "Vorige elektriciteitsprijs"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"name": "Huidig uurgemiddelde prijs"
|
"name": "Huidig uurgemiddelde prijs"
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"name": "Volgend uurgemiddelde prijs"
|
"name": "Volgend uurgemiddelde prijs"
|
||||||
},
|
},
|
||||||
"current_interval_price_level": {
|
"current_interval_price_level": {
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,10 @@
|
||||||
"previous_interval_price": {
|
"previous_interval_price": {
|
||||||
"name": "Föregående elpris"
|
"name": "Föregående elpris"
|
||||||
},
|
},
|
||||||
"current_hour_average": {
|
"current_hour_average_price": {
|
||||||
"name": "Nuvarande timgenomsnitt pris"
|
"name": "Nuvarande timgenomsnitt pris"
|
||||||
},
|
},
|
||||||
"next_hour_average": {
|
"next_hour_average_price": {
|
||||||
"name": "Nästa timgenomsnitt pris"
|
"name": "Nästa timgenomsnitt pris"
|
||||||
},
|
},
|
||||||
"current_interval_price_level": {
|
"current_interval_price_level": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue