Commit graph

715 commits

Author SHA1 Message Date
Julian Pawlowski
779e22a84e fix(periods): replace redundant total attributes with per-day counts
Some checks are pending
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
Removed periods_found_total and replaced with period_count_today /
period_count_tomorrow. The old attribute counted all periods including
yesterday (coordinator scope), causing a discrepancy vs. the displayed
list (sensor scope, today+tomorrow only).

Renamed periods_total → period_count_total for naming consistency with
the new per-day attributes. Recalculate period_position / period_count_total /
periods_remaining after the today+tomorrow filter so all three navigation
attributes reflect the filtered scope.

period_count_tomorrow is always present (0 when no tomorrow data or no
periods found), enabling automations without default(0) guards.

Removed internal periods_found key from relaxation metadata — it was
only consumed by add_calculation_summary_attributes which is now removed.

BREAKING CHANGE: periods_found_total removed (replace with
period_count_today + period_count_tomorrow). periods_total renamed to
period_count_total.

Impact: Period navigation attributes (position/total/remaining) now
correctly reflect today+tomorrow scope. Per-day counts allow automations
to distinguish "2 periods today, 0 tomorrow" from "1+1".
2026-04-12 09:50:31 +00:00
Julian Pawlowski
9e1ba10f0b refactor(options_flow): optimize loading of override translations based on active overrides 2026-04-12 08:54:41 +00:00
Julian Pawlowski
a8d5230531 feat(periods): implement geometric_extension_attempted flag and time_range filtering
Phase 3: When geometric bonus intervals cause CV gate failure, strip them
from period edges (unextended boundaries) and set geometric_extension_attempted=True
on the summary. Previously only geometric_extension_active was tracked.
Moved LOW_PRICE_QUALITY_BYPASS_THRESHOLD constant to types.py for shared access.

Phase 4: Add time_range: tuple[datetime, datetime] | None parameter to
build_periods(), calculate_periods(), and calculate_periods_with_relaxation().
Filters candidate intervals to [start, end) without affecting day-wide reference
prices. Refactored _apply_segment_forcing() to use time_range instead of the
restricted_prices list approach.

Impact: Period statistics now accurately reflect when geometric flex extension
was attempted but reverted due to quality gate failure. Segment forcing uses
a cleaner API that preserves full price context for reference calculations.
2026-04-12 08:24:38 +00:00
Julian Pawlowski
796eb4b422 feat(periods): implement geometric_extension_attempted flag and time_range filtering
Phase 3: When geometric bonus intervals cause CV gate failure, strip them
from period edges (unextended boundaries) and set geometric_extension_attempted=True
on the summary. Previously only geometric_extension_active was tracked.
Moved LOW_PRICE_QUALITY_BYPASS_THRESHOLD constant to types.py for shared access.

Phase 4: Add time_range: tuple[datetime, datetime] | None parameter to
build_periods(), calculate_periods(), and calculate_periods_with_relaxation().
Filters candidate intervals to [start, end) without affecting day-wide reference
prices. Refactored _apply_segment_forcing() to use time_range instead of the
restricted_prices list approach.

Impact: Period statistics now accurately reflect when geometric flex extension
was attempted but reverted due to quality gate failure. Segment forcing uses
a cleaner API that preserves full price context for reference calculations.
2026-04-12 08:24:25 +00:00
Julian Pawlowski
4ddd19b132 feat(periods): geometric V-shape flex extension for period detection
Some checks are pending
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
Uses valley/peak knee points from day pattern analysis to grant extra
flex to price intervals that fall inside detected geometric zones,
making period detection more permissive within V-shape (best price)
or Λ-shape (peak price) price formations.

New options:
- CONF_BEST_PRICE_GEOMETRIC_FLEX (0-25%, default 0 = disabled)
- CONF_PEAK_PRICE_GEOMETRIC_FLEX (0-25%, default 0 = disabled)

Implementation:
- compute_geometric_flex_bonus() in level_filtering.py checks if
  interval falls inside valley/peak zone and returns extra_flex
- period_building.py applies geo bonus per-interval via
  criteria._replace(flex=...) and sets geometric_bonus_applied flag
