Commit graph

419 commits

Author SHA1 Message Date
Julian Pawlowski
ac6f1e0955 chore(release): bump version to 0.20.0 2025-12-05 18:14:32 +00:00
Julian Pawlowski
c8e9f7ec2a feat(apexcharts): add server-side metadata with dynamic yaxis and gradient
Implemented comprehensive metadata calculation for chart data export service
with automatic Y-axis scaling and gradient positioning based on actual price
statistics.

Changes:
- Added 'metadata' parameter to get_chartdata service (include/only/none)
- Implemented _calculate_metadata() with per-day price statistics
  * min/max/avg/median prices
  * avg_position and median_position (0-1 scale for gradient stops)
  * yaxis_suggested bounds (floor(min)-1, ceil(max)+1)
  * time_range with day boundaries
  * currency info with symbol and unit
- Integrated metadata into rolling_window modes via config-template-card
  * Pre-calculated yaxis bounds (no async issues in templates)
  * Dynamic gradient stops based on avg_position
  * Server-side calculation ensures consistency

Visual refinements:
- Best price overlay opacity reduced to 0.05 (ultra-subtle green hint)
- Stroke width increased to 1.5 for better visibility
- Gradient opacity adjusted to 0.45 with "light" shade
- Marker configuration: size 0, hover size 2, strokeWidth 1
- Header display: Only show LOW/HIGH rating_levels (min/max prices)
  * Conditional logic excludes NORMAL and level types
  * Entity state shows meaningful extrema values
- NOW marker label removed for rolling_window_autozoom mode
  * Static position at 120min lookback makes label misleading

Code cleanup:
- Removed redundant all_series_config (server-side data formatting)
- Currency names capitalized (Cents, Øre, Öre, Pence)

Translation updates:
- Added metadata selector translations (de, en, nb, nl, sv)
- Added metadata field description in services
- Synchronized all language files

Impact: Users get dynamic Y-axis scaling based on actual price data,
eliminating manual configuration. Rolling window charts automatically
adjust axis bounds and gradient positioning. Header shows only
meaningful extreme values (daily min/max). All data transformation
happens server-side for optimal performance and consistency.
2025-12-05 18:14:18 +00:00
Julian Pawlowski
2f1929fbdc chore(release): bump version to 0.19.0 2025-12-04 14:39:16 +00:00
Julian Pawlowski
c9a7dcdae7 feat(services): add rolling window options with auto-zoom for ApexCharts
Added two new rolling window options for get_apexcharts_yaml service to provide
flexible dynamic chart visualization:

- rolling_window: Fixed 48h window that automatically shifts between
  yesterday+today and today+tomorrow based on data availability
- rolling_window_autozoom: Same as rolling_window but with progressive zoom-in
  (2h lookback + remaining time until midnight, updates every 15min)

