From 4ba159d81595d04098f9829ec313c32b36a94b65 Mon Sep 17 00:00:00 2001 From: Julian Pawlowski Date: Sun, 12 Apr 2026 19:55:57 +0000 Subject: [PATCH] feat(translations): enhance price trend change descriptions and usage tips Updated the long descriptions and usage tips for the price trend change sensors in multiple languages (de, en, nb, nl, sv) to provide clearer guidance on detection mechanics and expected behavior during V-shaped price days. Impact: Users will have a better understanding of how the sensors operate and can make more informed decisions regarding automation based on price trends. --- .../tibber_prices/custom_translations/de.json | 6 +- .../tibber_prices/custom_translations/en.json | 6 +- .../tibber_prices/custom_translations/nb.json | 6 +- .../tibber_prices/custom_translations/nl.json | 6 +- .../tibber_prices/custom_translations/sv.json | 6 +- .../tibber_prices/sensor/calculators/trend.py | 16 +++ custom_components/tibber_prices/services.yaml | 104 ------------------ .../tibber_prices/translations/de.json | 7 +- .../tibber_prices/translations/en.json | 7 +- .../tibber_prices/translations/nb.json | 7 +- .../tibber_prices/translations/nl.json | 7 +- .../tibber_prices/translations/sv.json | 7 +- docs/user/docs/sensors-trends.md | 38 +++++++ 13 files changed, 84 insertions(+), 139 deletions(-) diff --git a/custom_components/tibber_prices/custom_translations/de.json b/custom_components/tibber_prices/custom_translations/de.json index 6c36b9f..9f5353c 100644 --- a/custom_components/tibber_prices/custom_translations/de.json +++ b/custom_components/tibber_prices/custom_translations/de.json @@ -309,12 +309,12 @@ }, "next_price_trend_change": { "description": "Wann die nächste bedeutende Preistrend-Änderung eintreten wird", - "long_description": "Scannt die nächsten 24 Stunden (96 Intervalle), um zu finden, wann sich die Preistrend-Richtung ändern wird. Nur Richtungswechsel zählen: steigend/stark steigend bilden eine Gruppe, fallend/stark fallend eine andere, stabil ist eigenständig. Ein Wechsel von steigend zu stark steigend ist KEIN Trendwechsel. Verwendet volatilitätsadaptive Schwellwerte (Standard: ±3%/±9%) mit Hysterese (Standard: 3 aufeinanderfolgende Intervalle). Gibt den Zeitstempel zurück, wann die Änderung erwartet wird.", - "usage_tips": "Ereignisbasierte Automation: Aktionen WENN Trend wechselt auslösen, nicht IN X Stunden. Beispiel: 'E-Auto laden wenn nächste Trendänderung fallende Preise zeigt' oder 'Spülmaschine vor Preisanstieg starten'. Ergänzt Zeitfenster-Sensoren (price_trend_Xh), die beantworten 'WERDEN Preise in X Stunden höher sein?'" + "long_description": "Scannt die nächsten 24 Stunden (96 Intervalle), um zu finden, wann sich die Preistrend-Richtung ändern wird. Nur Richtungswechsel zählen: steigend/stark steigend bilden eine Gruppe, fallend/stark fallend eine andere, stabil ist eigenständig. Ein Wechsel von steigend zu stark steigend ist KEIN Trendwechsel. Verwendet volatilitätsadaptive Schwellwerte (Standard: ±3%/±9%) mit Hysterese (Standard: 3 aufeinanderfolgende Intervalle). Gibt den Zeitstempel zurück, wann die Änderung erwartet wird.\n\nWICHTIG — Wie die Erkennung funktioniert: Bei jedem zukünftigen Intervall vergleicht der Sensor den Preis dieses Intervalls mit dem DURCHSCHNITT der folgenden 3 Stunden (dem 3h-Vorschau-Mittelwert). Das bedeutet: Der Sensor erkennt, wann die durchschnittlichen Kosten der nächsten 3 Stunden die Richtung gewechselt haben — nicht wann das exakte Preisminimum oder -maximum erreicht ist.\n\nAn V-förmigen Preistagen: Beim Preisrückgang in Richtung eines Minimums beginnt das 3h-Vorschaufenster bereits Preise der steigenden Flanke einzubeziehen, bevor das eigentliche Minimum erreicht ist. Sobald diese steigenden Preise den 3h-Mittelwert über den aktuellen Preis treiben, meldet der Sensor 'Trend ändert sich jetzt'. Das passiert typischerweise 30–60 Minuten vor dem exakten Preisminimum. Dies ist beabsichtigt — der Sensor beantwortet 'wann ändert sich die grundlegende RICHTUNG?' und nicht 'wann ist der exakte Wendepunkt?'.", + "usage_tips": "Ereignisbasierte Automation: Aktionen WENN Trend wechselt auslösen, nicht IN X Stunden. Beispiel: 'E-Auto laden wenn nächste Trendänderung fallende Preise zeigt' oder 'Spülmaschine vor Preisanstieg starten'. Ergänzt Zeitfenster-Sensoren (price_trend_Xh), die beantworten 'WERDEN Preise in X Stunden höher sein?'\n\nHinweis: An stark V-förmigen Preistagen kann dieser Sensor 30–60 Minuten vor dem exakten Preisminimum auslösen. Wenn du einen präzisen Wendepunkt benötigst, vergleiche ihn mit dem Start der Günstigsten-Preis-Periode — diese startet beim eigentlichen günstigsten Fenster. Dieser Sensor eignet sich besser für Automations-Trigger nach dem Motto 'auf eine Änderung vorbereiten', wo eine kurze Frühwarnung akzeptabel ist." }, "next_price_trend_change_in": { "description": "Zeit bis zur nächsten Preistrend-Änderung", - "long_description": "Zeigt an, wie lange es bis zur nächsten bedeutenden Preistrend-Änderung dauert. Der Wert wird in Stunden angezeigt (z.B. 2,25 h) für Dashboards. Teilt die gleiche Analyse wie der Zeitstempel-Sensor 'Nächste Trendänderung', stellt sie aber als Countdown-Dauer dar. Aktualisiert sich jede Minute für präzise Countdowns. Zeigt 'Unbekannt' wenn keine Trendänderung in den nächsten 24 Stunden erwartet wird.", + "long_description": "Zeigt an, wie lange es bis zur nächsten bedeutenden Preistrend-Änderung dauert. Der Wert wird in Stunden angezeigt (z.B. 2,25 h) für Dashboards. Teilt die gleiche Analyse wie der Zeitstempel-Sensor 'Nächste Trendänderung', stellt sie aber als Countdown-Dauer dar. Aktualisiert sich jede Minute für präzise Countdowns. Zeigt 'Unbekannt' wenn keine Trendänderung in den nächsten 24 Stunden erwartet wird. Siehe 'Nächste Preistrend-Änderung' für eine Erklärung des 3h-Vorschau-Erkennungsmechanismus und seinem Verhalten an V-förmigen Preistagen.", "usage_tips": "Dashboard-Countdown: Zeige 'Trendänderung in 1,5 h' als Live-Countdown. Für Automationen: 'Wenn next_price_trend_change_in < 0,25 (15 Min), auf Preisrichtungswechsel vorbereiten'. Ergänzt 'Nächste Trendänderung' (Zeitstempel) — verwende den Zeitstempel für 'WANN' und diesen Sensor für 'WIE LANGE'." }, "daily_rating": { diff --git a/custom_components/tibber_prices/custom_translations/en.json b/custom_components/tibber_prices/custom_translations/en.json index 9e6c602..d6d50a3 100644 --- a/custom_components/tibber_prices/custom_translations/en.json +++ b/custom_components/tibber_prices/custom_translations/en.json @@ -309,12 +309,12 @@ }, "next_price_trend_change": { "description": "When the next significant price trend change will occur", - "long_description": "Scans the next 24 hours (96 intervals) to find when the price trend direction will change. Only direction changes count: rising/strongly_rising are one group, falling/strongly_falling another, stable is its own. A change from rising to strongly_rising is NOT a trend change. Uses volatility-adaptive thresholds (default: ±3%/±9%) with hysteresis (default: 3 consecutive intervals). Returns the timestamp when the change is expected.", - "usage_tips": "Event-based automation: Trigger actions WHEN trend changes, not IN X hours. Example: 'Charge EV when next trend change shows falling prices' or 'Run dishwasher before prices start rising'. More accurate than simple future comparison because it knows if you're already in a trend. Complements time-window sensors (price_trend_Xh) which answer 'WILL prices be higher in X hours?'" + "long_description": "Scans the next 24 hours (96 intervals) to find when the price trend direction will change. Only direction changes count: rising/strongly_rising are one group, falling/strongly_falling another, stable is its own. A change from rising to strongly_rising is NOT a trend change. Uses volatility-adaptive thresholds (default: ±3%/±9%) with hysteresis (default: 3 consecutive intervals). Returns the timestamp when the change is expected.\n\nIMPORTANT — How the detection works: At each future interval, the sensor compares that interval's price to the AVERAGE of the following 3 hours (the 3h lookahead mean). This means the sensor detects when the average cost of the next 3 hours has already flipped direction — not when the exact price minimum or maximum is reached.\n\nOn V-shaped price days: During a price drop toward a minimum, the 3h lookahead window starts including prices on the rising flank before the actual minimum is reached. Once those rising prices push the 3h average above the current price, the sensor reports 'trend is now changing'. This typically fires 30–60 minutes before the exact price minimum. This is intentional — the sensor answers 'when will the broad DIRECTION change?' rather than 'when is the exact turning point?'.", + "usage_tips": "Event-based automation: Trigger actions WHEN trend changes, not IN X hours. Example: 'Charge EV when next trend change shows falling prices' or 'Run dishwasher before prices start rising'. More accurate than simple future comparison because it knows if you're already in a trend. Complements time-window sensors (price_trend_Xh) which answer 'WILL prices be higher in X hours?'\n\nNote: On sharp V-shape days, this sensor may fire 30–60 minutes before the exact price minimum. If you need a precise turning point, compare it to the Best Price period start — the period starts at the actual cheapest window. This sensor is better suited to 'prepare for a change' automation triggers where a brief early warning is acceptable." }, "next_price_trend_change_in": { "description": "Time until the next price trend change", - "long_description": "Shows how long until the next significant price trend change occurs. The state displays in hours (e.g., 2.25 h) for dashboards. Shares the same analysis as the Next Price Trend Change timestamp sensor but presents it as a countdown duration. Updates every minute for accurate countdowns. Returns unknown when no trend change is expected in the next 24 hours.", + "long_description": "Shows how long until the next significant price trend change occurs. The state displays in hours (e.g., 2.25 h) for dashboards. Shares the same analysis as the Next Price Trend Change timestamp sensor but presents it as a countdown duration. Updates every minute for accurate countdowns. Returns unknown when no trend change is expected in the next 24 hours.\n\nSee 'Next Price Trend Change' for an explanation of the 3h-lookahead detection mechanism and its behaviour on V-shaped price days.", "usage_tips": "Dashboard countdown: Show 'Trend changes in 1.5 h' as a live countdown. For automations: 'If next_price_trend_change_in state < 0.25 (15 min), prepare for price direction change'. Pairs with Next Price Trend Change (timestamp) — use the timestamp for 'WHEN' and this sensor for 'HOW LONG'." }, "daily_rating": { diff --git a/custom_components/tibber_prices/custom_translations/nb.json b/custom_components/tibber_prices/custom_translations/nb.json index 3e1b726..2557a56 100644 --- a/custom_components/tibber_prices/custom_translations/nb.json +++ b/custom_components/tibber_prices/custom_translations/nb.json @@ -309,12 +309,12 @@ }, "next_price_trend_change": { "description": "Når neste betydelige pristrendendring vil skje", - "long_description": "Skanner de neste 24 timene (96 intervaller) for å finne når pristrend-retningen vil endre seg. Kun retningsendringer teller: stigende/sterkt stigende er én gruppe, fallende/sterkt fallende en annen, stabil er egen. En endring fra stigende til sterkt stigende er IKKE en trendendring. Bruker volatilitetstilpassede terskelverdier (standard: ±3%/±9%) med hysterese (standard: 3 påfølgende intervaller). Returnerer tidsstempelet når endringen forventes.", - "usage_tips": "Hendelsesbasert automatisering: Utløs handlinger NÅR trenden endres, ikke OM X timer. Eksempel: 'Lad EV når neste trendendring viser synkende priser' eller 'Start oppvaskmaskin før prisene stiger'. Kompletterer tidsvindu-sensorer (price_trend_Xh) som svarer på 'VIL prisene være høyere om X timer?'" + "long_description": "Skanner de neste 24 timene (96 intervaller) for å finne når pristrend-retningen vil endre seg. Kun retningsendringer teller: stigende/sterkt stigende er én gruppe, fallende/sterkt fallende en annen, stabil er egen. En endring fra stigende til sterkt stigende er IKKE en trendendring. Bruker volatilitetstilpassede terskelverdier (standard: ±3%/±9%) med hysterese (standard: 3 påfølgende intervaller). Returnerer tidsstempelet når endringen forventes.\n\nVIKTIG — Hvordan deteksjonen fungerer: For hvert fremtidig intervall sammenligner sensoren prisen for det intervallet med GJENNOMSNITTET av de følgende 3 timene (3h forhåndsvisnings-gjennomsnittet). Dette betyr at sensoren oppdager når de gjennomsnittlige kostnadene for de neste 3 timene allerede har skiftet retning — ikke når det nøyaktige prisminimum eller -maksimum er nådd.\n\nPå V-formede prisdager: Under et prisfall mot et minimum begynner 3h-forhåndsvinduet å inkludere priser på den stigende flanken før det faktiske minimumet er nådd. Når disse stigende prisene dytter 3h-gjennomsnittet over den nåværende prisen, rapporterer sensoren 'trenden endrer seg nå'. Dette skjer typisk 30–60 minutter før det eksakte prisminimum. Dette er tilsiktet — sensoren besvarer 'når vil den generelle RETNINGEN endre seg?' snarere enn 'når er det eksakte vendepunktet?'.", + "usage_tips": "Hendelsesbasert automatisering: Utløs handlinger NÅR trenden endres, ikke OM X timer. Eksempel: 'Lad EV når neste trendendring viser synkende priser' eller 'Start oppvaskmaskin før prisene stiger'. Kompletterer tidsvindu-sensorer (price_trend_Xh) som svarer på 'VIL prisene være høyere om X timer?'\n\nMerk: På skarpe V-formede prisdager kan denne sensoren utløse 30–60 minutter før det eksakte prisminimum. Hvis du trenger et presist vendepunkt, sammenlign det med starten av Beste Pris-perioden — perioden starter ved det faktisk billigste vinduet. Denne sensoren egner seg bedre for 'forbered deg på en endring'-automatiseringsutløsere der en kort forhåndsvarsel er akseptabelt." }, "next_price_trend_change_in": { "description": "Tid til neste pristrendendring", - "long_description": "Viser hvor lenge det er til neste betydelige pristrendendring inntreffer. Verdien vises i timer (f.eks. 2,25 t) for dashboards. Deler samme analyse som tidsstempel-sensoren 'Neste trendendring', men presenterer den som en nedtellingsvarighet. Oppdateres hvert minutt for nøyaktige nedtellinger. Viser 'Ukjent' når ingen trendendring forventes i løpet av de neste 24 timene.", + "long_description": "Viser hvor lenge det er til neste betydelige pristrendendring inntreffer. Verdien vises i timer (f.eks. 2,25 t) for dashboards. Deler samme analyse som tidsstempel-sensoren 'Neste trendendring', men presenterer den som en nedtellingsvarighet. Oppdateres hvert minutt for nøyaktige nedtellinger. Viser 'Ukjent' når ingen trendendring forventes i løpet av de neste 24 timene. Se 'Neste trendendring' for en forklaring av 3h-forhånds-deteksjonsmekanismen og dens oppførsel på V-formede prisdager.", "usage_tips": "Dashboard-nedtelling: Vis 'Trendendring om 1,5 t' som live nedtelling. For automatiseringer: 'Hvis next_price_trend_change_in < 0,25 (15 min), forbered på prisretningsendring'. Kompletterer 'Neste trendendring' (tidsstempel) — bruk tidsstempelet for 'NÅR' og denne sensoren for 'HVOR LENGE'." }, "daily_rating": { diff --git a/custom_components/tibber_prices/custom_translations/nl.json b/custom_components/tibber_prices/custom_translations/nl.json index 3c9a562..25fcf39 100644 --- a/custom_components/tibber_prices/custom_translations/nl.json +++ b/custom_components/tibber_prices/custom_translations/nl.json @@ -309,12 +309,12 @@ }, "next_price_trend_change": { "description": "Wanneer de volgende significante prijstrendwijziging zal plaatsvinden", - "long_description": "Scant de komende 24 uur (96 intervallen) om te vinden wanneer de prijstrend-richting zal veranderen. Alleen richtingswijzigingen tellen: stijgend/sterk stijgend vormen één groep, dalend/sterk dalend een andere, stabiel is apart. Een verandering van stijgend naar sterk stijgend is GEEN trendwijziging. Gebruikt volatiliteit-adaptieve drempelwaarden (standaard: ±3%/±9%) met hysterese (standaard: 3 opeenvolgende intervallen). Retourneert het tijdstempel wanneer de wijziging wordt verwacht.", - "usage_tips": "Gebeurtenisgestuurde automatisering: Trigger acties WANNEER trend wijzigt, niet OVER X uur. Voorbeeld: 'Laad EV wanneer volgende trendwijziging dalende prijzen toont' of 'Start vaatwasser voordat prijzen stijgen'. Vult tijdvenster-sensors aan (price_outlook_Xh) die beantwoorden 'ZULLEN prijzen over X uur hoger zijn?'" + "long_description": "Scant de komende 24 uur (96 intervallen) om te vinden wanneer de prijstrend-richting zal veranderen. Alleen richtingswijzigingen tellen: stijgend/sterk stijgend vormen één groep, dalend/sterk dalend een andere, stabiel is apart. Een verandering van stijgend naar sterk stijgend is GEEN trendwijziging. Gebruikt volatiliteit-adaptieve drempelwaarden (standaard: ±3%/±9%) met hysterese (standaard: 3 opeenvolgende intervallen). Retourneert het tijdstempel wanneer de wijziging wordt verwacht.\n\nBELANGRIJK — Hoe de detectie werkt: Bij elk toekomstig interval vergelijkt de sensor de prijs van dat interval met het GEMIDDELDE van de volgende 3 uur (het 3u vooruitkijkgemiddelde). Dit betekent dat de sensor detecteert wanneer de gemiddelde kosten van de komende 3 uur al van richting zijn veranderd — niet wanneer het exacte prijsminimum of -maximum is bereikt.\n\nOp V-vormige prisdagen: Tijdens een prijsdaling naar een minimum begint het 3u vooruitkijkvenster al prijzen van de stijgende flank te bevatten voordat het eigenlijke minimum is bereikt. Zodra die stijgende prijzen het 3u-gemiddelde boven de huidige prijs duwen, rapporteert de sensor 'trend verandert nu'. Dit treedt typisch 30–60 minuten voor het exacte prijsminimum op. Dit is opzettelijk — de sensor beantwoordt 'wanneer verandert de algemene RICHTING?' in plaats van 'wanneer is het exacte keerpunt?'.", + "usage_tips": "Gebeurtenisgestuurde automatisering: Trigger acties WANNEER trend wijzigt, niet OVER X uur. Voorbeeld: 'Laad EV wanneer volgende trendwijziging dalende prijzen toont' of 'Start vaatwasser voordat prijzen stijgen'. Vult tijdvenster-sensors aan (price_outlook_Xh) die beantwoorden 'ZULLEN prijzen over X uur hoger zijn?'\n\nOpmerking: Op scherpe V-vormige prisdagen kan deze sensor 30–60 minuten voor het exacte prijsminimum afgaan. Als je een precies keerpunt nodig hebt, vergelijk het met de start van de Beste Prijs-periode — de periode start bij het eigenlijke goedkoopste venster. Deze sensor is beter geschikt voor 'bereid je voor op een verandering' automatiserings-triggers waarbij een korte vroege waarschuwing acceptabel is." }, "next_price_trend_change_in": { "description": "Tijd tot de volgende prijstrendwijziging", - "long_description": "Toont hoe lang het duurt tot de volgende significante prijstrendwijziging plaatsvindt. De waarde wordt weergegeven in uren (bijv. 2,25 u) voor dashboards. Deelt dezelfde analyse als de tijdstempel-sensor 'Volgende Prijstrend Wijziging', maar presenteert het als een aftelduur. Wordt elke minuut bijgewerkt voor nauwkeurige aftellingen. Toont 'Onbekend' wanneer geen trendwijziging wordt verwacht in de komende 24 uur.", + "long_description": "Toont hoe lang het duurt tot de volgende significante prijstrendwijziging plaatsvindt. De waarde wordt weergegeven in uren (bijv. 2,25 u) voor dashboards. Deelt dezelfde analyse als de tijdstempel-sensor 'Volgende Prijstrend Wijziging', maar presenteert het als een aftelduur. Wordt elke minuut bijgewerkt voor nauwkeurige aftellingen. Toont 'Onbekend' wanneer geen trendwijziging wordt verwacht in de komende 24 uur. Zie 'Volgende Prijstrend Wijziging' voor een uitleg van het 3u-vooruitkijkdetectiemechanisme en het gedrag op V-vormige prisdagen.", "usage_tips": "Dashboard-aftelling: Toon 'Trendwijziging over 1,5 u' als live aftelling. Voor automatiseringen: 'Als next_price_trend_change_in < 0,25 (15 min), bereid je voor op prijsrichtingswijziging'. Vult 'Volgende Prijstrend Wijziging' (tijdstempel) aan — gebruik het tijdstempel voor 'WANNEER' en deze sensor voor 'HOE LANG'." }, "daily_rating": { diff --git a/custom_components/tibber_prices/custom_translations/sv.json b/custom_components/tibber_prices/custom_translations/sv.json index 323fc67..9631134 100644 --- a/custom_components/tibber_prices/custom_translations/sv.json +++ b/custom_components/tibber_prices/custom_translations/sv.json @@ -309,12 +309,12 @@ }, "next_price_trend_change": { "description": "När nästa betydande pristrendändring kommer att inträffa", - "long_description": "Skannar de nästa 24 timmarna (96 intervaller) för att hitta när pristrend-riktningen kommer att ändras. Bara riktningsändringar räknas: stigande/kraftigt stigande är en grupp, fallande/kraftigt fallande en annan, stabil är egen. En ändring från stigande till kraftigt stigande är INTE en trendändring. Använder volatilitetsadaptiva tröskelvärden (standard: ±3%/±9%) med hysteres (standard: 3 på varandra följande intervaller). Returnerar tidstämpeln när ändringen förväntas.", - "usage_tips": "Händelsestyrd automatisering: Utlös åtgärder NÄR trenden ändras, inte OM X timmar. Exempel: 'Ladda EV när nästa trendändring visar fallande priser' eller 'Starta diskmaskin innan priserna stiger'. Kompletterar tidsfönster-sensorer (price_outlook_Xh) som svarar på 'KOMMER priserna att vara högre om X timmar?'" + "long_description": "Skannar de nästa 24 timmarna (96 intervaller) för att hitta när pristrend-riktningen kommer att ändras. Bara riktningsändringar räknas: stigande/kraftigt stigande är en grupp, fallande/kraftigt fallande en annan, stabil är egen. En ändring från stigande till kraftigt stigande är INTE en trendändring. Använder volatilitetsadaptiva tröskelvärden (standard: ±3%/±9%) med hysteres (standard: 3 på varandra följande intervaller). Returnerar tidstämpeln när ändringen förväntas.\n\nVIKTIGT — Hur detektionen fungerar: Vid varje framtida intervall jämför sensorn priset för det intervallet med MEDELVÄRDET av de följande 3 timmarna (3h framåtblickande medelvärde). Det innebär att sensorn upptäcker när de genomsnittliga kostnaderna för de nästa 3 timmarna redan har bytt riktning — inte när det exakta prisminimumet eller -maximumet nås.\n\nPå V-formade prisdagar: Under ett prisfall mot ett minimum börjar 3h-framåtfönstret inkludera priser på den stigande flanken innan det faktiska minimumet nås. När dessa stigande priser drar upp 3h-medelvärdet över det aktuella priset rapporterar sensorn 'trenden ändras nu'. Detta inträffar typiskt 30–60 minuter före det exakta prisminimumet. Det är avsiktligt — sensorn svarar på 'när kommer den övergripande RIKTNINGEN att ändras?' snarare än 'när är den exakta vändpunkten?'.", + "usage_tips": "Händelsestyrd automatisering: Utlös åtgärder NÄR trenden ändras, inte OM X timmar. Exempel: 'Ladda EV när nästa trendändring visar fallande priser' eller 'Starta diskmaskin innan priserna stiger'. Kompletterar tidsfönster-sensorer (price_outlook_Xh) som svarar på 'KOMMER priserna att vara högre om X timmar?'\n\nObservera: På skarpa V-formade prisdagar kan den här sensorn aktiveras 30–60 minuter före det exakta prisminimumet. Om du behöver en exakt vändpunkt, jämför den med starten av Bästa Pris-perioden — perioden startar vid det faktiskt billigaste fönstret. Den här sensorn lämpar sig bättre för automatiseringsutlösare av typen 'förbered för en förändring' där en kort tidig varning är acceptabel." }, "next_price_trend_change_in": { "description": "Tid till nästa pristrendändring", - "long_description": "Visar hur lång tid det är kvar till nästa betydande pristrendändring inträffar. Värdet visas i timmar (t.ex. 2,25 h) för dashboards. Delar samma analys som tidstämpel-sensorn 'Nästa pristrendändring' men presenterar det som en nedtellningsvaraktighet. Uppdateras varje minut för noggranna nedtellningar. Visar 'Okänd' när ingen trendändring förväntas inom de närmaste 24 timmarna.", + "long_description": "Visar hur lång tid det är kvar till nästa betydande pristrendändring inträffar. Värdet visas i timmar (t.ex. 2,25 h) för dashboards. Delar samma analys som tidstämpel-sensorn 'Nästa pristrendändring' men presenterar det som en nedtellningsvaraktighet. Uppdateras varje minut för noggranna nedtellningar. Visar 'Okänd' när ingen trendändring förväntas inom de närmaste 24 timmarna. Se 'Nästa pristrendändring' för en förklaring av 3h-framåtblickande detektionsmekanismen och dess beteende på V-formade prisdagar.", "usage_tips": "Dashboard-nedtellning: Visa 'Trendändring om 1,5 h' som live nedtellning. För automatiseringar: 'Om next_price_trend_change_in < 0,25 (15 min), förbered för prisriktningsändring'. Kompletterar 'Nästa pristrendändring' (tidstämpel) — använd tidstämpeln för 'NÄR' och denna sensor för 'HUR LÄNGE'." }, "daily_rating": { diff --git a/custom_components/tibber_prices/sensor/calculators/trend.py b/custom_components/tibber_prices/sensor/calculators/trend.py index 22807a5..a21609c 100644 --- a/custom_components/tibber_prices/sensor/calculators/trend.py +++ b/custom_components/tibber_prices/sensor/calculators/trend.py @@ -797,10 +797,26 @@ class TibberPricesTrendCalculator(TibberPricesBaseCalculator): """ Scan future intervals for trend change with hysteresis. + Detection mechanic: For each future interval i, the sensor compares the price + of interval i to the AVERAGE price of the following 3 hours (intervals i+1..i+12). + A trend change is signalled when that 3h-ahead mean has already moved in the + opposite direction from the current trend. + Requires N consecutive intervals (configurable, default 3) showing a different trend before confirming a change. This prevents false positives from short-lived price spikes. + Behaviour on V-shaped price days: + On a sharp price drop toward a minimum, the 3h lookahead window begins + including rising-flank prices before the actual minimum is reached. Once + those rising prices push the 3h average above the current price, the scan + reports a trend change. This typically fires 30-60 minutes before the exact + price minimum - intentional, because the sensor answers "when will the + broad direction change?" rather than "when is the exact turning point?". + Users who need the precise minimum should compare with the Best Price + period start (``best_price_next_start_time``), which uses the actual + cheapest window. + Args: all_intervals: List of all price intervals scan_params: Dict with current_index, current_trend_state, current_interval, now diff --git a/custom_components/tibber_prices/services.yaml b/custom_components/tibber_prices/services.yaml index 75b45ba..3e8863e 100644 --- a/custom_components/tibber_prices/services.yaml +++ b/custom_components/tibber_prices/services.yaml @@ -941,110 +941,6 @@ find_cheapest_schedule: selector: boolean: - - search_start: - required: false - example: "2026-04-11T06:00:00+02:00" - selector: - datetime: - search_end: - required: false - example: "2026-04-12T00:00:00+02:00" - selector: - datetime: - search_start_time: - required: false - example: "06:00:00" - selector: - time: - search_start_day_offset: - required: false - default: 0 - selector: - number: - min: -7 - max: 2 - mode: box - search_end_time: - required: false - example: "23:00:00" - selector: - time: - search_end_day_offset: - required: false - default: 0 - selector: - number: - min: -7 - max: 2 - mode: box - search_start_offset_minutes: - required: false - example: 60 - selector: - number: - min: -10080 - max: 10080 - unit_of_measurement: min - mode: box - search_end_offset_minutes: - required: false - example: 480 - selector: - number: - min: -10080 - max: 10080 - unit_of_measurement: min - mode: box - search_scope: - required: false - selector: - select: - options: - - today - - tomorrow - - remaining_today - - next_24h - - next_48h - max_price_level: - required: false - selector: - select: - options: - - very_cheap - - cheap - - normal - - expensive - - very_expensive - min_price_level: - required: false - selector: - select: - options: - - very_cheap - - cheap - - normal - - expensive - - very_expensive - include_comparison_details: - required: false - default: false - selector: - boolean: - power_profile: - required: false - selector: - object: - include_current_interval: - required: false - default: true - selector: - boolean: - use_base_unit: - required: false - default: false - selector: - boolean: debug_clear_tomorrow: fields: entry_id: diff --git a/custom_components/tibber_prices/translations/de.json b/custom_components/tibber_prices/translations/de.json index 2bcd40c..de2a6ac 100644 --- a/custom_components/tibber_prices/translations/de.json +++ b/custom_components/tibber_prices/translations/de.json @@ -1190,7 +1190,7 @@ "message": "{offset_param} erfordert, dass {time_param} gesetzt ist. Der Tagesoffset ändert nur das Datum eines expliziten Zeitparameters." }, "min_level_exceeds_max": { - "message": "min_price_level '{min_level}' ist höher als max_price_level '{max_level}'. Das Mindestlevel muss gleich oder niedriger als das Maximallevel sein." + "message": "min_price_level {min_level} ist höher als max_price_level {max_level}. Das Mindestlevel muss gleich oder niedriger als das Maximallevel sein." }, "power_profile_length_mismatch": { "message": "power_profile hat {profile_length} Einträge, aber die Dauer erfordert {interval_count} Intervalle ({duration_minutes} Minuten). Das power_profile muss genau einen Eintrag pro 15-Minuten-Intervall haben." @@ -1199,7 +1199,7 @@ "message": "level_filter und rating_level_filter können nicht gleichzeitig verwendet werden. Verwende nur einen Filtertyp pro Anfrage." }, "insert_nulls_requires_filter": { - "message": "insert_nulls-Modus '{mode}' erfordert einen level_filter oder rating_level_filter zur Segmentdefinition. Ohne Filter verwende insert_nulls: none." + "message": "insert_nulls-Modus {mode} erfordert einen level_filter oder rating_level_filter zur Segmentdefinition. Ohne Filter verwende insert_nulls: none." }, "connect_segments_requires_segments_mode": { "message": "connect_segments erfordert, dass insert_nulls auf 'segments' gesetzt ist. Setze insert_nulls: segments, um Segmentverbindung zu nutzen." @@ -1999,6 +1999,5 @@ "next_48h": "Naechste 48 Stunden" } } - }, - "title": "Tibber Preisinformationen & Bewertungen" + } } diff --git a/custom_components/tibber_prices/translations/en.json b/custom_components/tibber_prices/translations/en.json index 4aba4b1..0001f59 100644 --- a/custom_components/tibber_prices/translations/en.json +++ b/custom_components/tibber_prices/translations/en.json @@ -1190,7 +1190,7 @@ "message": "{offset_param} requires {time_param} to be set. Day offset only modifies the date of an explicit time parameter." }, "min_level_exceeds_max": { - "message": "min_price_level '{min_level}' is higher than max_price_level '{max_level}'. The minimum level must be equal to or lower than the maximum level." + "message": "min_price_level {min_level} is higher than max_price_level {max_level}. The minimum level must be equal to or lower than the maximum level." }, "power_profile_length_mismatch": { "message": "power_profile has {profile_length} entries but the duration requires {interval_count} intervals ({duration_minutes} minutes). The power_profile must have exactly one entry per 15-minute interval." @@ -1199,7 +1199,7 @@ "message": "level_filter and rating_level_filter cannot be used together. Use only one filter type per request." }, "insert_nulls_requires_filter": { - "message": "insert_nulls mode '{mode}' requires a level_filter or rating_level_filter to define segments. Without a filter, use insert_nulls: none." + "message": "insert_nulls mode {mode} requires a level_filter or rating_level_filter to define segments. Without a filter, use insert_nulls: none." }, "connect_segments_requires_segments_mode": { "message": "connect_segments requires insert_nulls to be set to 'segments'. Set insert_nulls: segments to use segment connection." @@ -2009,6 +2009,5 @@ "next_48h": "Next 48 Hours" } } - }, - "title": "Tibber Price Information & Ratings" + } } diff --git a/custom_components/tibber_prices/translations/nb.json b/custom_components/tibber_prices/translations/nb.json index aa843a8..a719840 100644 --- a/custom_components/tibber_prices/translations/nb.json +++ b/custom_components/tibber_prices/translations/nb.json @@ -1190,7 +1190,7 @@ "message": "{offset_param} krever at {time_param} er satt. Dagsforskyvning endrer kun datoen til en eksplisitt tidsparameter." }, "min_level_exceeds_max": { - "message": "min_price_level '{min_level}' er høyere enn max_price_level '{max_level}'. Minimumsnivået må være lik eller lavere enn maksimumsnivået." + "message": "min_price_level {min_level} er høyere enn max_price_level {max_level}. Minimumsnivået må være lik eller lavere enn maksimumsnivået." }, "power_profile_length_mismatch": { "message": "power_profile har {profile_length} oppføringer, men varigheten krever {interval_count} intervaller ({duration_minutes} minutter). power_profile må ha nøyaktig én oppføring per 15-minutters intervall." @@ -1199,7 +1199,7 @@ "message": "level_filter og rating_level_filter kan ikke brukes sammen. Bruk kun én filtertype per forespørsel." }, "insert_nulls_requires_filter": { - "message": "insert_nulls-modus '{mode}' krever en level_filter eller rating_level_filter for å definere segmenter. Uten filter, bruk insert_nulls: none." + "message": "insert_nulls-modus {mode} krever en level_filter eller rating_level_filter for å definere segmenter. Uten filter, bruk insert_nulls: none." }, "connect_segments_requires_segments_mode": { "message": "connect_segments krever at insert_nulls er satt til 'segments'. Sett insert_nulls: segments for å bruke segmentforbindelse." @@ -1999,6 +1999,5 @@ "next_48h": "Neste 48 timer" } } - }, - "title": "Tibber Prisinformasjon & Vurderinger" + } } diff --git a/custom_components/tibber_prices/translations/nl.json b/custom_components/tibber_prices/translations/nl.json index af754b6..2db0e9b 100644 --- a/custom_components/tibber_prices/translations/nl.json +++ b/custom_components/tibber_prices/translations/nl.json @@ -1190,7 +1190,7 @@ "message": "{offset_param} vereist dat {time_param} ingesteld is. Dagoffset wijzigt alleen de datum van een expliciete tijdparameter." }, "min_level_exceeds_max": { - "message": "min_price_level '{min_level}' is hoger dan max_price_level '{max_level}'. Het minimumniveau moet gelijk aan of lager zijn dan het maximumniveau." + "message": "min_price_level {min_level} is hoger dan max_price_level {max_level}. Het minimumniveau moet gelijk aan of lager zijn dan het maximumniveau." }, "power_profile_length_mismatch": { "message": "power_profile heeft {profile_length} items maar de duur vereist {interval_count} intervallen ({duration_minutes} minuten). Het power_profile moet precies één item per 15-minuten-interval hebben." @@ -1199,7 +1199,7 @@ "message": "level_filter en rating_level_filter kunnen niet samen gebruikt worden. Gebruik slechts één filtertype per verzoek." }, "insert_nulls_requires_filter": { - "message": "insert_nulls-modus '{mode}' vereist een level_filter of rating_level_filter om segmenten te definiëren. Zonder filter, gebruik insert_nulls: none." + "message": "insert_nulls-modus {mode} vereist een level_filter of rating_level_filter om segmenten te definiëren. Zonder filter, gebruik insert_nulls: none." }, "connect_segments_requires_segments_mode": { "message": "connect_segments vereist dat insert_nulls op 'segments' staat. Stel insert_nulls: segments in om segmentverbinding te gebruiken." @@ -1999,6 +1999,5 @@ "next_48h": "Komende 48 uur" } } - }, - "title": "Tibber Prijsinformatie & Beoordelingen" + } } diff --git a/custom_components/tibber_prices/translations/sv.json b/custom_components/tibber_prices/translations/sv.json index 5dfc752..beb2757 100644 --- a/custom_components/tibber_prices/translations/sv.json +++ b/custom_components/tibber_prices/translations/sv.json @@ -1190,7 +1190,7 @@ "message": "{offset_param} kräver att {time_param} är satt. Dagsförskjutning ändrar bara datumet för en explicit tidsparameter." }, "min_level_exceeds_max": { - "message": "min_price_level '{min_level}' är högre än max_price_level '{max_level}'. Miniminivån måste vara lika med eller lägre än maximinivån." + "message": "min_price_level {min_level} är högre än max_price_level {max_level}. Miniminivån måste vara lika med eller lägre än maximinivån." }, "power_profile_length_mismatch": { "message": "power_profile har {profile_length} poster men varaktigheten kräver {interval_count} intervaller ({duration_minutes} minuter). power_profile måste ha exakt en post per 15-minutersintervall." @@ -1199,7 +1199,7 @@ "message": "level_filter och rating_level_filter kan inte användas tillsammans. Använd bara en filtertyp per begäran." }, "insert_nulls_requires_filter": { - "message": "insert_nulls-läge '{mode}' kräver ett level_filter eller rating_level_filter för att definiera segment. Utan filter, använd insert_nulls: none." + "message": "insert_nulls-läge {mode} kräver ett level_filter eller rating_level_filter för att definiera segment. Utan filter, använd insert_nulls: none." }, "connect_segments_requires_segments_mode": { "message": "connect_segments kräver att insert_nulls är satt till 'segments'. Ställ in insert_nulls: segments för att använda segmentanslutning." @@ -1999,6 +1999,5 @@ "next_48h": "Naesta 48 timmar" } } - }, - "title": "Tibber Prisinformation & Betyg" + } } diff --git a/docs/user/docs/sensors-trends.md b/docs/user/docs/sensors-trends.md index 6e8879f..4d4ba45 100644 --- a/docs/user/docs/sensors-trends.md +++ b/docs/user/docs/sensors-trends.md @@ -176,6 +176,44 @@ A change from `rising` to `strongly_rising` (same direction) is **not** reported | `threshold_falling_strongly_%` | Active strongly-falling threshold after volatility adjustment | `-4.8` | | `volatility_factor` | Applied multiplier (0.6 = low, 1.0 = moderate, 1.4 = high volatility) | `0.8` | +:::info How the detection works — 3-hour lookahead mean +At each future 15-minute interval, the sensor does a single comparison: + +> **interval price** vs. **average price of the following 3 hours** + +If that 3-hour-ahead average has moved in the opposite direction from the current trend, the interval counts as a "candidate" for a trend change. Once 3 consecutive candidates are found (hysteresis), the sensor reports the first one as the change timestamp. + +**Why a 3-hour average and not the next price?** +A single future price is noisy — one cheap or expensive interval doesn't mean the trend has reversed. Averaging the next 3 hours smooths out spikes and gives a stable signal about where prices are broadly heading. +::: + +:::caution On V-shaped price days — expect an early signal +On days with a sharp V-shaped curve (price drops steeply to a minimum, then rises steeply), this sensor typically fires **30–60 minutes before the exact price minimum**. + +**Why?** When the price is still falling toward the bottom, the 3-hour lookahead window already reaches across the minimum and starts including the rising prices on the other side. As soon as those rising prices pull the 3-hour average above the current falling price, the sensor detects "trend changing to rising" — even though the cheapest interval is still 2–4 steps ahead. + +**Timeline example — V-shaped day:** + +``` +Time Price 3h-ahead avg Signal +13:00 24 ct 18 ct falling (avg still below current) +13:15 20 ct 17 ct falling +13:30 16 ct 17 ct ← avg crosses above current → RISING signal ✓ +13:45 13 ct 18 ct (actual minimum — sensor already fired earlier) +14:00 16 ct 20 ct +14:15 21 ct 22 ct +``` + +**What to use instead if you need the exact minimum:** +Compare with the [Best Price Period](sensors-timing.md) start time — it finds the actual cheapest window, not the first moment the direction looks like it's changing. + +| Goal | Use | +|------|-----| +| "When will prices broadly start rising?" | **Next Price Trend Change** (may fire early) | +| "When is the cheapest interval / window to run my appliance?" | **Best Price Period** (`best_price_period`, `best_price_next_start_time`) | +| "Am I at the minimum right now?" | **Outlook `falling` + Trajectory `rising`** combination | +::: + --- ## Next Price Trend Change In (Countdown)