- period_statistics.py reports geometric_extension_active and
  geometric_extension_intervals in period summaries
- Day patterns threaded through full pipeline:
  data_transformation → coordinator/core → periods →
  relaxation → calculate_periods → price_context
- UI sliders in both extension_settings sections
- Translations: en, de, nb, nl, sv

Impact: Users with clearly V-shaped or Λ-shaped daily price curves
can enable geometric flex to improve period detection accuracy within
those characteristic shapes without increasing global flex.
2026-04-11 21:49:24 +00:00
Julian Pawlowski
e44f639b41 feat(editorconfig,devcontainer): configure JSON formatting settings for consistency 2026-04-11 21:49:04 +00:00
Julian Pawlowski
b7f1efce1f feat(best_price,peak_price): add optional extension to VERY_CHEAP/VERY_EXPENSIVE intervals
After period detection, optionally walk left/right from each period boundary
to absorb adjacent VERY_CHEAP (best price) or VERY_EXPENSIVE (peak price)
intervals (step 7.5 in the pipeline).

New constants: CONF_BEST_PRICE_EXTEND_TO_VERY_CHEAP, CONF_BEST_PRICE_MAX_EXTENSION_INTERVALS,
CONF_PEAK_PRICE_EXTEND_TO_VERY_EXPENSIVE, CONF_PEAK_PRICE_MAX_EXTENSION_INTERVALS.
Defaults: off / 4 intervals (1 hour per side). Hard maximum: 12 intervals (3 hours).

Config stored under "extension_settings" section, reflected in period hash
for correct cache invalidation.

New module: coordinator/period_handlers/shape_extension.py handles the
boundary walk, stat recalculation, and extension_intervals_added bookkeeping.

Impact: Users can opt-in to wider best/peak price windows that include
extreme-level adjacent intervals, reducing missed very cheap/expensive slots
at period edges.
2026-04-11 21:24:44 +00:00
Julian Pawlowski
447dc907e6 feat(sensors): add day pattern detection sensors (valley/peak/flat/rising/falling)
Introduces a new day_pattern.py module that analyses the 15-min price curve
for each calendar day (yesterday/today/tomorrow) and classifies its shape.

New sensors:
  day_pattern_yesterday / day_pattern_today / day_pattern_tomorrow
  EntityCategory.DIAGNOSTIC, SensorDeviceClass.ENUM

Patterns: valley, peak, double_valley, double_peak, flat, rising, falling, mixed

The detector uses centred-rolling smoothing, prominence-filtered extrema,
Kneedle-based knee detection, and monotone segment building.
Coordinator populates transformed_data["dayPatterns"] after priceInfo enrichment.

Impact: Users can trigger automations based on the shape of the day's price
curve, e.g. pre-heat when tomorrow is a valley day.
2026-04-11 21:07:16 +00:00
Julian Pawlowski
999ecd358f docs(user): collapse code blocks and normalize labels
Wrap most user-guide code examples in collapsible details sections to reduce visual noise while keeping Mermaid diagrams expanded.

Standardized summary labels across the user docs to a small set of readable patterns and removed technical or awkward wording from visible collapse titles.

Impact: User documentation is easier to scan, with long examples hidden by default and more consistent expand/collapse labels.
2026-04-11 19:51:58 +00:00
Julian Pawlowski
f6a49d9cf3 Merge branch 'main' of https://github.com/jpawlowski/hass.tibber_prices
# Conflicts:
#	docs/user/docs/actions.md
#	docs/user/docs/automation-examples.md
#	docs/user/sidebars.ts
2026-04-11 19:31:57 +00:00
Julian Pawlowski
4cc150df6f docs(actions): restructure into dedicated Actions category
Split monolithic actions.md into focused sub-pages:
- actions.md: lightweight overview with links
- scheduling-actions.md: renamed from scheduling-services.md
- chart-actions.md: get_chartdata + get_apexcharts_yaml
- data-actions.md: get_price + refresh_user_data

New  Actions sidebar category. Reference keeps only sensor-reference.
Updated cross-references in 6 files.

