hass.tibber_prices/custom_components/tibber_prices/translations/nb.json
Julian Pawlowski 817658f230 feat(periods): add gap tolerance for price level filters with intelligent period splitting
Implemented configurable gap tolerance (0-8 intervals) for best price and peak price
level filters to prevent periods from being split by occasional level deviations.

Key features:
- Gap tolerance only applies to periods ≥ MIN_INTERVALS_FOR_GAP_TOLERANCE (1.5h)
- Short periods (< 1.5h) use strict filtering (zero tolerance)
- Dynamic minimum distance between gaps: max(2, (interval_count // max_gap_count) // 2)
- 25% maximum cap on total gaps to prevent excessive outliers in long periods
- Intelligent period splitting at gap clusters (2+ consecutive non-qualifying intervals)
- Each sub-period independently validated with same gap tolerance rules

Technical implementation:
- Added CONF_BEST_PRICE_MAX_LEVEL_GAP_COUNT and CONF_PEAK_PRICE_MAX_LEVEL_GAP_COUNT constants
- Added MIN_INTERVALS_FOR_GAP_TOLERANCE = 6 (1.5h minimum for gap tolerance)
- Implemented _split_at_gap_clusters() for period recovery
- Implemented _check_short_period_strict() for strict short-period filtering
- Implemented _check_level_filter_with_gaps() with fallback splitting logic
- Extracted _check_sequence_with_gap_tolerance() for reusable core validation
- Enhanced _check_level_filter() to use gap-tolerant validation

Configuration UI:
- Added NumberSelector (0-8, slider mode) for gap count in config flow
- Added translations for all 5 languages (de, en, nb, nl, sv)
- Default: 0 (strict filtering, backwards compatible)

Impact: Users can now configure how many occasional level deviations are acceptable
within qualifying price periods. This reduces period fragmentation while maintaining
meaningful price-based filtering. Long periods are protected by the 25% cap, and
gap clusters trigger intelligent splitting to recover usable sub-periods.
2025-11-10 04:38:44 +00:00

518 lines
No EOL
25 KiB
JSON

{
"config": {
"step": {
"user": {
"description": "Sett opp Tibber Prisinformasjon & Vurderinger.\n\nFor å generere et API-tilgangstoken, besøk https://developer.tibber.com.",
"data": {
"access_token": "API-tilgangstoken"
},
"submit": "Valider token"
},
"select_home": {
"description": "Velg et hjem for å hente prisinformasjon og vurderinger.",
"data": {
"home_id": "Hjem"
},
"title": "Velg et hjem",
"submit": "Velg hjem"
},
"finish": {
"description": "Velg et hjem for å hente prisinformasjon og vurderinger.",
"data": {
"home_id": "Hjem-ID"
},
"title": "Velg et hjem",
"submit": "Velg hjem"
},
"reauth_confirm": {
"title": "Autentiser Tibber Prisintegrasjonen på nytt",
"description": "Tilgangstokenet for Tibber er ikke lenger gyldig. Vennligst oppgi et nytt API-tilgangstoken for å fortsette å bruke denne integrasjonen.\n\nFor å generere et nytt API-tilgangstoken, besøk https://developer.tibber.com.",
"data": {
"access_token": "API-tilgangstoken"
},
"submit": "Oppdater token"
}
},
"error": {
"auth": "Tibber-tilgangstokenet er ugyldig.",
"connection": "Kunne ikke koble til Tibber. Vennligst sjekk internettforbindelsen din.",
"unknown": "Uventet feil",
"cannot_connect": "Kunne ikke koble til",
"invalid_access_token": "Ugyldig tilgangstoken",
"missing_homes": "Det nye tilgangstokenet har ikke tilgang til alle konfigurerte hjem. Vennligst bruk et tilgangstoken som har tilgang til de samme Tibber-hjemmene."
},
"abort": {
"already_configured": "Integrasjonen er allerede konfigurert",
"entry_not_found": "Tibber-konfigurasjonsoppføring ikke funnet.",
"setup_complete": "Oppsett fullført! Du kan endre flere innstillinger for Tibber-priser i integrasjonens alternativer etter å ha lukket denne dialogen.",
"reauth_successful": "Autentisering vellykket. Integrasjonen er oppdatert med det nye tilgangstokenet."
}
},
"common": {
"step_progress": "Trinn {step_num} av {total_steps}"
},
"config_subentries": {
"home": {
"initiate_flow": {
"user": "Legg til Tibber-hjem"
},
"title": "Legg til Tibber-hjem",
"step": {
"user": {
"title": "Legg til Tibber-hjem",
"description": "Velg et hjem å legge til i din Tibber-integrasjon.\n\n**Merk:** Etter å ha lagt til dette hjemmet, kan du legge til flere hjem fra integrasjonens kontekstmeny ved å velge \"Legg til Tibber-hjem\".",
"data": {
"home_id": "Hjem"
}
}
},
"error": {
"api_error": "Kunne ikke hente hjem fra Tibber API"
},
"abort": {
"no_parent_entry": "Overordnet oppføring ikke funnet",
"no_access_token": "Ingen tilgangstoken tilgjengelig",
"home_not_found": "Valgt hjem ikke funnet",
"api_error": "Kunne ikke hente hjem fra Tibber API",
"no_available_homes": "Ingen flere hjem tilgjengelig for å legge til. Alle hjem fra din Tibber-konto er allerede lagt til."
}
}
},
"options": {
"step": {
"init": {
"title": "Generelle innstillinger",
"description": "{step_progress}\n\nKonfigurer generelle innstillinger for Tibber Prisinformasjon & Vurderinger.\n\nBruker: {user_login}",
"data": {
"extended_descriptions": "Vis utvidede beskrivelser i entitetsattributter"
},
"submit": "Neste til steg 2"
},
"price_rating": {
"title": "Prisvurderingsterskler",
"description": "{step_progress}\n\nKonfigurer terskler for prisvurderingsnivåer (lav/normal/høy) basert på sammenligning med 24-timers glidende gjennomsnitt.",
"data": {
"price_rating_threshold_low": "Lav vurderingsterskel (% under glidende gjennomsnitt)",
"price_rating_threshold_high": "Høy vurderingsterskel (% over glidende gjennomsnitt)"
},
"submit": "Neste til steg 3"
},
"best_price": {
"title": "Innstillinger for beste prisperiode",
"description": "{step_progress}\n\nKonfigurer innstillinger for binærsensoren Beste prisperiode. Denne sensoren er aktiv i perioder med de laveste strømprisene.",
"data": {
"best_price_min_period_length": "Minimum periodelengde",
"best_price_flex": "Fleksibilitet: Maksimum % over minimumspris",
"best_price_min_distance_from_avg": "Minimumsavstand: Påkrevd % under daglig gjennomsnitt",
"best_price_min_volatility": "Minimum volatilitetsfilter",
"best_price_max_level": "Prisnivåfilter (valgfritt)",
"best_price_max_level_gap_count": "Gaptoleranse for nivåfilter",
"enable_min_periods_best": "Prøv å oppnå minimum antall perioder",
"min_periods_best": "Minimum antall perioder",
"relaxation_step_best": "Avslappingstrinn"
},
"data_description": {
"best_price_min_volatility": "Vis kun beste prisperioder når periodens interne prisvolatilitet (prisspennet innenfor perioden) oppfyller eller overskrider dette nivået. Standard: 'Lav' (vis perioder med hvilket som helst volatilitetsnivå) - gjør det mulig å finne billige perioder selv om prisene er stabile. Velg 'Moderat'/'Høy' for kun å vise perioder med betydelige prisvariasjoner, noe som kan indikere mer dynamiske prismuligheter.",
"best_price_max_level": "Vis kun beste prisperioder hvis de inneholder intervaller med prisnivåer ≤ valgt verdi. For eksempel: å velge 'Billig' betyr at perioden må ha minst ett 'VELDIG_BILLIG' eller 'BILLIG' intervall. Dette sikrer at 'beste pris'-perioder ikke bare er relativt billige for dagen, men faktisk billige i absolutte tall. Velg 'Alle' for å vise beste priser uavhengig av deres absolutte prisnivå.",
"enable_min_periods_best": "Når aktivert vil filtrene gradvis bli lempeligere hvis det ikke blir funnet nok perioder. Dette forsøker å nå ønsket minimum antall perioder, noe som kan føre til at mindre optimale tidsrom blir markert som beste-pris-perioder.",
"min_periods_best": "Minimum antall beste-pris-perioder å sikte mot per dag. Filtre vil bli lempet trinn for trinn for å prøve å oppnå dette antallet. Kun aktiv når 'Prøv å oppnå minimum antall perioder' er aktivert. Standard: 1",
"relaxation_step_best": "Prosentandel av den opprinnelige fleksibilitetsterskealen som legges til per avslappingstrinn. For eksempel: med 15% fleksibilitet og 25% trinnstørrelse vil filtrene prøve 15%, 18,75%, 22,5%, osv. Høyere verdier betyr raskere avslapping men mindre presisjon.",
"best_price_max_level_gap_count": "Maksimalt antall påfølgende intervaller som kan avvike med nøyaktig ett nivåtrinn fra det nødvendige nivået. For eksempel: med 'Billig' filter og gapantall 1, aksepteres sekvensen 'BILLIG, BILLIG, NORMAL, BILLIG' (NORMAL er ett trinn over BILLIG). Dette forhindrer at perioder blir delt opp av tilfeldige nivåavvik. Standard: 0 (streng filtrering, ingen toleranse)."
},
"submit": "Neste til steg 5"
},
"peak_price": {
"title": "Innstillinger for topprisperiode",
"description": "{step_progress}\n\nKonfigurer innstillinger for binærsensoren Topprisperiode. Denne sensoren er aktiv i perioder med de høyeste strømprisene.",
"data": {
"peak_price_min_period_length": "Minimum periodelengde",
"peak_price_flex": "Fleksibilitet: Maksimum % under maksimumspris (negativ verdi)",
"peak_price_min_distance_from_avg": "Minimumsavstand: Påkrevd % over daglig gjennomsnitt",
"peak_price_min_volatility": "Minimum volatilitetsfilter",
"peak_price_min_level": "Prisnivåfilter (valgfritt)",
"peak_price_max_level_gap_count": "Gaptoleranse for nivåfilter",
"enable_min_periods_peak": "Prøv å oppnå minimum antall perioder",
"min_periods_peak": "Minimum antall perioder",
"relaxation_step_peak": "Avslappingstrinn"
},
"data_description": {
"peak_price_min_volatility": "Vis kun topprisperioder når periodens interne prisvolatilitet (prisspennet innenfor perioden) oppfyller eller overskrider dette nivået. Standard: 'Lav' (vis perioder med hvilket som helst volatilitetsnivå) - gjør det mulig å identifisere dyre perioder selv om prisene er stabile. Velg 'Moderat'/'Høy' for kun å vise perioder med betydelige prisvariasjoner, noe som kan indikere mer presserende behov for å unngå disse tidspunktene.",
"peak_price_min_level": "Vis kun topprisperioder hvis de inneholder intervaller med prisnivåer ≥ valgt verdi. For eksempel: å velge 'Dyr' betyr at perioden må ha minst ett 'DYR' eller 'VELDIG_DYR' intervall. Dette sikrer at 'topppris'-perioder ikke bare er relativt dyre for dagen, men faktisk dyre i absolutte tall. Velg 'Alle' for å vise topppriser uavhengig av deres absolutte prisnivå.",
"enable_min_periods_peak": "Når aktivert vil filtrene gradvis bli lempeligere hvis det ikke blir funnet nok perioder. Dette forsøker å nå ønsket minimum antall perioder for å sikre at du blir advart om dyre perioder selv på dager med uvanlige prismønstre.",
"min_periods_peak": "Minimum antall topp-pris-perioder å sikte mot per dag. Filtre vil bli lempet trinn for trinn for å prøve å oppnå dette antallet. Kun aktiv når 'Prøv å oppnå minimum antall perioder' er aktivert. Standard: 1",
"relaxation_step_peak": "Prosentandel av den opprinnelige fleksibilitetsterskealen som legges til per avslappingstrinn. For eksempel: med -15% fleksibilitet og 25% trinnstørrelse vil filtrene prøve -15%, -18,75%, -22,5%, osv. Høyere verdier betyr raskere avslapping men mindre presisjon.",
"peak_price_max_level_gap_count": "Maksimalt antall påfølgende intervaller som kan avvike med nøyaktig ett nivåtrinn fra det nødvendige nivået. For eksempel: med 'Dyr' filter og gapantall 2, aksepteres sekvensen 'DYR, NORMAL, NORMAL, DYR' (NORMAL er ett trinn under DYR). Dette forhindrer at perioder blir delt opp av tilfeldige nivåavvik. Standard: 0 (streng filtrering, ingen toleranse)."
},
"submit": "Neste til steg 6"
},
"price_trend": {
"title": "Pristrendterskler",
"description": "{step_progress}\n\nKonfigurer terskler for pristrendsensorer. Disse sensorene sammenligner nåværende pris med gjennomsnittet av de neste N timene for å bestemme om prisene stiger, faller eller er stabile.",
"data": {
"price_trend_threshold_rising": "Stigende terskel (% over nåværende pris)",
"price_trend_threshold_falling": "Fallende terskel (% under nåværende pris, negativ verdi)"
},
"submit": "Fullfør konfigurasjon"
},
"volatility": {
"title": "Prisvolatilitet Terskler",
"description": "{step_progress}\n\nKonfigurer terskler for volatilitetsklassifisering. Volatilitet måler prisvariasjoner (spredning mellom min/maks) i minste valutaenhet (ct/øre). Disse tersklene brukes av volatilitetssensorer og periodefiltre.",
"data": {
"volatility_threshold_moderate": "Moderat terskel (ct/øre, spredning ≥ denne verdien)",
"volatility_threshold_high": "Høy terskel (ct/øre, spredning ≥ denne verdien)",
"volatility_threshold_very_high": "Veldig høy terskel (ct/øre, spredning ≥ denne verdien)"
},
"submit": "Neste til steg 4"
}
},
"error": {
"auth": "Tibber-tilgangstokenet er ugyldig.",
"connection": "Kunne ikke koble til Tibber. Vennligst sjekk internettforbindelsen din.",
"unknown": "En uventet feil oppstod. Vennligst sjekk loggene for detaljer.",
"cannot_connect": "Kunne ikke koble til",
"invalid_access_token": "Ugyldig tilgangstoken",
"different_home": "Tilgangstokenet er ikke gyldig for hjem-ID-en denne integrasjonen er konfigurert for."
},
"abort": {
"entry_not_found": "Tibber-konfigurasjonsoppføring ikke funnet."
}
},
"entity": {
"sensor": {
"current_price": {
"name": "Nåværende strømpris"
},
"next_interval_price": {
"name": "Neste pris"
},
"previous_interval_price": {
"name": "Forrige strømpris"
},
"current_hour_average": {
"name": "Nåværende timepris gjennomsnitt"
},
"next_hour_average": {
"name": "Neste timepris gjennomsnitt"
},
"price_level": {
"name": "Nåværende prisnivå",
"state": {
"very_cheap": "Veldig billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Veldig dyr"
}
},
"next_interval_price_level": {
"name": "Neste prisnivå",
"state": {
"very_cheap": "Veldig billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Veldig dyr"
}
},
"previous_interval_price_level": {
"name": "Forrige prisnivå",
"state": {
"very_cheap": "Veldig billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Veldig dyr"
}
},
"current_hour_price_level": {
"name": "Nåværende timepris nivå",
"state": {
"very_cheap": "Veldig billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Veldig dyr"
}
},
"next_hour_price_level": {
"name": "Neste timepris nivå",
"state": {
"very_cheap": "Veldig billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Veldig dyr"
}
},
"lowest_price_today": {
"name": "Dagens laveste pris"
},
"highest_price_today": {
"name": "Dagens høyeste pris"
},
"average_price_today": {
"name": "Dagens gjennomsnittspris"
},
"lowest_price_tomorrow": {
"name": "Morgendagens laveste pris"
},
"highest_price_tomorrow": {
"name": "Morgendagens høyeste pris"
},
"average_price_tomorrow": {
"name": "Morgendagens gjennomsnittspris"
},
"trailing_price_average": {
"name": "Glidende 24t gjennomsnittspris"
},
"leading_price_average": {
"name": "Fremtidig 24t gjennomsnittspris"
},
"trailing_price_min": {
"name": "Glidende 24t minimumspris"
},
"trailing_price_max": {
"name": "Glidende 24t maksimumspris"
},
"leading_price_min": {
"name": "Fremtidig 24t minimumspris"
},
"leading_price_max": {
"name": "Fremtidig 24t maksimumspris"
},
"price_rating": {
"name": "Nåværende prisvurdering",
"state": {
"low": "Lav",
"normal": "Normal",
"high": "Høy"
}
},
"next_interval_price_rating": {
"name": "Neste prisvurdering",
"state": {
"low": "Lav",
"normal": "Normal",
"high": "Høy"
}
},
"previous_interval_price_rating": {
"name": "Forrige prisvurdering",
"state": {
"low": "Lav",
"normal": "Normal",
"high": "Høy"
}
},
"current_hour_price_rating": {
"name": "Nåværende timepris vurdering",
"state": {
"low": "Lav",
"normal": "Normal",
"high": "Høy"
}
},
"next_hour_price_rating": {
"name": "Neste timepris vurdering",
"state": {
"low": "Lav",
"normal": "Normal",
"high": "Høy"
}
},
"next_avg_1h": {
"name": "Neste 1t gjennomsnittspris"
},
"next_avg_2h": {
"name": "Neste 2t gjennomsnittspris"
},
"next_avg_3h": {
"name": "Neste 3t gjennomsnittspris"
},
"next_avg_4h": {
"name": "Neste 4t gjennomsnittspris"
},
"next_avg_5h": {
"name": "Neste 5t gjennomsnittspris"
},
"next_avg_6h": {
"name": "Neste 6t gjennomsnittspris"
},
"next_avg_8h": {
"name": "Neste 8t gjennomsnittspris"
},
"next_avg_12h": {
"name": "Neste 12t gjennomsnittspris"
},
"price_trend_1h": {
"name": "Pristrend (1t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_2h": {
"name": "Pristrend (2t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_3h": {
"name": "Pristrend (3t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_4h": {
"name": "Pristrend (4t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_5h": {
"name": "Pristrend (5t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_6h": {
"name": "Pristrend (6t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_8h": {
"name": "Pristrend (8t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"price_trend_12h": {
"name": "Pristrend (12t)",
"state": {
"rising": "Stigende",
"falling": "Fallende",
"stable": "Stabil"
}
},
"daily_rating": {
"name": "Daglig prisvurdering"
},
"monthly_rating": {
"name": "Månedlig prisvurdering"
},
"data_timestamp": {
"name": "Prisdata Utløp"
},
"today_volatility": {
"name": "Dagens Prisvolatilitet",
"state": {
"low": "Lav",
"moderate": "Moderat",
"high": "Høy",
"very_high": "Svært Høy"
}
},
"tomorrow_volatility": {
"name": "Morgendagens Prisvolatilitet",
"state": {
"low": "Lav",
"moderate": "Moderat",
"high": "Høy",
"very_high": "Svært Høy"
}
},
"next_24h_volatility": {
"name": "Neste 24t Prisvolatilitet",
"state": {
"low": "Lav",
"moderate": "Moderat",
"high": "Høy",
"very_high": "Svært Høy"
}
},
"today_tomorrow_volatility": {
"name": "I dag+I morgen Prisvolatilitet",
"state": {
"low": "Lav",
"moderate": "Moderat",
"high": "Høy",
"very_high": "Svært Høy"
}
},
"price_forecast": {
"name": "Prisprognose"
}
},
"binary_sensor": {
"peak_price_period": {
"name": "Topprisperiode"
},
"best_price_period": {
"name": "Beste prisperiode"
},
"connection": {
"name": "Tibber API-tilkobling"
},
"tomorrow_data_available": {
"name": "Morgendagens data tilgjengelig"
}
}
},
"issues": {
"new_homes_available": {
"title": "Nye Tibber-hjem oppdaget",
"description": "Vi oppdaget {count} nytt/nye hjem på din Tibber-konto: {homes}. Du kan legge dem til i Home Assistant gjennom Tibber-integrasjonskonfigurasjonen."
},
"homes_removed": {
"title": "Tibber-hjem fjernet",
"description": "Vi oppdaget at {count} hjem har blitt fjernet fra din Tibber-konto: {homes}. Vennligst gjennomgå din Tibber-integrasjonskonfigurasjon."
}
},
"services": {
"refresh_user_data": {
"name": "Oppdater brukerdata",
"description": "Tvinger en oppdatering av brukerdataene (hjem, profilinformasjon) fra Tibber API. Dette kan være nyttig etter å ha gjort endringer i Tibber-kontoen din eller ved feilsøking av tilkoblingsproblemer.",
"fields": {
"entry_id": {
"name": "Oppførings-ID",
"description": "Konfig-oppførings-ID for Tibber-integrasjonen."
}
}
}
},
"selector": {
"volatility": {
"options": {
"low": "Lav",
"moderate": "Moderat",
"high": "Høy",
"very_high": "Svært høy"
}
},
"price_level": {
"options": {
"any": "Alle",
"very_cheap": "Svært billig",
"cheap": "Billig",
"normal": "Normal",
"expensive": "Dyr",
"very_expensive": "Svært dyr"
}
}
},
"title": "Tibber Prisinformasjon & Vurderinger"
}