Explain the top-level success flag and the price_data_unavailable reason for
get_price, find_cheapest_*, and plan_charging, and clarify that an empty
result with success=true (e.g. tomorrow's prices not yet published) is not an
error. Note that day-ahead prices usually arrive around 13:00 but can be
delayed into the afternoon or evening.
Impact: Automation authors can reliably tell a temporary API outage apart from
normally missing data.
Track API failures over time in the repair manager and raise an api_outage
repair issue once fresh data has been missing for longer than two hours,
independent of the update interval. A genuine successful fetch clears it;
serving cached data as a fallback keeps the outage active. Expose the degraded
cache-fallback state via the connection binary sensor (using_cached_data,
last_successful_update) so users can tell when sensors run on locally cached
prices. Add the api_outage repair strings to all supported languages.
Impact: Users get a clear repair notice during prolonged Tibber outages and
can see when the integration is running on cached data.
Add a track_degraded parameter to IntervalPool.get_intervals so service calls
(track_degraded=False) never flip the coordinator's sensor-health flags or use
the covers-current-interval cache fallback; authentication errors still
propagate. All price-fetching services now go through
async_fetch_service_intervals and return a structured response with a
top-level success flag: success=false with reason="price_data_unavailable" on
a real API outage, and success=true (possibly empty) otherwise.
Impact: Action calls (get_price, find_cheapest_*, plan_charging) always return
the expected shape, never impair sensors during a Tibber outage, and let
automations distinguish an outage from "no data yet".
Some markets/accounts (e.g. NL hourly) return an empty
priceInfo(QUARTER_HOURLY).today while priceInfoRange still delivers the full
set of intervals. _check_price_info_empty required today's data and wrongly
classified such complete responses as empty, which blocked setup. It now
treats a response as valid when today OR yesterday data is present, since
priceInfoRange is the authoritative source the interval pool uses.
Additionally, "Empty data received" is now retried a few times with
exponential backoff, smoothing brief Tibber outages that transiently return
empty data within a single update cycle. Long outages are still absorbed by
the IntervalPool cache fallback, so the in-request retry count stays small.
Reported in #141.
Impact: Setup and updates no longer fail with "Empty data received" for NL
hourly accounts (and similar), and short Tibber blips are smoothed over.
Updated the translations for various price phase sensors in the sensor reference documentation to ensure consistency and accuracy across multiple languages.
Impact: Users will see improved clarity in the documentation for price phase sensors in their preferred language.
Add warnings to indicate that scheduling actions and the plan_charging action are experimental and subject to change. This informs users to use them with caution and report any issues.
Impact: Users are aware of the experimental nature of these features, promoting careful usage.
Updated the pytest-homeassistant-custom-component version to match the Home Assistant versioning scheme. Added a script to automate the update process for Home Assistant versions across the development environment.
Impact: Developers can now easily update Home Assistant versions and corresponding dependencies with a single command.
Blueprints are kept in the repository for development but are not yet
ready for distribution. Commented out the install and remove calls in
async_setup and async_remove_entry so they are not copied to the user's
HA config directory on integration setup.
Release-Notes: skip
User-Impact: none
Two fixes in all 4 home_connect_alt blueprints:
1. home_connect_alt.start_program uses its own `device_id` field (not HA's
standard target mechanism) and `program_key` (not `program`). The
previous `target: entity_id:` was silently ignored, causing the service
call to fail due to missing required `device_id`. Fixed by:
- Removing `target: entity_id:` block
- Adding `data.device_id: "{{ device_id(program_entity) }}"`
- Renaming `program:` to `program_key:`
- Adding `| int` filter to numeric option values
2. Same remote_start_sensor description fix as the non-alt variants
(RemoteControlActive → RemoteControlStartAllowed).
Also reset blueprint version from v2.0.0 to v1.0.0.
Release-Notes: skip
Released-Bug: no
The input field described the wrong binary sensor entity. The automation
correctly triggers on `RemoteControlStartAllowed`, but the label and
description still referenced `RemoteControlActive`.
Updated all 4 home_connect (non-alt) blueprints:
- dishwasher_home_connect.yaml
- washing_machine_home_connect.yaml
- dryer_home_connect.yaml
- laundry_day_pipeline_home_connect.yaml
Also reset blueprint version from v2.0.0 to v1.0.0 (version was bumped
prematurely, blueprints not yet released).
Release-Notes: skip
Released-Bug: no
Add `include_current_interval` parameter to `find_cheapest_block` and
`find_cheapest_schedule` services, controlling whether the currently
active price interval can be the start of the selected window.
Add power-profile weighting to `find_cheapest_contiguous_window`: accepts
an optional `power_profile` list that weights each interval's price by
relative power draw (e.g. heat-up phase heavier than steady state). Without
a profile the behaviour is unchanged (uniform weighting).
Extend search-range tests and add price-window unit tests covering weighted
and unweighted scenarios, edge cases, and sequential scheduling interactions.
Update scheduling-actions documentation with parameter and profile examples.
Impact: Users can now model appliances with non-uniform power draw (e.g. heat
pumps, washing machines) to find truly cheapest windows based on actual energy
cost rather than average price.
Keep raw Tibber API levels for best/peak period filtering while leaving smoothed levels in priceInfo for display-oriented sensors. Also make relaxation retry each flex step with the configured level filter before falling back to level_filter="any", and add regression tests for both paths.
Impact: Best-price periods no longer extend into expensive intervals because of level smoothing, and adjacent best/peak windows stay separated as expected.
Add a `price_source` field (total | energy | tax, default: total) to both
services, allowing users to choose which price component is used as the
primary chart series.
- get_chartdata: all 9 interval.get("total") calls now use price_source
- get_apexcharts_yaml: price_source forwarded through all 4 JS
data_generator calls; yaxis template variables resolve to
yaxis_min_energy / yaxis_min_tax when price_source != "total"
- Metadata-only path: always computes yaxis_suggested_energy and
yaxis_suggested_tax alongside the main yaxis bounds so the
chart_metadata sensor can expose the correct axis scale for any source
- chart_metadata sensor: exposes yaxis_min_energy, yaxis_max_energy,
yaxis_min_tax, yaxis_max_tax as new attributes
- services.yaml + all 5 language files (en, de, nb, nl, sv): price_source
field and selector options added
Impact: Users can now chart the raw energy (spot) price or the tax component separately, with correct Y-axis scaling in ApexCharts.
Co-authored-by: Copilot <copilot@github.com>
Add a dedicated type-check-tests helper, wire it into check-all behind --with-test-types, and align the affected tests with current typing and helper contracts.
Impact: No direct user-facing change.
User-Impact: none
Recompute merged relaxed periods from raw intervals, harden numeric period option normalization, update day-volatility handling for zero or negative averages, and expose day context on period binary sensors.
Add focused regressions for overlap merges, cache invalidation, day statistics, and visible binary sensor attributes.
Impact: Best and peak period entities stay consistent on negative-price days, refresh correctly when same-day prices change, and expose the documented day context attributes.
Always treat prices at or below zero as valid best-price intervals, rescue short
negative cores with directly adjacent cheap shoulders before min-length filtering,
and block geometric or shape-based widening for periods that already contain a
negative-price core.
Impact: Negative best-price periods no longer expand into positive edge intervals on days with extreme negative prices.
Introduce a new settings file to define permissions for various script executions.
Impact: Enables controlled execution of linting, type-checking, and testing scripts.
Accepts battery parameters (capacity, current/target SoC, max power) and
returns a cost-minimized charging schedule with per-interval power, SoC
progression, and total cost — no manual duration calculation needed.
Supports fixed, continuous (min_charge_power_w), and stepped
(charge_power_steps_w) charging modes, deadline-aware two-pass planning
(must_reach_soc + must_reach_by / must_reach_by_event), and round-trip
economics (expected_discharge_price, reserve_for_discharge,
max_cost_per_kwh) for arbitrage use cases. Includes min_charge_duration
and max_cycles_per_day constraints.
Groups deadline fields (must_reach_soc_*, must_reach_by,
must_reach_by_event) into a dedicated section so a deadline use case can
be configured in one place. Battery section lists capacity before the
percent SoC fields that depend on it. Response exposes stable reason
codes (already_at_target, energy_unreachable, energy_unreachable_by_
deadline, no_intervals_after_economic_filter, …) documented in the
service description and user docs.
automation-examples.md:
- Add info callout blocks with "Blueprint available" badges and
one-click import links for each appliance section (dishwasher,
washing machine, dryer, EV charging, pipeline)
- Update YAML examples to reflect current service API (remove
relaxation_applied template, fix indentation)
sensor-reference.md:
- Remove stale data-refs attributes from current_price_trend,
next_price_trend_change, and today_volatility anchors
examples/:
- Add examples/scripts/ directory with placeholder for
tibber_notify_residents.yaml script example
User-Impact: none
Bundle automation and script blueprints into the integration and
install them automatically at HA startup via _install_blueprints().
Remove them cleanly when the last config entry is removed.
Automation blueprints (standalone):
- dishwasher, washing_machine, dryer — smart plug and Home Connect
variants (HC: door/remote-start sensors; HC Alt: program selector)
Automation blueprints (pipeline):
- laundry_day_pipeline — chains washer → dryer for multiple loads,
HC and HC Alt variants
Other automation blueprints:
- ev_charging, heat_pump_price_level, heat_pump_smart_boost,
home_battery, water_heater, laundry_day_pipeline (smart plug)
Script blueprint:
- notify_residents — presence-aware dispatcher for up to 10 residents
with auto-discovered mobile_app notify services, iOS/Android push
settings, and per-resident notify overrides
Notification UX across all blueprints:
- Apple Watch-optimised titles (~25 chars) and messages (most
important info first, middle-dot separators, emoji anchors)
- Customisable notification titles via blueprint inputs (standalone)
- Comma-separated notify services for simple multi-target delivery
- Advanced script path for presence filtering and platform push data
Impact: Users get ready-to-use blueprints installed automatically
with the integration for scheduling appliances during cheap Tibber
price windows. No manual import required.
Read the version field from manifest.json at import time via a new
INTEGRATION_VERSION constant in const.py. Pass it as sw_version to
DeviceInfo in TibberPricesEntity so the current integration version
is visible in the HA device registry.
Impact: Device page in HA now shows the installed integration version
under firmware/software version.
Add entity_resolver module that lets all service parameters accept
HA entity references in place of literal values. The entity's current
state (or a specific attribute via the @attr syntax) is resolved at
call time and coerced to the expected Python type.
Syntax:
"sensor.washing_duration" → uses entity state
"sensor.washing_duration@run_minutes" → uses entity attribute
Apply or_entity_ref() and resolve_entity_references() to all five
service handlers (get_price, find_cheapest_block, find_cheapest_hours,
find_cheapest_schedule, get_chartdata) for every parameter where a
dynamic value from another entity is useful (duration, start/end times,
offsets, etc.).
Add five new translation keys for entity-resolution error messages
(invalid_entity_reference, entity_not_found, entity_attribute_not_found,
entity_state_unavailable, entity_value_conversion_failed) across all
five language files.
Fix pytest warning filter to suppress AsyncMock cleanup noise, and
update test_resource_cleanup to mock hass.config_entries.async_entries
so the blueprint-removal path in async_remove_entry does not raise.
Impact: Automations and scripts can pass sensor entity IDs as service
parameters (e.g. duration from a sensor) instead of having to use
template-based workarounds.
Replace workaround recommendations (2× find_cheapest_block) with the
new sequential: true parameter. Rewrite washer→dryer example as a single
find_cheapest_schedule call. Update quick reference tables.
Release-Notes: skip
When sequential: true, tasks are placed in declaration order instead of
being sorted by duration. Each task's search window starts after the
previous task ends (plus gap_minutes). If a task cannot be placed, all
subsequent tasks in the chain are also marked unscheduled.
Adds 12 tests covering ordering, chaining, gap enforcement, and
chain-breaking behavior.
Impact: Users can now schedule dependent appliances (e.g., washing
machine → dryer) in a single find_cheapest_schedule call with guaranteed
order, instead of chaining two find_cheapest_block calls.
Updated the dishwasher automation to include planning and execution steps using input_datetime helpers for better reliability across restarts. Clarified the use of find_cheapest_schedule for independent appliances and added caution regarding task order. Improved messaging in notifications for planned schedules.
Impact: Users can now schedule appliances more reliably, ensuring planned start times persist through Home Assistant restarts.
docs(sidebars): rename automation section for clarity
Changed the sidebar label from '🤖 Automations' to '🤖 Automations & Usage' to better reflect the content and improve user navigation.
Impact: Users will find it easier to locate automation-related documentation.