From b8a502672b0739f8b99866190348a217599593d7 Mon Sep 17 00:00:00 2001 From: Julian Pawlowski Date: Thu, 20 Nov 2025 12:59:12 +0000 Subject: [PATCH] refactor(config_flow): unify translation structure across all languages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standardized config flow translations (nb, nl, sv) to match German/English format with minimal field labels and comprehensive data_descriptions. Changes across Norwegian, Dutch, and Swedish translations: - Updated step_progress format: **{step_progress}** → _{step_progress}_ - Made all step descriptions bold with **text** formatting - Simplified field labels (removed verbose explanations) - Added data_description for price_rating (low/high thresholds) - Added data_description for price_trend (rising/falling thresholds) - Added data_description for volatility (moderate/high/very high thresholds) - Ensured all steps have: emojis, italic step_progress, separator (---) - Added missing emoji to Swedish price_rating step (📊) Impact: All 5 languages now have consistent UX with minimal, scannable field labels and detailed optional descriptions accessible via ⓘ icon. Users get cleaner config flow with better clarity. --- .../config_flow_handlers/schemas.py | 4 +- .../tibber_prices/translations/de.json | 126 ++++++++++-------- .../tibber_prices/translations/en.json | 104 +++++++++------ .../tibber_prices/translations/nb.json | 94 ++++++++----- .../tibber_prices/translations/nl.json | 94 ++++++++----- .../tibber_prices/translations/sv.json | 92 ++++++++----- 6 files changed, 312 insertions(+), 202 deletions(-) diff --git a/custom_components/tibber_prices/config_flow_handlers/schemas.py b/custom_components/tibber_prices/config_flow_handlers/schemas.py index 5872007..119e617 100644 --- a/custom_components/tibber_prices/config_flow_handlers/schemas.py +++ b/custom_components/tibber_prices/config_flow_handlers/schemas.py @@ -276,7 +276,7 @@ def get_best_price_schema(options: Mapping[str, Any]) -> vol.Schema: ): NumberSelector( NumberSelectorConfig( min=0, - max=100, + max=50, step=1, unit_of_measurement="%", mode=NumberSelectorMode.SLIDER, @@ -402,7 +402,7 @@ def get_peak_price_schema(options: Mapping[str, Any]) -> vol.Schema: ), ): NumberSelector( NumberSelectorConfig( - min=-100, + min=-50, max=0, step=1, unit_of_measurement="%", diff --git a/custom_components/tibber_prices/translations/de.json b/custom_components/tibber_prices/translations/de.json index e9f2852..7f08602 100644 --- a/custom_components/tibber_prices/translations/de.json +++ b/custom_components/tibber_prices/translations/de.json @@ -52,7 +52,7 @@ } }, "common": { - "step_progress": "Schritt {step_num} von {total_steps}" + "step_progress": "{step_num} / {total_steps}" }, "config_subentries": { "home": { @@ -84,95 +84,117 @@ "options": { "step": { "init": { - "title": "Allgemeine Einstellungen", - "description": "{step_progress}\n\nKonfiguration allgemeiner Einstellungen fĂŒr Tibber Preisinformationen & Bewertungen.\n\nBenutzer: {user_login}", + "title": "⚙ Allgemeine Einstellungen", + "description": "_{step_progress}_\n\n**Konfiguriere allgemeine Einstellungen fĂŒr Tibber-Preisinformationen und -bewertungen.**\n\n---\n\n**Benutzer:** {user_login}", "data": { - "extended_descriptions": "Erweiterte Beschreibungen in Entity-Attributen anzeigen" - }, - "submit": "Weiter zu Schritt 2" - }, - "current_interval_price_rating": { - "title": "Preisbewertungs-Schwellwerte", - "description": "{step_progress}\n\nKonfiguration der Schwellwerte fĂŒr Preisbewertungsstufen (niedrig/normal/hoch) basierend auf dem Vergleich mit dem gleitenden 24-Stunden-Durchschnitt.", - "data": { - "price_rating_threshold_low": "Schwellwert fĂŒr niedrige Bewertung (unter gleitendem Durchschnitt)", - "price_rating_threshold_high": "Schwellwert fĂŒr hohe Bewertung (ĂŒber gleitendem Durchschnitt)" - }, - "submit": "Weiter zu Schritt 3" - }, - "best_price": { - "title": "Bestpreis-Zeitraum Einstellungen", - "description": "{step_progress}\n\nKonfiguration fĂŒr den Bestpreis-Zeitraum mit den niedrigsten Strompreisen.", - "data": { - "best_price_min_period_length": "Minimale ZeitraumlĂ€nge", - "best_price_flex": "FlexibilitĂ€t: Maximal ĂŒber dem Mindestpreis", - "best_price_min_distance_from_avg": "Mindestabstand: Erforderlich unter dem Tagesdurchschnitt", - "best_price_max_level": "Preisniveau-Filter (Optional)", - "best_price_max_level_gap_count": "LĂŒckentoleranz fĂŒr Niveaufilter", - "enable_min_periods_best": "Mindestanzahl ZeitrĂ€ume anstreben", - "min_periods_best": "Mindestanzahl ZeitrĂ€ume", - "relaxation_attempts_best": "Lockerungsversuche (Flex-Stufen)" + "extended_descriptions": "Erweiterte Beschreibungen" }, "data_description": { + "extended_descriptions": "Steuert, ob EntitĂ€tsattribute ausfĂŒhrliche ErklĂ€rungen und Nutzungstipps enthalten.\n\n‱ Deaktiviert (Standard): Nur kurze Beschreibung\n‱ Aktiviert: AusfĂŒhrliche ErklĂ€rung + praktische Nutzungsbeispiele\n\nBeispiel:\nDeaktiviert = 1 Attribut\nAktiviert = 2 zusĂ€tzliche Attribute" + }, + "submit": "Weiter →" + }, + "current_interval_price_rating": { + "title": "📊 Preisbewertungs-Schwellenwerte", + "description": "_{step_progress}_\n\n**Konfiguriere Schwellenwerte fĂŒr Preisbewertungsstufen (niedrig/normal/hoch) basierend auf dem Vergleich mit dem nachlaufenden 24-Stunden-Durchschnitt.**\n\n---", + "data": { + "price_rating_threshold_low": "Niedrig-Schwelle", + "price_rating_threshold_high": "Hoch-Schwelle" + }, + "data_description": { + "price_rating_threshold_low": "Prozentwert, um wie viel der aktuelle Preis unter dem nachlaufenden 24-Stunden-Durchschnitt liegen muss, damit er als 'niedrig' bewertet wird. Beispiel: 5 bedeutet mindestens 5% unter Durchschnitt. Sensoren mit dieser Bewertung zeigen gĂŒnstige Zeitfenster an. Standard: 5%", + "price_rating_threshold_high": "Prozentwert, um wie viel der aktuelle Preis ĂŒber dem nachlaufenden 24-Stunden-Durchschnitt liegen muss, damit er als 'hoch' bewertet wird. Beispiel: 10 bedeutet mindestens 10% ĂŒber Durchschnitt. Sensoren mit dieser Bewertung warnen vor teuren Zeitfenstern. Standard: 10%" + }, + "submit": "Weiter →" + }, + "best_price": { + "title": "💚 Bestpreis-Zeitraum Einstellungen", + "description": "_{step_progress}_\n\n**Konfiguration fĂŒr den Bestpreis-Zeitraum mit den niedrigsten Strompreisen.**\n\n---", + "data": { + "best_price_min_period_length": "Minimale ZeitraumlĂ€nge", + "best_price_flex": "FlexibilitĂ€t", + "best_price_min_distance_from_avg": "Mindestabstand", + "best_price_max_level": "Preisniveau-Filter", + "best_price_max_level_gap_count": "LĂŒckentoleranz", + "enable_min_periods_best": "Mindestanzahl anstreben", + "min_periods_best": "Mindestanzahl ZeitrĂ€ume", + "relaxation_attempts_best": "Lockerungsversuche" + }, + "data_description": { + "best_price_min_period_length": "Minimale Dauer, damit ein Zeitraum als 'Bestpreis' gilt. LĂ€ngere ZeitrĂ€ume sind praktischer fĂŒr den Betrieb von GerĂ€ten wie GeschirrspĂŒlern oder WĂ€rmepumpen. Bestpreis-ZeitrĂ€ume erfordern mindestens 60 Minuten (im Vergleich zu 30 Minuten fĂŒr Spitzenpreis-Warnungen), da sie sinnvolle Zeitfenster fĂŒr die Verbrauchsplanung bieten sollen, nicht nur kurze Gelegenheiten.", + "best_price_flex": "Maximal ĂŒber dem tĂ€glichen Mindestpreis, bei dem Intervalle noch als 'Bestpreis' qualifizieren. Empfehlung: 15-20 mit aktivierter Lockerung (Standard), oder 25-35 ohne Lockerung. Maximum: 50 (harte Grenze fĂŒr zuverlĂ€ssige Zeitraumerkennung).", + "best_price_min_distance_from_avg": "Stellt sicher, dass ZeitrĂ€ume signifikant gĂŒnstiger als der Tagesdurchschnitt sind, nicht nur geringfĂŒgig darunter. Dies filtert Rauschen und verhindert, dass leicht unterdurchschnittliche ZeitrĂ€ume an Tagen mit flachen Preisen als 'Bestpreis' markiert werden. Höhere Werte = strengere Filterung (nur wirklich gĂŒnstige ZeitrĂ€ume qualifizieren). Standard: 5 bedeutet, ZeitrĂ€ume mĂŒssen mindestens 5% unter dem Tagesdurchschnitt liegen.", "best_price_max_level": "Zeigt Bestpreis-ZeitrĂ€ume nur an, wenn sie Intervalle mit Preisniveaus ≀ dem gewĂ€hlten Wert enthalten. Beispiel: Wahl von 'GĂŒnstig' bedeutet, dass der Zeitraum mindestens ein 'SEHR GÜNSTIG' oder 'GÜNSTIG' Intervall haben muss. Dies stellt sicher, dass Bestpreis-ZeitrĂ€ume nicht nur relativ gĂŒnstig fĂŒr den Tag sind, sondern tatsĂ€chlich gĂŒnstig in absoluten Zahlen. WĂ€hle 'Beliebig' um Bestpreise unabhĂ€ngig vom absoluten Preisniveau anzuzeigen.", "best_price_max_level_gap_count": "Maximale Anzahl aufeinanderfolgender Intervalle, die exakt um eine Niveaustufe vom geforderten Level abweichen dĂŒrfen. Beispiel: Bei Filter 'GĂŒnstig' und LĂŒckentoleranz 1 wird die Sequenz 'GÜNSTIG, GÜNSTIG, NORMAL, GÜNSTIG' akzeptiert (NORMAL ist eine Stufe ĂŒber GÜNSTIG). Dies verhindert, dass ZeitrĂ€ume durch gelegentliche Niveau-Abweichungen aufgespalten werden. Standard: 1.", "enable_min_periods_best": "Wenn aktiviert, werden Filter schrittweise gelockert, falls nicht genug ZeitrĂ€ume gefunden wurden. Dies versucht die gewĂŒnschte Mindestanzahl zu erreichen, was dazu fĂŒhren kann, dass auch weniger optimale ZeitrĂ€ume als Bestpreis-ZeitrĂ€ume markiert werden.", "min_periods_best": "Mindestanzahl an Bestpreis-ZeitrĂ€umen, die pro Tag angestrebt werden. Filter werden schrittweise gelockert, um diese Anzahl zu erreichen. Nur aktiv, wenn 'Mindestanzahl ZeitrĂ€ume anstreben' aktiviert ist. Standard: 1", "relaxation_attempts_best": "Wie viele Flex-Stufen (Versuche) nacheinander ausprobiert werden, bevor aufgegeben wird. Jeder Versuch testet alle Filterkombinationen auf der neuen Flex-Stufe. Mehr Versuche erhöhen die Chance auf zusĂ€tzliche ZeitrĂ€ume, benötigen aber etwas mehr Rechenzeit." }, - "submit": "Weiter zu Schritt 5" + "submit": "Weiter →" }, "peak_price": { - "title": "Spitzenpreis-Zeitraum Einstellungen", - "description": "{step_progress}\n\nKonfiguration fĂŒr den Spitzenpreis-Zeitraum mit den höchsten Strompreisen.", + "title": "🔮 Spitzenpreis-Zeitraum Einstellungen", + "description": "_{step_progress}_\n\n**Konfiguration fĂŒr den Spitzenpreis-Zeitraum mit den höchsten Strompreisen.**\n\n---", "data": { "peak_price_min_period_length": "Minimale ZeitraumlĂ€nge", - "peak_price_flex": "FlexibilitĂ€t: Maximal unter dem Höchstpreis (negativer Wert)", - "peak_price_min_distance_from_avg": "Mindestabstand: Erforderlich ĂŒber dem Tagesdurchschnitt", - "peak_price_min_level": "Preisniveau-Filter (Optional)", - "peak_price_max_level_gap_count": "LĂŒckentoleranz fĂŒr Niveaufilter", - "enable_min_periods_peak": "Mindestanzahl ZeitrĂ€ume anstreben", + "peak_price_flex": "FlexibilitĂ€t", + "peak_price_min_distance_from_avg": "Mindestabstand", + "peak_price_min_level": "Preisniveau-Filter", + "peak_price_max_level_gap_count": "LĂŒckentoleranz", + "enable_min_periods_peak": "Mindestanzahl anstreben", "min_periods_peak": "Mindestanzahl ZeitrĂ€ume", - "relaxation_attempts_peak": "Lockerungsversuche (Flex-Stufen)" + "relaxation_attempts_peak": "Lockerungsversuche" }, "data_description": { + "peak_price_min_period_length": "Minimale Dauer, damit ein Zeitraum als 'Spitzenpreis' gilt. Spitzenpreis-Warnungen sind fĂŒr kĂŒrzere ZeitrĂ€ume zulĂ€ssig (mindestens 30 Minuten im Vergleich zu 60 Minuten fĂŒr Bestpreis), da kurze teure Spitzen eine Warnung wert sind, auch wenn sie fĂŒr die Verbrauchsplanung zu kurz sind.", + "peak_price_flex": "Maximal unter dem tĂ€glichen Höchstpreis, bei dem Intervalle noch als 'Spitzenpreis' qualifizieren. Empfehlung: -15 bis -20 mit aktivierter Lockerung (Standard), oder -25 bis -35 ohne Lockerung. Maximum: -50 (harte Grenze fĂŒr zuverlĂ€ssige Zeitraumerkennung). Hinweis: Negative Werte zeigen den Abstand unter dem Maximum an.", + "peak_price_min_distance_from_avg": "Stellt sicher, dass ZeitrĂ€ume signifikant teurer als der Tagesdurchschnitt sind, nicht nur geringfĂŒgig darĂŒber. Dies filtert Rauschen und verhindert, dass leicht ĂŒberdurchschnittliche ZeitrĂ€ume an Tagen mit flachen Preisen als 'Spitzenpreis' markiert werden. Höhere Werte = strengere Filterung (nur wirklich teure ZeitrĂ€ume qualifizieren). Standard: 5 bedeutet, ZeitrĂ€ume mĂŒssen mindestens 5% ĂŒber dem Tagesdurchschnitt liegen.", "peak_price_min_level": "Zeigt Spitzenpreis-ZeitrĂ€ume nur an, wenn sie Intervalle mit Preisniveaus ≄ dem gewĂ€hlten Wert enthalten. Beispiel: Wahl von 'Teuer' bedeutet, dass der Zeitraum mindestens ein 'TEUER' oder 'SEHR TEUER' Intervall haben muss. Dies stellt sicher, dass Spitzenpreis-ZeitrĂ€ume nicht nur relativ teuer fĂŒr den Tag sind, sondern tatsĂ€chlich teuer in absoluten Zahlen. WĂ€hle 'Beliebig' um Spitzenpreise unabhĂ€ngig vom absoluten Preisniveau anzuzeigen.", "peak_price_max_level_gap_count": "Maximale Anzahl aufeinanderfolgender Intervalle, die exakt um eine Niveaustufe vom geforderten Level abweichen dĂŒrfen. Beispiel: Bei Filter 'Teuer' und LĂŒckentoleranz 2 wird die Sequenz 'TEUER, NORMAL, NORMAL, TEUER' akzeptiert (NORMAL ist eine Stufe unter TEUER). Dies verhindert, dass ZeitrĂ€ume durch gelegentliche Niveau-Abweichungen aufgespalten werden. Standard: 0.", "enable_min_periods_peak": "Wenn aktiviert, werden Filter schrittweise gelockert, falls nicht genug ZeitrĂ€ume gefunden wurden. Dies versucht die gewĂŒnschte Mindestanzahl zu erreichen, um sicherzustellen, dass du auch an Tagen mit ungewöhnlichen Preismustern vor teuren ZeitrĂ€umen gewarnt wirst.", "min_periods_peak": "Mindestanzahl an Spitzenpreis-ZeitrĂ€umen, die pro Tag angestrebt werden. Filter werden schrittweise gelockert, um diese Anzahl zu erreichen. Nur aktiv, wenn 'Mindestanzahl ZeitrĂ€ume anstreben' aktiviert ist. Standard: 1", "relaxation_attempts_peak": "Wie viele Flex-Stufen (Versuche) nacheinander ausprobiert werden, bevor aufgegeben wird. Jeder Versuch testet alle Filterkombinationen auf der neuen Flex-Stufe. Mehr Versuche erhöhen die Chance auf zusĂ€tzliche Spitzenpreis-ZeitrĂ€ume, benötigen aber etwas mehr Rechenzeit." }, - "submit": "Weiter zu Schritt 6" + "submit": "Weiter →" }, "price_trend": { - "title": "Preistrend-Schwellenwerte", - "description": "{step_progress}\n\nKonfiguriere Schwellenwerte fĂŒr Preistrend-Sensoren. Diese Sensoren vergleichen den aktuellen Preis mit dem Durchschnitt der nĂ€chsten N Stunden, um festzustellen, ob die Preise steigen, fallen oder stabil sind.", + "title": "📈 Pristrend-Schwellenwerte", + "description": "_{step_progress}_\n\n**Konfiguriere Schwellenwerte fĂŒr Preistrend-Sensoren. Diese Sensoren vergleichen den aktuellen Preis mit dem Durchschnitt der nĂ€chsten N Stunden, um festzustellen, ob die Preise steigen, fallen oder stabil sind.**\n\n---", "data": { - "price_trend_threshold_rising": "Steigender Schwellenwert (ĂŒber dem aktuellen Preis)", - "price_trend_threshold_falling": "Fallender Schwellenwert (unter dem aktuellen Preis, negativer Wert)" + "price_trend_threshold_rising": "Steigend-Schwelle", + "price_trend_threshold_falling": "Fallend-Schwelle" }, - "submit": "Weiter zu Schritt 7" + "data_description": { + "price_trend_threshold_rising": "Prozentwert, um wie viel der Durchschnitt der nĂ€chsten N Stunden ĂŒber dem aktuellen Preis liegen muss, damit der Trend als 'steigend' gilt. Beispiel: 5 bedeutet Durchschnitt ist mindestens 5% höher → Preise werden steigen. Typische Werte: 5-15%. Standard: 5%", + "price_trend_threshold_falling": "Prozentwert (negativ), um wie viel der Durchschnitt der nĂ€chsten N Stunden unter dem aktuellen Preis liegen muss, damit der Trend als 'fallend' gilt. Beispiel: -5 bedeutet Durchschnitt ist mindestens 5% niedriger → Preise werden fallen. Typische Werte: -5 bis -15%. Standard: -5%" + }, + "submit": "Weiter →" }, "volatility": { - "title": "VolatilitĂ€t Schwellenwerte", - "description": "{step_progress}\n\nKonfiguriere Schwellenwerte fĂŒr die VolatilitĂ€tsklassifizierung. VolatilitĂ€t misst relative Preisschwankungen anhand des Variationskoeffizienten (VK = Standardabweichung / Durchschnitt × 100%). Diese Schwellenwerte sind Prozentwerte, die fĂŒr alle Preisniveaus funktionieren.\n\nVerwendet von:\n‱ VolatilitĂ€tssensoren (Klassifizierung)\n‱ Trend-Sensoren (adaptive Schwellenanpassung: