versioned_docs/ was already tracked but versioned_sidebars/ was never
committed. Docusaurus requires both to render sidebar navigation for
old versions — without the sidebar files, all versioned pages show
no navigation.
Adds sidebar snapshots for user and developer docs:
v0.21.0, v0.22.0, v0.22.1, v0.23.0, v0.23.1, v0.24.0, v0.27.0, v0.28.0
Future versions: CI (docusaurus.yml) runs docs:version on each stable
tag push, which generates both versioned_docs/ and versioned_sidebars/.
The workflow should be updated to commit these files back, or they need
to be added manually after each release.
Impact: Sidebar navigation now appears correctly for all existing
versioned documentation pages.
Swizzled @docusaurus/theme-mermaid's Mermaid component to wrap
every diagram with a portal-based lightbox overlay.
An expand icon appears on diagram hover. Clicking opens the SVG
in a full-screen overlay (90vw × 85vh, scrollable). Closes via
backdrop click, Escape key, or close button. SSR-safe, no
external dependencies. Matches Tibber electric color theme.
Impact: Users can inspect complex flowcharts (e.g. the Options
Flow wizard) without squinting at small embedded diagrams.
Switched Giscus mapping from 'pathname' to 'og:title' with strict=1.
Discussions are now titled after the readable page title (e.g.
'Chart Examples | Tibber Prices Integration') instead of the URL path,
making them immediately identifiable in the GitHub Discussions list.
Added a small hint above every comment box pointing users to open
a dedicated Discussion on GitHub for new questions/ideas, so
page-specific comments don't accumulate unrelated threads.
Note: Existing Discussion #94 (pathname-mapped) will no longer appear
on chart-examples — a new og:title-mapped discussion will be created
on the next comment. #94 remains visible on GitHub.
Impact: Maintainer can identify discussion origin at a glance.
Users are guided toward proper Discussion threads for new topics.
Added a dedicated 'Finding Your Entry ID' section to actions.md
explaining the two workflows: dropdown in the Action UI vs.
'Copy Config Entry ID' from the integration's three-dot menu in YAML.
Added matching :::info callouts to chart-examples.md and
automation-examples.md where entry_id: YOUR_ENTRY_ID appears in code
examples, and a new 'Config Entry ID' entry in the glossary.
Addresses user confusion reported in GitHub Discussions #94.
Impact: Users no longer get stuck on YOUR_ENTRY_ID placeholders.
Both GUI and YAML workflows are clearly explained at the point of need.
Add coverage for the state_class/statistics table optimization across
both user and developer documentation.
docs/user/docs/configuration.md:
- Add 'Price Sensor Statistics' section explaining that only 3 sensors
write to the HA statistics database (current_interval_price,
current_interval_price_base, average_price_today)
- Fix incorrect entity ID examples: remove non-existent _override suffix
from recorder exclude globs, Developer Tools example, and seasonal
automation example (actual IDs: number.*_best_price_flexibility etc.)
docs/developer/docs/recorder-optimization.md:
- Add 'Long-Term Statistics Optimization (state_class)' section covering
the statistics/statistics_short_term table dimension, which is distinct
from _unrecorded_attributes (state_attributes table)
- Documents the MONETARY device_class constraint (MEASUREMENT blocked by
hassfest, only TOTAL or None valid), the 3 sensors keeping TOTAL with
rationale, the 23 sensors set to None, and ~88% write reduction
- Includes comparison table: _unrecorded_attributes vs state_class
Impact: Users now understand the built-in statistics optimization and
have correct recorder exclude examples. Developers understand both
optimization layers and their interaction.
User docs (period-calculation.md):
- New troubleshooting section "Fewer Periods Than Configured" (most
common confusing scenario, added before "No Periods Found")
- Extended "Understanding Sensor Attributes" section: all four diagnostic
attributes documented with concrete YAML examples and prose explanations
- Updated Table of Contents
Developer docs (period-calculation-theory.md):
- New section "Flat Day and Low-Price Adaptations" (between Flex Limits
and Relaxation Strategy) documenting all three mechanisms with
implementation details, scaling tables, and rationale for hardcoding
- Two new scenarios: 2b (flat day with adaptive min_periods) and 2c
(solar surplus / absolute low-price day) with expected logs and
sensor attribute examples
- Debugging checklist point 6: flat day / low-price checks with
exact log string patterns to grep for
- Diagnostic attribute reference table in the debugging section
Impact: Users can self-diagnose "fewer periods than configured" without
support. Contributors understand why the three thresholds are hardcoded
and cannot be user-configured.
When runtime config override entities (number/switch) are enabled,
the Options Flow now displays warning indicators at the top of each
affected section. Users see which fields are being managed by config
entities and can still edit the base values if needed.
Changes:
- Add ConstantSelector warnings in Best Price/Peak Price sections
- Implement multi-language support for override warnings (de, en, nb, nl, sv)
- Add _get_override_translations() to load translated field labels
- Add _get_active_overrides() to detect enabled override entities
- Extend get_best_price_schema/get_peak_price_schema with translations param
- Add 14 number/switch config entities for runtime period tuning
- Document runtime configuration entities in user docs
Warning format adapts to overridden fields:
- Single: "⚠️ Flexibility controlled by config entity"
- Multiple: "⚠️ Flexibility and Minimum Distance controlled by config entity"
Impact: Users can now dynamically adjust period calculation parameters
via Home Assistant automations, scripts, or dashboards without entering
the Options Flow. Clear UI indicators show which settings are currently
overridden.
Added a consistent "Entity ID tip" block and normalized all example
entity IDs to the `<home_name>` placeholder across user docs. Updated
YAML and example references to current entity naming (e.g.,
`sensor.<home_name>_current_electricity_price`,
`sensor.<home_name>_price_today`,
`sensor.<home_name>_today_s_price_volatility`,
`binary_sensor.<home_name>_best_price_period`, etc.). Refreshed
automation examples to use language-independent attributes (e.g.
`price_volatility`) and improved robustness. Aligned ApexCharts examples
to use `sensor.<home_name>_chart_metadata` and corrected references for
tomorrow data availability.
Changed files:
- docs/user/docs/actions.md
- docs/user/docs/automation-examples.md
- docs/user/docs/chart-examples.md
- docs/user/docs/configuration.md
- docs/user/docs/dashboard-examples.md
- docs/user/docs/dynamic-icons.md
- docs/user/docs/faq.md
- docs/user/docs/icon-colors.md
- docs/user/docs/period-calculation.md
- docs/user/docs/sensors.md
Impact: Clearer, language-independent examples that reduce confusion and
prevent brittle automations; easier copy/paste adaptation across setups;
more accurate guidance for chart configuration and period/volatility usage.
Expanded user documentation with detailed guidance on average sensors:
1. sensors.md (+182 lines):
- New 'Average Price Sensors' section with mean vs median explanation
- 3 real-world automation examples (heat pump, dishwasher, EV charging)
- Display configuration guide with use-case recommendations
2. configuration.md (+75 lines):
- New 'Average Sensor Display Settings' section
- Comparison table of display modes (mean/median/both)
- Attribute availability details and recorder implications
3. Minor updates to installation.md and versioned docs
Impact: Users can now understand when to use mean vs median and how to
configure display format for their specific automation needs.
Add user-configurable option to choose between median and arithmetic mean
as the displayed value for all 14 average price sensors, with the alternate
value exposed as attribute.
BREAKING CHANGE: Average sensor default changed from arithmetic mean to
median. Users who rely on arithmetic mean behavior may use the price_mean attribue now, or must manually reconfigure
via Settings → Devices & Services → Tibber Prices → Configure → General
Settings → "Average Sensor Display" → Select "Arithmetic Mean" to get this as sensor state.
Affected sensors (14 total):
- Daily averages: average_price_today, average_price_tomorrow
- 24h windows: trailing_price_average, leading_price_average
- Rolling hour: current_hour_average_price, next_hour_average_price
- Future forecasts: next_avg_3h, next_avg_6h, next_avg_9h, next_avg_12h
Implementation:
- All average calculators now return (mean, median) tuples
- User preference controls which value appears in sensor state
- Alternate value automatically added to attributes
- Period statistics (best_price/peak_price) extended with both values
Technical changes:
- New config option: CONF_AVERAGE_SENSOR_DISPLAY (default: "median")
- Calculator functions return tuples: (avg, median)
- Attribute builders: add_alternate_average_attribute() helper function
- Period statistics: price_avg → price_mean + price_median
- Translations: Updated all 5 languages (de, en, nb, nl, sv)
- Documentation: AGENTS.md, period-calculation.md, recorder-optimization.md
Migration path:
Users can switch back to arithmetic mean via:
Settings → Integrations → Tibber Prices → Configure
→ General Settings → "Average Sensor Display" → "Arithmetic Mean"
Impact: Median is more resistant to price spikes, providing more stable
automation triggers. Statistical analysis from coordinator still uses
arithmetic mean (e.g., trailing_avg_24h for rating calculations).
Co-developed-with: GitHub Copilot <copilot@github.com>
Change relative path ../development/ to absolute path /hass.tibber_prices/developer/
since user and developer docs are now separate Docusaurus instances.
Fixes broken link warning during build.
- Created a new documentation file `chart-examples.md` detailing various chart configurations available through the `tibber_prices.get_apexcharts_yaml` action.
- Included descriptions, dependencies, and YAML generation examples for four chart modes: Today's Prices, Rolling 48h Window, and Rolling Window Auto-Zoom.
- Added a section on dynamic Y-axis scaling and best price period highlights.
- Established prerequisites for using the charts, including required cards and customization tips.
- Introduced a new `README.md` in the images/charts directory to document available chart screenshots and guidelines for capturing them.
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.
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.
Periods can now naturally cross midnight boundaries, and new diagnostic
attributes help users understand price classification changes at midnight.
**New Features:**
1. Midnight-Crossing Period Support (relaxation.py):
- group_periods_by_day() assigns periods to ALL spanned days
- Periods crossing midnight appear in both yesterday and today
- Enables period formation across calendar day boundaries
- Ensures min_periods checking works correctly at midnight
2. Extended Price Data Window (relaxation.py):
- Period calculation now uses full 3-day data (yesterday+today+tomorrow)
- Enables natural period formation without artificial midnight cutoff
- Removed date filter that excluded yesterday's prices
3. Day Volatility Diagnostic Attributes (period_statistics.py, core.py):
- day_volatility_%: Daily price spread as percentage (span/avg × 100)
- day_price_min/max/span: Daily price range in minor currency (ct/øre)
- Helps detect when midnight classification changes are economically significant
- Uses period start day's reference prices for consistency
**Documentation:**
4. Design Principles (period-calculation-theory.md):
- Clarified per-day evaluation principle (always was the design)
- Added comprehensive section on midnight boundary handling
- Documented volatility threshold separation (sensor vs period filters)
- Explained market context for midnight price jumps (EPEX SPOT timing)
5. User Guides (period-calculation.md, automation-examples.md):
- Added \"Midnight Price Classification Changes\" troubleshooting section
- Provided automation examples using volatility attributes
- Explained why Best→Peak classification can change at midnight
- Documented level filter volatility threshold behavior
**Architecture:**
- Per-day evaluation: Each interval evaluated against its OWN day's min/max/avg
(not period start day) ensures mathematical correctness across midnight
- Period boundaries: Periods can naturally cross midnight but may split when
consecutive days differ significantly (intentional, mathematically correct)
- Volatility thresholds: Sensor thresholds (user-configurable) remain separate
from period filter thresholds (fixed internal) to prevent unexpected behavior
Impact: Periods crossing midnight are now consistently visible before and
after midnight turnover. Users can understand and handle edge cases where
price classification changes at midnight on low-volatility days.
BREAKING CHANGE: Period overlap resolution now merges adjacent/overlapping periods
instead of marking them as extensions. This simplifies automation logic and provides
clearer period boundaries for users.
Previous Behavior:
- Adjacent periods created by relaxation were marked with is_extension=true
- Multiple short periods instead of one continuous period
- Complex logic needed to determine actual period length in automations
New Behavior:
- Adjacent/overlapping periods are merged into single continuous periods
- Newer period's relaxation attributes override older period's
- Simpler automation: one period = one continuous time window
Changes:
- Period Overlap Resolution (new file: period_overlap.py):
* Added merge_adjacent_periods() to combine periods and preserve attributes
* Rewrote resolve_period_overlaps() with simplified merge logic
* Removed split_period_by_overlaps() (no longer needed)
* Removed is_extension marking logic
* Removed unused parameters: min_period_length, baseline_periods
- Relaxation Strategy (relaxation.py):
* Removed all is_extension filtering from period counting
* Simplified standalone counting to just len(periods)
* Changed from period_merging import to period_overlap import
* Added MAX_FLEX_HARD_LIMIT constant (0.50)
* Improved debug logging for merged periods
- Code Quality:
* Fixed all remaining linter errors (N806, PLR2004, PLR0912)
* Extracted magic values to module-level constants:
- FLEX_SCALING_THRESHOLD = 0.20
- SCALE_FACTOR_WARNING_THRESHOLD = 0.8
- MAX_FLEX_HARD_LIMIT = 0.50
* Added appropriate noqa comments for unavoidable patterns
- Configuration (from previous work in this session):
* Removed CONF_RELAXATION_STEP_BEST, CONF_RELAXATION_STEP_PEAK
* Hard-coded 3% relaxation increment for reliability
* Optimized defaults: RELAXATION_ATTEMPTS 8→11, ENABLE_MIN_PERIODS False→True,
MIN_PERIODS undefined→2
* Removed relaxation_step UI fields from config flow
* Updated all 5 translation files
- Documentation:
* Updated period_handlers/__init__.py: period_merging → period_overlap
* No user-facing docs changes needed (already described continuous periods)
Rationale - Period Merging:
User experience was complicated by fragmented periods:
- Automations had to check multiple adjacent periods
- Binary sensors showed ON/OFF transitions within same cheap time
- No clear way to determine actual continuous period length
With merging:
- One continuous cheap time = one period
- Binary sensor clearly ON during entire period
- Attributes show merge history via merged_from dict
- Relaxation info preserved from newest/highest flex period
Rationale - Hard-Coded Relaxation Increment:
The configurable relaxation_step parameter proved problematic:
- High base flex + high step → rapid explosion (40% base + 10% step → 100% in 6 steps)
- Users don't understand the multiplicative nature
- 3% increment provides optimal balance: 11 attempts to reach 50% hard cap
Impact:
- Existing installations: Periods may appear longer (merged instead of split)
- Automations benefit from simpler logic (no is_extension checks needed)
- Custom relaxation_step values will use new 3% increment
- Users may need to adjust relaxation_attempts if they relied on high step sizes