Impact: Clearer navigation — users find actions by purpose instead of
scrolling a long page. Consistent "actions" terminology (HA standard).
2026-04-11 19:25:17 +00:00
Julian Pawlowski
83ec3910bd docs(services): add scheduling services user documentation
New comprehensive documentation page for all 5 scheduling services:
- Decision flowchart for choosing the right service
- Detailed parameter reference with examples for each service
- Response format examples with realistic data
- Practical automation examples (overnight scheduling, EV charging,
  peak price avoidance)
- Power profile and search range explanations

Also updated:
- actions.md: Added scheduling services overview, entry_id as optional
- automation-examples.md: Cross-reference to scheduling services guide
- Sidebar: Added scheduling-services to Reference category

Impact: Users have comprehensive documentation with a decision guide,
practical examples, and automation templates for the new services.
2026-04-11 19:01:15 +00:00
Julian Pawlowski
9142f87abd docs(services): add scheduling services user documentation
New comprehensive documentation page for all 5 scheduling services:
- Decision flowchart for choosing the right service
- Detailed parameter reference with examples for each service
- Response format examples with realistic data
- Practical automation examples (overnight scheduling, EV charging,
  peak price avoidance)
- Power profile and search range explanations

Also updated:
- actions.md: Added scheduling services overview, entry_id as optional
- automation-examples.md: Cross-reference to scheduling services guide
- Sidebar: Added scheduling-services to Reference category

Impact: Users have comprehensive documentation with a decision guide,
practical examples, and automation templates for the new services.
2026-04-11 18:58:37 +00:00
Julian Pawlowski
6e0613c055 feat(services): add 5 scheduling services for price-optimized time windows
New services for finding optimal electricity price windows:
- find_cheapest_block: Cheapest contiguous time block (e.g., dishwasher)
- find_cheapest_hours: Cheapest N hours, non-contiguous (e.g., EV charging)
- find_cheapest_schedule: Multi-task scheduling with no-overlap (e.g., shared circuit)
- find_most_expensive_block: Most expensive contiguous block (peak avoidance)
- find_most_expensive_hours: Most expensive N hours (consumption shifting)

Key features:
- Flexible search range (today, tomorrow, today+tomorrow, rolling window)
- Power profile support for variable consumption patterns
- Price level filtering (e.g., only CHEAP/VERY_CHEAP intervals)
- Comparison details showing savings vs. alternatives
- Sliding window algorithm (O(n)) for block search, greedy scheduling
  for multi-task optimization

Also includes:
- Shared validation utilities (search range, price level, power profile)
- entry_id now optional on all services (auto-selects single home)
- Input validation for existing services (time range, filter conflicts)
- Service icons for all new and existing services
- Translations for all 5 languages (en, de, nb, nl, sv)
- Removed 10 unused config.error translation keys (replaced by exceptions)
- Tests for price window algorithms and search range resolution

Impact: Users can find optimal time windows for appliances, EV charging,
and multi-device scheduling via HA service calls. Existing services
improved with optional entry_id and better input validation.
2026-04-11 18:58:27 +00:00
Julian Pawlowski
8aa5769784 feat(devcontainer): add yq and additional CLI tools, improve compatibility symlinks
Some checks are pending
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
2026-04-11 15:56:14 +00:00
Julian Pawlowski
c7af02f7c2 feat(devcontainer): add common CLI tools and setup symlinks for compatibility 2026-04-11 15:17:20 +00:00
Julian Pawlowski
2f704a35a3 refactor: remove dead code across integration
Remove unused functions, constants, and entity definitions that were
left over from previous refactorings. All removed code was either
superseded by better implementations or never actually called.