Implementation changes:
- Updated service schema validation to accept new day options
- Added entity mapping patterns for both rolling modes
- Implemented minute-based graph_span calculation with quarter-hour alignment
- Added config-template-card integration for dynamic span updates
- Used current_interval_price sensor as 15-minute update trigger
- Unified data loading: both rolling modes omit day parameter for dynamic selection
- Applied ternary operator pattern for cleaner day_param logic
- Made grid lines more subtle (borderColor #f5f5f5, strokeDashArray 0)

Translation updates:
- Added selector options in all 5 languages (de, en, nb, nl, sv)
- Updated field descriptions to include default behavior and new options
- Documented that rolling window is default when day parameter omitted

Documentation updates:
- Updated user docs (actions.md, automation-examples.md) with new options
- Added detailed explanation of day parameter options
- Included examples for both rolling_window and rolling_window_autozoom modes

Impact: Users can now create auto-adapting ApexCharts that show 48h rolling
windows with optional progressive zoom throughout the day. Requires
config-template-card for dynamic behavior.
2025-12-04 14:39:00 +00:00
Julian Pawlowski
1386407df8 fix(translations): update descriptions and names for clarity in multiple language files 2025-12-04 12:41:11 +00:00
Julian Pawlowski
c28c33dade chore(release): bump version to 0.18.1 2025-12-03 14:21:06 +00:00
Julian Pawlowski
6e0310ef7c fix(services): correct period data format for ApexCharts visualization
Period data in array_of_arrays format now generates proper segment structure
for stepline charts. Each period produces 2-3 data points depending on
insert_nulls parameter:

1. Start time with price (begin period)
2. End time with price (hold price level)
3. End time with NULL (terminate segment, only if insert_nulls='segments'/'all')

This enables ApexCharts to correctly display periods as continuous blocks with
clean gaps between them. Previously only start point was generated, causing
periods to render as single points instead of continuous segments.

Changes:
- formatters.py: Updated get_period_data() to generate 2-3 points per period
- formatters.py: Added insert_nulls parameter to control NULL termination
- get_chartdata.py: Pass insert_nulls parameter to get_period_data()
- get_apexcharts_yaml.py: Set insert_nulls='segments' for period overlay
- get_apexcharts_yaml.py: Preserve NULL values in data_generator mapping
- get_apexcharts_yaml.py: Store original price for potential tooltip access
- tests: Added comprehensive period data format tests

Impact: Best price and peak price period overlays now display correctly as
continuous blocks with proper segment separation in ApexCharts cards.
2025-12-03 14:20:46 +00:00
Julian Pawlowski
a3696fe182 ci(release): auto-delete inappropriate version tags with clear error messaging
Release workflow now automatically deletes tags when version number doesn't
match commit types (e.g., PATCH bump when MINOR needed for features).

Changes:
- New step 'Delete inappropriate version tag' runs after version_check
- Automatically deletes tag and exits with error if version inappropriate
- All subsequent steps conditional on successful version validation
- Improved warning message: removed confusing 'X.Y.Z' placeholder
- Added notice: 'This tag will be automatically deleted in the next step'
- Removed redundant 'Version Check Summary' step

Impact: Users get immediate, clear feedback when pushing wrong version tags.
Workflow fails fast with actionable error message instead of creating release
with embedded warning. No manual tag deletion needed.
2025-12-03 13:45:21 +00:00
Julian Pawlowski
a2d664e120 chore(release): bump version to 0.18.0 2025-12-03 13:36:04 +00:00
Julian Pawlowski
d7b129efec chore(release): bump version to 0.17.1 2025-12-03 13:16:06 +00:00
Julian Pawlowski
8893b31f21 fix(binary_sensor): restore push updates from coordinator
Binary sensor _handle_coordinator_update() was empty, blocking all push updates
from coordinator. This prevented binary sensors from reflecting state changes
immediately after API fetch or error conditions.

Changes:
- Implement _handle_coordinator_update() to call async_write_ha_state()
- All binary sensors now receive push updates when coordinator has new data

Binary sensors affected:
- tomorrow_data_available: Now reflects data availability immediately after API fetch
- connection: Now shows disconnected state immediately on auth/API errors
- chart_data_export: Now updates chart data when price data changes
- peak_price_period, best_price_period: Get push updates when periods change
- data_lifecycle_status: Gets push updates on status changes

Impact: Binary sensors update in real-time instead of waiting for next timer
cycle or user interaction. Fixes stale state issue where tomorrow_data_available
remained off despite data being available, and connection sensor not reflecting
authentication failures immediately.
2025-12-03 13:14:26 +00:00
Julian Pawlowski
0ac2c4970f feat(config): add energy section to configuration.yaml 2025-12-03 11:18:59 +00:00
dependabot[bot]
604c5d53cb
chore(deps): bump actions/checkout from 6.0.0 to 6.0.1 (#49)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v6...v6.0.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 21:24:01 +01:00
Julian Pawlowski
a1ab98d666 refactor(config_flow): reorganize options flow steps with section structure
Restructured 5 options flow steps (current_interval_price_rating, best_price,
peak_price, price_trend, volatility) to use Home Assistant's sections feature
for better UI organization and logical grouping.

Changes:
- current_interval_price_rating: Single section "price_rating_thresholds"
- best_price: Three sections (period_settings, flexibility_settings,
  relaxation_and_target_periods)
- peak_price: Three sections (period_settings, flexibility_settings,
  relaxation_and_target_periods)
- price_trend: Single section "price_trend_thresholds"
- volatility: Single section "volatility_thresholds"

Each section includes name, description, data fields, and data_description
fields following HA translation schema requirements.

Updated all 5 language files (de, en, nb, nl, sv) with new section structure
while preserving existing field descriptions and translations.

Impact: Options flow now displays configuration fields in collapsible,
logically grouped sections with clear section headers, improving UX for
complex multi-parameter configuration steps. No functional changes to
configuration logic or validation.
2025-12-02 20:23:31 +00:00
Julian Pawlowski
3098144db2 chore(release): bump version to 0.17.0 2025-12-02 19:00:54 +00:00
Julian Pawlowski
3977d5e329 fix(coordinator): add _is_fetching flag and fix tomorrow data detection
Implement _is_fetching flag to show "refreshing" status during API calls,
and fix needs_tomorrow_data() to recognize single-home cache format.

Changes:
- Set _is_fetching flag before API call, reset after completion (core.py)
- Fix needs_tomorrow_data() to check for "price_info" key instead of "homes"
- Remove redundant "homes" check in should_update_price_data()
- Improve logging: change debug to info for tomorrow data checks

Lifecycle status now correctly transitions after 13:00 when tomorrow data
is missing: cached → searching_tomorrow → refreshing → fresh → cached

Impact: Users will see accurate lifecycle status and tomorrow's electricity
prices will automatically load when available after 13:00, fixing issue
since v0.14.0 where prices weren't fetched without manual HA restart.
2025-12-02 19:00:20 +00:00
Julian Pawlowski
d6ae931918 feat(services): add new services and icons for enhanced functionality and user experience 2025-12-02 18:46:15 +00:00
Julian Pawlowski
ab9735928a refactor(docs): update terminology from "services" to "actions" for clarity and consistency 2025-12-02 18:35:59 +00:00
Julian Pawlowski
97db134ed5 feat(services): add icons to service definitions for better visibility 2025-12-02 17:16:44 +00:00
Julian Pawlowski
d2252cac45 Merge branch 'main' of https://github.com/jpawlowski/hass.tibber_prices 2025-12-02 17:13:59 +00:00
Julian Pawlowski
7978498006 chore(release): sync manifest.json with tag and recreate release if necessary 2025-12-02 17:13:56 +00:00
github-actions[bot]
ae6f0780fd chore(release): sync manifest.json with tag v0.16.1 2025-12-02 16:49:44 +00:00
Julian Pawlowski
b78ddeaf43 feat(docs): update get_apexcharts_yaml service descriptions to clarify limitations and customization options 2025-12-02 16:47:36 +00:00
Julian Pawlowski
0a44dd7f12 chore(release): bump version to 0.16.0 2025-12-01 23:48:36 +00:00
Julian Pawlowski
369f07ee39 docs(AGENTS): update Conventional Commits guidelines and best practices 2025-12-01 23:48:30 +00:00
Julian Pawlowski
e156dfb061 feat(services): add rolling 48h window support to chart services
Add dynamic rolling window mode to get_chartdata and get_apexcharts_yaml
services that automatically adapts to data availability.

When 'day' parameter is omitted, services return 48-hour window:
- With tomorrow data (after ~13:00): today + tomorrow
- Without tomorrow data: yesterday + today

Changes:
- Implement rolling window logic in get_chartdata using has_tomorrow_data()
- Generate config-template-card wrapper in get_apexcharts_yaml for dynamic
  ApexCharts span.offset based on tomorrow_data_available binary sensor
- Update service descriptions in services.yaml
- Add rolling window descriptions to all translations (de, en, nb, nl, sv)
- Document rolling window mode in docs/user/services.md
- Add ApexCharts examples with prerequisites in docs/user/automation-examples.md

BREAKING CHANGE: get_apexcharts_yaml rolling window mode requires
config-template-card in addition to apexcharts-card for dynamic offset
calculation.

Impact: Users can create auto-adapting 48h price charts without manual day
selection. Fixed day views (day: today/yesterday/tomorrow) still work with
apexcharts-card only.
2025-12-01 23:46:09 +00:00
Julian Pawlowski
cf8d9ba8e8 feat(apexcharts): add highlight option for best price periods in chart 2025-12-01 21:51:39 +00:00
Julian Pawlowski
f70ac9cff6 feat(services): improve ApexCharts segment visualization and fix header display
Simplifies the connect_segments implementation to use a unified bridge-point
approach for all price transitions (up/down/same). Previously used
direction-dependent logic (hold vs connect points) which was unnecessarily
complex.

Changes:
- get_chartdata.py: Bridge points now always use next interval's price at
  boundary timestamp, creating smooth visual connection between segments
- get_chartdata.py: Trailing NULL removal now conditional on insert_nulls mode
  ('segments' removes for header fix, 'all' preserves intentional gaps)
- get_apexcharts_yaml.py: Enable connect_segments by default, activate
  show_states for header min/max display
- get_apexcharts_yaml.py: Remove extrema series (not compatible with
  data_generator approach - ApexCharts requires entity time-series data)
- tests: Move test_connect_segments.py to tests/services/ to mirror source
  structure

Impact: ApexCharts cards now show clean visual connections between price level
segments with proper header statistics display. Trailing NULLs no longer cause
"N/A" in headers for filtered data. Test organization improved for
maintainability.
2025-12-01 11:14:27 +00:00
Copilot
49628f3394
Add connect_segments parameter and fix ApexCharts header N/A display (#46)
* Initial plan

* Add connect_segments parameter to get_chartdata service for visual segment connections

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Address code review feedback: fix test logic and correct misleading comment

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Integrate PR45: Remove trailing null values for proper ApexCharts header display

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Add connect_segments translations for de, nb, nl, sv languages

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Changes before error encountered

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Fix hassfest validation: Move time_units from translations to custom_translations

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>
2025-12-01 03:19:52 +01:00
Julian Pawlowski
b306a491e0 refactor(translations): unify time unit translations across multiple languages 2025-11-30 17:25:58 +00:00
Julian Pawlowski
fe2cb1180a refactor(generate-notes): enhance output formatting for error messages and logs 2025-11-30 16:55:31 +00:00
Julian Pawlowski
2320520ed9 chore(release): bump version to 0.15.0 2025-11-30 16:43:21 +00:00
Julian Pawlowski
412cecc126 refactor(cache): enhance cache validation to support new structure and invalidate old format 2025-11-30 16:42:41 +00:00
Julian Pawlowski
6f93bb8288 refactor(formatters, get_chartdata): serialize datetime objects to ISO format in data points 2025-11-30 15:07:18 +00:00
Julian Pawlowski
09eb9c7050 refactor(validate): remove 'ignore' key from HACS validation step 2025-11-28 16:39:00 +00:00
Julian Pawlowski
b9647659bd chore(devcontainer): update Node.js version to 24 in devcontainer configuration 2025-11-26 14:36:30 +00:00
Julian Pawlowski
7c0000039e refactor(config_flow): disable subentry flow temporarily due to incomplete time-travel feature 2025-11-26 14:36:08 +00:00
Julian Pawlowski
50021ce3ba chore(devcontainer): add setup-git.sh script for host Git configuration 2025-11-26 14:36:00 +00:00
Julian Pawlowski
a90fef6f2d refactor(scripts): reorganize and standardize development scripts
Major restructuring of the scripts/ directory with consistent output
formatting, improved organization, and stricter error handling.

Breaking Changes:
- Updated development environment to Home Assistant 2025.7+
  - Removed Python 3.12 compatibility (HA 2025.7+ requires Python 3.13)
  - Updated all HA core requirements from 2025.7 requirement files
  - Added new dependencies: python-multipart, uv (for faster package management)
  - Updated GitHub Actions workflows to use Python 3.13

Changes:
- Created centralized output library (scripts/.lib/output.sh)
  - Unified color codes and Unicode symbols
  - Consistent formatting functions (log_header, log_success, log_error, etc.)
  - Support for embedded formatting codes (${BOLD}, ${GREEN}, etc.)

- Reorganized into logical subdirectories:
  - scripts/setup/ - Setup and maintenance scripts
    - bootstrap: Install/update dependencies (used in CI/CD)
    - setup: Full DevContainer setup (pyright, copilot, HACS)
    - reset: Reset config/ directory to fresh state (NEW)
    - sync-hacs: Sync HACS integrations
  - scripts/release/ - Release management scripts
    - prepare: Version bump and tagging
    - suggest-version: Semantic version suggestion
    - generate-notes: Release notes generation
    - check-if-released: Check release status
    - hassfest: Local integration validation

- Updated all scripts with:
  - set -euo pipefail for stricter error handling
  - Consistent SCRIPT_DIR pattern for reliable sourcing
  - Professional output with colors and emojis
  - Unified styling across all 17 scripts

- Removed redundant scripts:
  - scripts/update (was just wrapper around bootstrap)
  - scripts/json_schemas/ (moved to schemas/json/)

- Enhanced clean script:
  - Improved artifact cleanup
  - Better handling of accidental package installations
  - Hints for reset and deep clean options

- New reset script features:
  - Standard mode: Keep configuration.yaml
  - Full mode (--full): Reset configuration.yaml from git
  - Automatic re-setup after reset

- Updated documentation:
  - AGENTS.md: Updated script references and workflow guidance
  - docs/development/: Updated all references to new script structure

Impact: Development environment now requires Python 3.13 and Home Assistant
2025.7+. Developers get consistent, professional script output with better
error handling and logical organization. Single source of truth for styling
makes future updates trivial.
2025-11-26 13:11:52 +00:00
Julian Pawlowski
1a396a4faf docs(agents): update class naming documentation
Updated AGENTS.md:
- Fixed TibberPricesFlowHandler → TibberPricesConfigFlowHandler reference

Impact: Documentation now matches current code structure.
2025-11-25 20:44:40 +00:00
Julian Pawlowski
cca104dfc4 chore(dev): update dev environment configuration
DevContainer updates:
- .devcontainer/devcontainer.json: Added Python path configuration

Configuration updates:
- config/configuration.yaml: Added test home configuration

Impact: Improved development environment setup. No production changes.
2025-11-25 20:44:40 +00:00
Julian Pawlowski
3c69807c05 refactor(logging): use details logger for verbose period calculation logs
Moved verbose debug logging to separate _LOGGER_DETAILS logger:
- core.py: Outlier flex capping messages
- outlier_filtering.py: Spike detection, context validation, smoothing details
- period_building.py: Level filter details, gap tolerance info
- relaxation.py: Per-phase iteration details, filter combination attempts

Pattern: Main _LOGGER for high-level progress, _LOGGER_DETAILS for step-by-step

Benefits:
- Users can disable verbose logs via logger configuration
- Main DEBUG log stays readable (high-level flow)
- Details available when needed for troubleshooting

Added:
- period_overlap.py: Docstring for extend_period_if_adjacent()

Impact: Cleaner log output by default. Enable details logger
(homeassistant.components.tibber_prices.coordinator.period_handlers.details)
for deep debugging.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
9ae618fff9 refactor(config_flow): rename TibberPricesFlowHandler to TibberPricesConfigFlowHandler
Renamed main config flow handler class for clarity:
- TibberPricesFlowHandler → TibberPricesConfigFlowHandler

Updated imports in:
- config_flow.py (import alias)
- config_flow_handlers/__init__.py (exports)

Reason: More explicit name distinguishes from OptionsFlowHandler and
SubentryFlowHandler. Follows naming convention of other flow handlers.

Impact: No functional changes, improved code readability.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
6338f51527 refactor(services): rename service modules to match service names
Renamed service modules for consistency with service identifiers:
- apexcharts.py → get_apexcharts_yaml.py
- chartdata.py → get_chartdata.py
- Added: get_price.py (new service module)

Naming convention: Module names now match service names directly
(tibber_prices.get_apexcharts_yaml → get_apexcharts_yaml.py)

Impact: Improved code organization, easier to locate service implementations.
No functional changes.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
7c117a2267 docs(schemas): update JSON schemas for translation structure
Updated translation JSON schemas to reflect current implementation:
- translation_schema.json: Documents HA's official translation structure
  (config, options, selector paths, entity states)
- custom_translation_schema.json: Documents custom extension structure
  (entity descriptions not supported by HA schema)

Schema updates:
- Added time_units section (day, days, hour, hours, minute, minutes, ago, now)
- Documented selector.{translation_key}.options.{value} pattern
- Added account_choice selector structure

Impact: Provides validation and documentation for translation files.
Helps maintain consistency across all 5 language files (de, en, nb, nl, sv).
2025-11-25 20:44:39 +00:00
Julian Pawlowski
b6f5f1678f feat(services): add fetch_price_info_range service and update schema
Added new service for fetching historical/future price data:
- fetch_price_info_range: Query prices for arbitrary date ranges
- Supports start_time and end_time parameters
- Returns structured price data via service response
- Uses interval pool for efficient data retrieval

Service definition:
- services.yaml: Added fetch_price_info_range with date selectors
- services/__init__.py: Implemented handler with validation
- Response format: {"priceInfo": [...], "currency": "..."}

Schema updates:
- config_flow_handlers/schemas.py: Convert days slider to IntSelector
  (was NumberSelector with float, caused "2.0 Tage" display issue)

Impact: Users can fetch price data for custom date ranges programmatically.
Config flow displays clean integer values for day offsets.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
44f6ae2c5e feat(interval-pool): add intelligent interval caching and memory optimization
Implemented interval pool architecture for efficient price data management:

Core Components:
- IntervalPool: Central storage with timestamp-based index
- FetchGroupCache: Protected range management (day-before-yesterday to tomorrow)
- IntervalFetcher: Gap detection and optimized API queries
- TimestampIndex: O(1) lookup for price intervals

Key Features:
- Deduplication: Touch intervals instead of duplicating (memory efficient)
- GC cleanup: Removes dead intervals no longer referenced by index
- Gap detection: Only fetches missing ranges, reuses cached data
- Protected range: Keeps yesterday/today/tomorrow, purges older data
- Resolution support: Handles hourly (pre-Oct 2025) and quarter-hourly data

Integration:
- TibberPricesApiClient: Uses interval pool for all range queries
- DataUpdateCoordinator: Retrieves data from pool instead of direct API
- Transparent: No changes required in sensor/service layers

Performance Benefits:
- Reduces API calls by 70% (reuses overlapping intervals)
- Memory footprint: ~10KB per home (protects 384 intervals max)
- Lookup time: O(1) timestamp-based index

Breaking Changes: None (backward compatible integration layer)

Impact: Significantly reduces Tibber API load while maintaining data
freshness. Memory-efficient storage prevents unbounded growth.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
74789877ff test: fix async mocking and add noqa comments for private access
Fixed test issues:
- test_resource_cleanup.py: Use AsyncMock for async_unload_entry
  (was MagicMock, caused TypeError with async context)
- Added # noqa: SLF001 comments to all private member access in tests
  (18 instances - legitimate test access patterns)

Test files updated:
- test_resource_cleanup.py (AsyncMock fix)
- test_interval_pool_memory_leak.py (8 noqa comments)
- test_interval_pool_optimization.py (4 noqa comments)

Impact: All tests pass linting, async tests execute correctly.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
e04e38d09f refactor(logging): remove verbose debug logging from price enrichment
Removed excessive debug logging in enrich_price_info_with_differences():
- Deleted per-interval "Processing" messages (cluttered logs)
- Kept boundary INFO messages (enrichment start/skip counts)
- Removed unused variable expected_intervals_24h
- Removed unused parameter day_label from _process_price_interval()

Impact: Cleaner logs, no functional changes. Reduces log volume during
price data processing.
2025-11-25 20:44:39 +00:00
Julian Pawlowski
2449c28a88 feat(i18n): localize time offset descriptions and config flow strings
Added complete localization support for time offset descriptions:
- Convert hardcoded English strings "(X days ago)" to translatable keys
- Add time_units translations (day/days, hour/hours, minute/minutes, ago, now)
- Support singular/plural forms in all 5 languages (de, en, nb, nl, sv)
- German: Proper Dativ case "Tagen" with preposition "vor"
- Compact format for mixed offsets: "7 Tagen - 02:30"

Config flow improvements:
- Replace hardcoded "Enter new API token" with translated "Add new Tibber account API token"
- Use get_translation() for account_choice dropdown labels
- Fix SelectOptionDict usage (no mixing with translation_key parameter)
- Convert days slider from float to int (prevents "2.0 Tage" display)
- DurationSelector: default {"hours": 0, "minutes": 0} to fix validation errors

Translation keys added:
- selector.account_choice.options.new_token
- time_units (day, days, hour, hours, minute, minutes, ago, now)
- config.step.time_offset_description guidance text

Impact: Config flow works fully translated in all 5 languages with proper grammar.
2025-11-25 20:44:39 +00:00