Removed functions:
- entity_utils/helpers.py: translate_level(), translate_rating_level()
  (HA handles ENUM translation automatically via translations/*.json)
- entity_utils/attributes.py: build_timestamp_attribute(),
  build_period_attributes() (superseded by inline implementations)
- sensor/helpers.py: get_hourly_price_value(), aggregate_window_data()
  (replaced by Calculator Pattern in sensor/calculators/)

Removed constants and definitions:
- const.py: CONF_CHART_DATA_CONFIG (DATA_CHART_CONFIG is the active one),
  PRICE_LEVEL_OPTIONS, PRICE_RATING_OPTIONS, VOLATILITY_OPTIONS,
  PRICE_TREND_OPTIONS (never imported; options defined inline in
  definitions.py due to HA import timing constraints),
  async_get_home_type_translation() (sync version used instead)
- coordinator/core.py: FRESH_TO_CACHED_SECONDS (leftover from old
  caching strategy, never referenced)
- switch/definitions.py: BEST_PRICE_SWITCH_ENTITIES (duplicate of
  BEST_PRICE_SWITCH_ENTITY_DESCRIPTIONS using base class instead of
  custom TibberPricesSwitchEntityDescription subclass)

Cleanup:
- entity_utils/__init__.py: Remove exports for deleted functions
- sensor/helpers.py: Remove now-unused imports (timedelta,
  get_intervals_for_day_offsets, get_price_value, Callable)
- entity_utils/helpers.py: Remove unused get_price_level_translation
  import after translate_level() removal
- sensor/definitions.py: Update 7x "Keep in sync with *_OPTIONS"
  comments to reference individual PRICE_LEVEL_*/PRICE_RATING_*/
  VOLATILITY_* constants instead

Impact: No user-visible changes. Reduces codebase by ~130 lines.
Improves maintainability by eliminating misleading dead code.
2026-04-11 12:13:26 +00:00
Julian Pawlowski
d6bd933e90 docs(period-calculation): clarify Best Price definition and V-shaped price day behavior 2026-04-11 12:09:15 +00:00
Julian Pawlowski
07117801d2 fix(docs): correct inaccuracies and add missing documentation
Documentation fixes:
- configuration.md: Fix default min period length (30→60 min)
- configuration.md: Fix Average Sensor Display location (Step 6→General Settings)
- sensors-volatility.md: Add missing price_volatility attribute to table
- sensors-trends.md: Document undocumented next_price_trend_change_in sensor
- actions.md: Document undocumented get_price service

Code quality fixes:
- get_price.py: Fix misleading module docstring
- timing.py: Remove dead code (unreachable return None)
- binary_sensor/core.py: Simplify redundant tomorrow_data logic

Impact: Users get accurate documentation. No behavioral changes.
2026-04-11 11:51:52 +00:00
Julian Pawlowski
1db86d1766 feat(docs): improve sidebar and navbar UX
Disable autoCollapseCategories to prevent unwanted collapsing when
clicking an active category header twice.

Add hideOnScroll to navbar for more reading space on long pages.

Add category link targets in both sidebars so category headers are
clickable and navigate to the section overview page.

Impact: Sidebar navigation no longer collapses unexpectedly.
Category titles are now direct navigation links. Navbar hides while
scrolling, giving more screen space for content.
2026-04-11 11:20:10 +00:00
Julian Pawlowski
c610dbe1a3 fix(tests): move LogCaptureFixture import under TYPE_CHECKING for better type hinting 2026-04-11 11:05:55 +00:00
Julian Pawlowski
ac7cd5b572 fix(lint): apply Python 3.14 ruff rules and update HA minimum version
Add UP037 to ruff ignore list to preserve quoted TYPE_CHECKING forward
references (PEP 649 lazy eval breaks get_type_hints() at runtime for
TYPE_CHECKING-guarded imports).

Move datetime imports into TYPE_CHECKING blocks in sensor/calculators
timing.py and trend.py (TC003, type-only usage confirmed).

Apply PEP 758 parenthesis-free except clauses across 7 files via
ruff format with target-version=py314.

Update hacs.json minimum HA version to 2026.4.0, the first HA release
requiring Python 3.14.

Impact: Linter config now correctly handles Python 3.14 semantics.
Users need HA >= 2026.4 (Python 3.14) to use this integration.
2026-04-11 10:56:34 +00:00
Julian Pawlowski
f2f0d296d1 docs(readme): restructure as HACS storefront with updated features
Complete README rewrite focused on user value propositions instead
of exhaustive technical entity tables. Updated feature list to
reflect 100+ entities across sensors, binary sensors, switches,
and number platforms.

Key changes:
- "Why This Integration?" section with 5 value categories
- Compact entity highlights table replacing 6 detailed tables
- Added missing features: forecasts, trends, volatility, runtime
  config (switches/numbers), period timing, interval pool
- Fixed broken /user/sensors link → /user/sensor-reference
- Reduced automation examples to 2 highlights + link
- Moved troubleshooting to doc links (FAQ + Troubleshooting)
- Updated service: → action: in YAML examples

Impact: README now serves as an inviting HACS storefront that
showcases all integration capabilities and encourages users to
try it, instead of overwhelming with technical details.
2026-04-11 10:55:21 +00:00
Julian Pawlowski
cbbfadbf4f refactor(docs): restructure navigation and split large pages
Split sensors.md (1,693 lines) into 7 focused pages:
- sensors-overview: binary sensors, core price, min/max, diagnostics
- sensors-average: median/mean, automation examples, key attributes
- sensors-ratings-levels: 3-level ratings + 5-level system
- sensors-volatility: CV formula, 4 sensors, configuration
- sensors-trends: outlook, trajectory, current/next, decision guide
- sensors-timing: period timing state diagram + examples
- sensors-energy-tax: energy/tax breakdown + use cases

Extract relaxation deep-dive from period-calculation.md into
dedicated period-relaxation.md. Remove duplicate ApexCharts section
from automation-examples.md (cross-references chart-examples.md).

Reorganize sidebar into semantic categories:
- Sensors (7 pages), Price Periods (2), Dashboards & Charts (4),
  Reference (sensor-reference + actions)

Update all cross-references across 10 pages, EntitySearch DOC_NAMES,
and generator template for new page slugs.

Impact: Users can find information faster with shorter, focused pages
and a clearer navigation structure. No content was removed — only
reorganized and deduplicated.
2026-04-11 10:33:58 +00:00
Julian Pawlowski
c494d0e39d docs: remove outdated last updated and integration version notes from period calculation 2026-04-11 09:57:46 +00:00
Julian Pawlowski
c892d7376c docs: document entity reference system in AGENTS.md
Add documentation for the new multi-language entity reference system:
- Generator script usage (generate-sensor-reference, --check mode)
- Entity reference annotation guidelines for doc pages
- Updated scripts/check description to include reference freshness
- Reminder to regenerate reference after adding/renaming entities

Impact: Future sessions know how to maintain the entity reference
system and keep it in sync with translation file changes.
2026-04-11 09:56:10 +00:00
Julian Pawlowski
0e699ae142 feat(docs): add multi-language entity reference with search
Add a comprehensive entity reference system that helps users find
entities across all 5 supported languages (EN, DE, NO, NL, SV).

Core components:
- Generator script (scripts/docs/generate-sensor-reference) that
  builds sensor-reference.md from translation files with --check
  mode for CI validation
- EntityRef component for compact inline entity annotations with
  tooltip and version-aware linking to the reference table
- EntitySearch component with live filtering, clickable results,
  keyboard navigation, "/" shortcut to focus, category filter chips,
  match highlighting, copy-entity-ID button per row, back-links to
  documentation pages, persistent row highlights, hash-based deep
  linking, and mobile-responsive layout
- MDXComponents theme override for global component registration

Documentation updates:
- New sensor-reference.md page (115 entities x 5 languages)
- EntityRef annotations across 10 documentation pages
- Sidebar entry for quick navigation
- CI integration (docusaurus.yml + scripts/check)
- Ruff per-file-ignores for scripts/ (T201, INP001)

Impact: Users can now find any entity by its localized display name
regardless of their UI language. Inline EntityRef annotations link
directly to the multi-language lookup table with version-aware URLs.
2026-04-11 09:55:28 +00:00
Julian Pawlowski
cd59834277 Merge branch 'main' of https://github.com/jpawlowski/hass.tibber_prices
Some checks are pending
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
2026-04-11 08:30:43 +00:00
Julian Pawlowski
89de3dcadf docs(user): wrap large YAML blocks in collapsible details elements
All YAML code blocks >12-14 lines in example and concept pages are now
wrapped in HTML <details>/<summary> elements, reducing scroll depth
and making complex pages easier to navigate.

Pages affected:
- automation-examples.md: 9 blocks (heat pump, EV, battery automations)
- dashboard-examples.md: 6 blocks (button-card, mushroom, grid layouts)
- sensors.md: 7 blocks (practical examples, energy/tax templates, timing)
- icon-colors.md: 8 blocks (card_mod methods, complete dashboard, custom colors)
- period-calculation.md: 3 blocks (sensor attr reference, midnight example, automations)

Blocks left visible: short examples (<13 lines), Good/Bad comparisons,
Method 1 (primary recommended approach in icon-colors.md).

Impact: Users can scan page structure without scrolling past long YAML.
Code is still one click away, not hidden behind navigation.
2026-04-11 08:30:25 +00:00
dependabot[bot]
40a80247a0
chore(deps): bump the react group in /docs/user with 2 updates (#106) 2026-04-11 09:18:28 +02:00
dependabot[bot]
16f74d6419
chore(deps): bump the react group in /docs/developer with 2 updates (#107) 2026-04-11 09:18:16 +02:00
Julian Pawlowski
5314454a26 docs(user): add community examples page with NL solar feed-in templates
Some checks are pending
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
New dedicated page for community-contributed examples, starting with
Dutch solar feed-in compensation (saldering) patterns adapted from
GitHub Discussion #105 (OdynBrouwer). Includes input_number helpers
for country-specific tax rates, template sensors for feed-in with
and without saldering, smart export automation, and dashboard card.
German spot price share template as starting point. Norwegian/Swedish
sections as placeholders for future contributions.

YAML code blocks use collapsible details elements to keep the page
scannable. Page is framed generically to accommodate any type of
community example in the future (not just country-specific).

Added cross-reference from sensors.md Energy Price section and new
"Community" sidebar category.

Impact: Users (especially Netherlands) can find ready-to-adapt template
examples for country-specific price calculations using the energy_price
and tax attributes. Framework ready for additional community examples.
2026-04-10 14:57:02 +00:00
Julian Pawlowski
6e7b7b3ceb docs(agents): document entity migration & repairs pattern
Added Entity Migration & Breaking Change Repairs section (Common Pitfalls #6)
documenting the separation between migrations.py, coordinator/repairs.py, and
_migrate_config_options().

Additional changes:
- migrations.py added to allowed root files list and component structure tree
- Common Tasks "Add a new sensor": step 6 for ENTITY_KEY_RENAMES registration
- Duration sensor pattern (native=MINUTES, suggested=HOURS) documented

Impact: Future sessions generate correct migration code on first try without
rediscovering the pattern.
2026-04-10 12:21:55 +00:00
Julian Pawlowski
565397b8ca feat(migrations): add entity auto-migration system with HA repairs
Adds migrations.py with automatic entity registry migration for renamed
sensor keys. Separated from coordinator/repairs.py (runtime issues) and
__init__.py _migrate_config_options() (config format changes).

- ENTITY_KEY_RENAMES dict maps old→new entity keys (extensible)
- _auto_migrate_entity_keys() updates unique_id, preserves entity_id
- Handles partial migration (new entity already exists → remove old)
- Creates persistent HA repair issue after migration via ir.async_create_issue()
- Called in async_setup_entry() after _migrate_config_options()

Migrates: trend_change_in_minutes → next_price_trend_change_in

Repair issue informs users about:
- Auto-migrated entity renames (entity_id preserved, no action needed)
- Duration sensor value unit change (hours → minutes): update automation
  thresholds from `state < 0.25` to `state < 15` for 15-minute checks

All 5 language files (en, de, nb, nl, sv) updated with translations.

BREAKING CHANGE: Duration sensors (remaining time, starts in, period
duration, trend change countdown) now report state values in minutes
instead of hours. Display unit in dashboards remains hours by default.
Update numeric comparisons in automations accordingly.

Impact: Users upgrading from previous releases see an informational
repair notice guiding them through any required automation updates.
Entity renames are handled transparently with no loss of history.
2026-04-10 12:21:49 +00:00
Julian Pawlowski
2a08515ba0 fix(sensors): use consistent rounding for trend duration calculations
Some checks are pending
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
Replaced int(time.minutes_until()) with time.minutes_until_rounded()
in trend calculator (3 locations). The int() call truncated values
(14.7 → 14) while timing sensors used standard rounding (14.7 → 15).

All duration sensors now use the same rounding method
(math.floor(seconds/60 + 0.5)), matching HA's timestamp rendering
behavior.

Impact: Trend countdown values may differ by ±1 minute compared to
previous behavior. Consistency across all duration sensors improved.
2026-04-10 09:13:32 +00:00
Julian Pawlowski
faa3b2b71a feat(sensors)!: use native minutes for all duration sensors
Changed native_unit_of_measurement from HOURS to MINUTES for all 7
duration sensors. HA auto-converts to hours for display via
suggested_unit_of_measurement=HOURS.

Sensors affected:
- next_price_trend_change_in
- best_price_period_duration, best_price_remaining_minutes,
  best_price_next_in_minutes
- peak_price_period_duration, peak_price_remaining_minutes,
  peak_price_next_in_minutes

Removed _minutes_to_hours() conversion function — calculator values
(minutes) are now passed through directly.

BREAKING CHANGE: State values for all duration sensors change from
hours to minutes (e.g. 1.5 → 90). The display unit remains hours
(suggested_unit_of_measurement). Automations using numeric state
comparisons must be updated (multiply old thresholds by 60).

Impact: Users with automations comparing duration sensor states
numerically need to update thresholds. Dashboard display is unchanged
for new installations. Existing installations retain their configured
display unit but the underlying numeric value changes.
2026-04-10 09:08:38 +00:00
Julian Pawlowski
b1b41be9aa feat(sensors)!: rename trend change countdown sensor for naming consistency
Renamed trend_change_in_minutes → next_price_trend_change_in to align
with its sibling sensor next_price_trend_change (timestamp variant).

Follows the established best/peak price naming pattern where related
sensors share a common prefix (e.g. best_price_next_start_time /
best_price_next_in_minutes).

Updated entity key, translation key, friendly names (all 5 languages),
custom translations, coordinator constants, attribute routing, and
cache-clear mapping.

BREAKING CHANGE: Entity ID changes from
sensor.<home>_trend_change_in_minutes to
sensor.<home>_next_price_trend_change_in. Automations and dashboards
referencing the old entity ID must be updated.

Impact: Users with automations or dashboard cards referencing the old
sensor name need to update references. The sensor retains identical
functionality and attributes.
2026-04-10 09:08:27 +00:00
Julian Pawlowski
74cca1857a fix(docs): update image URLs in README for proper rendering
Some checks failed
Deploy Docusaurus Documentation (Dual Sites) / Build and Deploy Documentation Sites (push) Waiting to run
Lint / Ruff (push) Waiting to run
Validate / Hassfest validation (push) Waiting to run
Validate / HACS validation (push) Waiting to run
Auto-Tag on Version Bump / Check and create version tag (push) Has been cancelled
2026-04-09 19:28:41 +00:00
Julian Pawlowski
112b169f26 feat(docs): enable mdx1 compatibility for admonitions in Docusaurus config 2026-04-09 19:20:15 +00:00
github-actions[bot]
84deafbdf5 docs: add version snapshot v0.30.0 and cleanup old versions [skip ci] 2026-04-09 19:07:16 +00:00
Julian Pawlowski
c1ffcfd559 chore(release): bump version to 0.30.0 2026-04-09 19:05:27 +00:00
Julian Pawlowski
55e02e3b54 feat(brand): update dark icons for improved visual consistency 2026-04-09 19:04:26 +00:00
Julian Pawlowski
459d6762c7 perf(sensors): add call-avoidance for timer-based state updates
Skip expensive async_write_ha_state() when native_value hasn't changed
since last write. HA's state machine has built-in change detection, but
it only runs AFTER all properties and attributes are evaluated — the
expensive part we now avoid entirely.

Sensor platform (Timer #2 + #3):
- New _write_if_changed() method compares native_value before writing
- Timer #3 (30s, 7 entities): Skips all writes when no period active
- Timer #2 (15min, ~45 entities): Skips enum levels/ratings that stay
  constant across quarter-hour intervals
- Replaces data_lifecycle_status-only pattern with unified approach

Binary sensor platform (Timer #2):
- Period sensors only write at actual period boundaries, not every 15min

Coordinator push updates always write (sentinel reset ensures freshness).

Impact: Eliminates asyncio "Executing TimerHandle took 1.4s" warnings
caused by redundant property evaluation in Timer #3 callbacks. Reduces
event loop blocking from ~1.4s to microseconds when values unchanged.
2026-04-09 19:04:04 +00:00
Julian Pawlowski
ac09e5f235 fix(docs): avoid mdx/ssg runtime error in energy-tax formula
Replace the inline KaTeX block in the Energy Price & Tax Breakdown
section with a plain inline equation string.

The previous expression caused a Docusaurus SSG runtime failure on the
sensors page (ReferenceError during static rendering).

Impact: User docs build now succeeds consistently for the sensors page.
2026-04-09 18:41:46 +00:00
Julian Pawlowski
aee1920292 chore(pre-commit): add docusaurus build guard for changed docs sites
Add a local pre-commit hook that builds Docusaurus when files under
docs/user or docs/developer are staged.

Introduced scripts/docs/build-changed-sites to detect which docs site
was touched and run only the required npm build(s).

Impact: Prevents broken MDX/Docusaurus changes from being committed by
failing fast in pre-commit before CI.
2026-04-09 18:41:41 +00:00
Julian Pawlowski
06eedee410 docs: update links for energy and tax fields in actions documentation 2026-04-09 18:35:05 +00:00
Julian Pawlowski
9c4ac6bce4 docs(user): document energy price and tax breakdown
Add new section 'Energy Price & Tax Breakdown' to sensors.md:
- Attribute overview table (interval, min/max, daily avg sensors)
- Use cases: solar feed-in/net metering, price composition analysis,
  dashboard cost breakdown with example YAML templates
- Cache transition note for gradual data availability after update

Add 'Energy & Tax Fields in get_chartdata' section to actions.md:
- Parameter documentation with defaults
- Example service call YAML
- ApexCharts integration example with custom field names

Impact: Users can discover and utilize the new energy/tax attributes
with ready-to-use automation and dashboard examples.
2026-04-09 18:28:06 +00:00
Julian Pawlowski
d1b25e9cfe feat(services): add energy/tax fields to get_chartdata action
Add four optional parameters to the get_chartdata service:
- include_energy: Include raw energy/spot price (default: false)
- include_tax: Include tax component (default: false)
- energy_field: Custom field name (default: energy_price)
- tax_field: Custom field name (default: tax)

Custom field names allow direct compatibility with ApexCharts
and other charting tools without post-processing.

All code paths (all/segments/none insert_nulls modes) and the
last-interval handler include energy/tax when enabled.

Added translations for all 5 languages (en, de, nl, nb, sv).

Impact: Users can include price composition data in chart exports,
enabling visual breakdowns of energy cost vs. taxes in dashboards.
2026-04-09 18:27:53 +00:00
Julian Pawlowski
edabb49309 feat(sensors): expose energy/tax breakdown as sensor attributes
Add energy_price and tax attributes to interval and daily stat sensors:

- Interval sensors (current/next/previous): energy_price and tax from
  the specific 15-minute interval
- Daily min/max sensors: energy_price and tax from the extreme interval
- Daily average sensors: energy_price_mean, energy_price_median,
  tax_mean, tax_median — matching the existing mean/median pattern
  used for the main price attribute

Calculator caches both mean and median for energy/tax using
calculate_median() from utils/average. All new attributes are
excluded from Recorder to prevent database bloat.

Impact: Users can see price composition (spot price vs. taxes) on
all major price sensors. Enables solar feed-in and net metering
automations based on raw energy prices.
2026-04-09 18:27:36 +00:00
Julian Pawlowski
f5dcf04aab feat(api): add energy and tax fields to Tibber GraphQL queries
Request `energy` and `tax` fields alongside `total` in both
quarter-hourly price queries. These represent the raw spot price and
the tax/fee component that together make up the total consumer price.

Updated hourly aggregation in formatters.py to carry energy/tax
values through to aggregated output.

Impact: Enables downstream consumers (sensors, services) to expose
price composition data. Useful for solar feed-in compensation and
net metering (saldering) calculations where the raw energy price
is needed separately from taxes.
2026-04-09 18:27:21 +00:00