Adjusted the required Python version in the project configuration to ensure compatibility with the latest features and improvements.
Impact: Users must have Python 3.14.2 or higher to run the project.
Restructure configuration.md: separate "stored precision" from "default display
precision" tables to avoid confusion between internal representation and what is
shown in dashboards. Add note that HA shows its own unit-change dialog (delayed);
our repair issue appears immediately as step 1. Recommend deleting old statistics
data rather than re-labeling, which would leave wrong values with the new unit.
Update faq.md examples to use display precision values for consistency with the
documentation.
Add DATA_STATISTICS_REVIEW_REQUIRED flag to config_entry.data. Set on
currency mode change, cleared on same-mode save. On every async_setup_entry
with flag set, delete and recreate the repair issue so it reappears after
HA restart even if previously dismissed.
Repair issue text explains that HA Recorder shows its own unit-change
dialog (delayed) and recommends deleting old statistic data rather than
re-labeling, which would leave wrong values with the new unit.
Impact: Users are notified to review statistics and automations after
switching between base/subunit currency mode. Notification persists across
HA restarts until acknowledged by saving display settings again.
Add get_display_precision() to const.py returning DISPLAY_PRECISION_SUBUNIT (2)
or DISPLAY_PRECISION_BASE (4) based on config. Replace hardcoded round(..., 2)
with get_display_precision() in all calculators and attribute builders.
Add _update_suggested_precision() to sensor core; syncs entity registry
suggested_display_precision on every coordinator update.
Interval price sensors get full precision (2 or 4 dp); other MONETARY sensors
get half precision (1 or 2 dp) as sensible default.
Impact: Price sensor states and attributes now correctly use 4 decimal places
in base-currency mode (was always 2). Display precision in dashboards updates
automatically when currency mode changes.
Enhance the documentation for volatility sensors by explaining that the maximum price rank will never reach 100% and providing a YAML automation example for managing device usage during peak pricing.
Impact: Users gain a clearer understanding of price rank behavior and practical automation guidance.
Refactor the contribution guidelines to enhance readability and consistency in formatting. Adjusted code blocks and list formatting for better visual structure.
Impact: Contributors will find it easier to follow the guidelines when contributing to the project.
---
docs(README): update automation examples for better readability
Reformatted YAML automation examples in the README to improve clarity and consistency. Indentation and structure were adjusted for better understanding.
Impact: Users will have clearer examples for setting up automations with the integration.
---
chore(manifest): streamline manifest file formatting
Consolidated formatting in the manifest file for consistency. Adjusted the codeowners and requirements sections for a cleaner look.
User-Impact: none
---
chore(pyproject): enhance project configuration for better linting and testing
Updated the pyproject.toml file to improve linting configurations and testing options. Added specific rules for ruff and pytest to align with project standards.
User-Impact: none
---
chore(manifest_schema): simplify JSON schema for integration manifest
Refined the manifest schema by consolidating enum definitions for better readability and maintenance.
User-Impact: none
---
chore(prettier): add Prettier configuration for consistent code formatting
Introduced a Prettier configuration file to standardize code formatting across the project, ensuring consistency in style.
User-Impact: none
Updated color and icon logic to include additional keys for price trends, outlooks, and trajectories. This improves the visual representation of price changes in the UI.
Impact: Users will see more accurate color coding and icons for price trends and forecasts.
Improve error handling for API fetch failures by implementing a fallback to cached intervals. This ensures the system can continue functioning during transient API issues.
Impact: Users experience fewer interruptions when the API is temporarily unavailable, as cached data will be used seamlessly.
Modified error messages in multiple language translation files to remove unnecessary curly braces around the template placeholder for improved clarity.
Impact: Users will see clearer error messages when invalid array_fields are provided.
Improved validation logic for service parameters in find_cheapest_hours, find_cheapest_schedule, and chartdata services. Added checks for unique task names, ensured that segment durations do not exceed total duration, and clarified error messages for better user understanding.
Impact: Users will receive clearer error messages and improved validation when using the services, leading to a more robust experience.
Updated the filter logic to include period_filter alongside level_filter and rating_level_filter for segment definitions. This change ensures that users can utilize period_filter effectively when defining segments.
Impact: Users can now use period_filter in addition to existing filters for more flexible segment definitions.
Updated sensor definitions to enhance clarity and maintain consistency by removing the diagnostic entity category from day pattern sensors.
Impact: No user-facing changes.
Revised the comment regarding explicitly skipped commits to enhance readability and maintain consistency in documentation style.
Impact: Improved clarity for developers reviewing the release notes generation script.
Updated the long descriptions and usage tips for the price trend change sensors in multiple languages (de, en, nb, nl, sv) to provide clearer guidance on detection mechanics and expected behavior during V-shaped price days.
Impact: Users will have a better understanding of how the sensors operate and can make more informed decisions regarding automation based on price trends.
Refactor the period extension logic to clarify the handling of primary and fallback price levels. Update the documentation to reflect the changes in how periods extend into adjacent intervals.
Impact: Users will benefit from clearer price extension behavior and improved performance in period calculations.
Implement an auto-assign workflow to automatically assign newly opened issues to the repository owner.
Impact: Streamlines issue management by ensuring the owner is automatically assigned to new issues.
Replace CV with IQR% as the primary indicator for flat-day detection
in _compute_day_effective_min(). CV is inflated by isolated price spikes
(a single spike at 2× the average pushes CV to 15-25% while the core
price band stays flat), causing the flat-day adaptation to be missed.
IQR% (spread of the central 50% of prices / median) is unaffected by
tail outliers and correctly identifies "flat core + spike" days.
Threshold: LOW_IQR_PCT_FLAT_DAY_THRESHOLD = 15.0%
- IQR% ≈ 1.35 × CV for symmetric data, so 15% ≈ old CV threshold of 10%
- Extra headroom catches flat days with a single outlier (IQR%~3%,
CV~20%) that were previously missed
CV retained as fallback for edge cases where iqr_pct is None
(near-zero or negative median prices).
Impact: Flat days with a single isolated price spike are now correctly
identified, reducing unnecessary relaxation iterations on those days.
Rename the three existing price rank sensors from price_rank_* to
current_interval_price_rank_* to clarify they rank the current
quarter-hour interval's price, not a daily aggregate — consistent with
current_interval_price_level / current_interval_price_rating naming.
Add 8 new rank sensors covering additional subjects and reference windows:
- next_interval_price_rank_{today,today_tomorrow}
- previous_interval_price_rank_{today,today_tomorrow}
- current_hour_price_rank_{today,today_tomorrow} (5-interval rolling avg)
- next_hour_price_rank_{today,today_tomorrow} (5-interval rolling avg)
All new sensors are disabled by default. The volatility calculator gains a
subject parameter (_get_subject_price / _get_subject_price_attr_key /
_get_rolling_hour_avg_price) to select which price to rank. Sensor key
routing in value_getters.py and attributes/__init__.py updated accordingly.
No migration entries needed — the original price_rank_* sensors were never
released to users.
All 5 translation files updated. sensor-reference.md regenerated (129 entities).
Impact: Users can now track price rank for the next interval (look-ahead),
the previous interval (logging), and rolling hourly averages — for both
same-day and two-day reference windows.
Updated the configuration files to improve development experience by explicitly loading useful integrations and adjusting logging levels. Added YAML schemas for configuration and services to ensure proper structure and validation.
Impact: Developers will have a more streamlined setup process and better logging during integration development.
Enhance the configuration for the HTTP component to support development in Codespaces and DevContainer. This includes settings for server host, IP banning, trusted proxies, and CORS.
Impact: Improved development experience by allowing easier access and configuration in development environments.
Convert four-space-indented list items (`- item`) to standard two-space
(`- item`) in AGENTS.md, CONTRIBUTING.md, README.md, and all Docusaurus
documentation pages (developer and user, including versioned snapshots).
No content changes.
Release-Notes: skip
Apply consistent 4-space indentation and trailing-operator style for line
continuations (&&, |) across all development and release scripts. No logic
changes.
Release-Notes: skip
Update sensors-volatility.md to cover the three new price rank sensors and the
IQR-based volatility attributes (typical price band / price spike count).
Section headers include technical terms in parentheses for experts:
"Typical Price Band Statistics (IQR)" and "Price Rank Sensors (Percentile Rank)".
Attribute tables list Tukey fence formulas and plain-language explanations
side-by-side.
Regenerate sensor-reference.md to include price_rank_today,
price_rank_tomorrow, and price_rank_today_tomorrow with translations for all
five supported languages.
Impact: Users have full documentation for the new sensors including examples,
formulas, and a multi-language lookup table.
Add entity descriptions, long descriptions, and usage tips for the three new
price_rank_* sensors and the updated volatility sensors with IQR attributes.
Plain-language terms are used as primary labels (e.g. "typical price band",
"price rank"); technical terms are included parenthetically for experts
(e.g. "IQR", "percentile rank", "Tukey fences") in all five languages.
Impact: Sensors show descriptive help text in the entity detail view, making it
easier for users to understand what each sensor measures without consulting
external documentation.
Add entity name translations for price_rank_today, price_rank_tomorrow, and
price_rank_today_tomorrow sensors in English, German, Norwegian, Dutch, and
Swedish.
Impact: Sensor display names appear correctly in the Home Assistant UI for all
supported languages.
Add three new price rank sensors that show where today's/tomorrow's/combined
average price falls relative to all intervals in the evaluated window:
- price_rank_today: today's average price percentile rank (0–100%)
- price_rank_tomorrow: tomorrow's average price percentile rank
- price_rank_today_tomorrow: combined today+tomorrow percentile rank
Extend all volatility sensors with IQR-based band statistics:
- price_typical_spread: interquartile range (IQR) in currency subunit
- price_typical_spread_%: IQR as percentage of daily average
- price_spike_count: number of intervals outside Tukey fences (outliers)
Add calculate_iqr_stats() utility function in utils/price.py that computes
the 25th/75th percentiles, IQR, outer fences (Q1 - 1.5×IQR / Q3 + 1.5×IQR),
and outlier count for any list of price values. Entity keys and attribute
names use plain language (`price_rank`, `price_typical_spread`) as primary
labels; technical terms (percentile rank, IQR) are included parenthetically
in descriptions and documentation.
Impact: Users can now see where current day prices rank compared to their window and how tightly clustered or spike-prone a day's prices are.
Add structured reason codes to no-result responses for find_cheapest_block,
find_cheapest_hours, and find_cheapest_schedule. Each handler now classifies
why no result was returned: no_data_in_range, no_intervals_matching_level_filter,
insufficient_intervals_after_filter, or insufficient_contiguous_window.
Add include_comparison_details flag to find_cheapest_schedule. When enabled,
each scheduled task includes a price_comparison field showing the most expensive
alternative window (mean, min, max, start, end) for cost-savings context.
Document stable reason code contracts in en.json service descriptions.
Add corresponding field translations to all locales (de, nb, nl, sv).
Impact: Automations and scripts can now react to why no window was found,
and schedules can display concrete savings vs. worst-case pricing.
cliff.toml:
- Extract Impact footer value from commit footers and use as release note
text when present, falling back to scope+message format otherwise
- Fix whitespace in body template (remove extra indentation)
scripts/release/generate-notes:
- Add RELEASE_NOTES_TRAILER_SKIP_FILTER to exclude commits marked with
Release-Notes: skip, User-Impact: none, or Released-Bug: no trailers
- Add RELEASE_NOTES_COMPACT_DIFF and RELEASE_NOTES_DIFF_MAX_BYTES to
limit AI diff context size for faster, more focused prompts
- Add RELEASE_NOTES_CLIFF_FILTER_PATHS to restrict cliff to user-facing
paths only when generating AI-assisted notes
- Add RELEASE_NOTES_CLIFF_SINGLE_RELEASE to pass --latest to cliff
- Define USER_FACING_PATHS list for scoped AI diff context
Release-Notes: skip
User-Impact: none
AGENTS.md:
- Replace the minimal 'Type checking and linting' block with a full
script selection guide including preferred dev flow (auto-healing),
check-only flow, and agent behavior rules for fix vs. verify intent
- Add new scripts: format-all, lint-fix, lint-all, check-all
- Clarify commit execution rules: agents only run git commit on explicit
user request; a one-time request does not authorize future commits;
git push is never suggested or executed
CONTRIBUTING.md:
- Add reference to commit-messages.instructions.md for full commit rules
- Add trailer examples for suppressing release notes on internal fixes
Release-Notes: skip
User-Impact: none
- Link commit-messages.instructions.md via commitMessageGeneration.instructions
setting so the VS Code SCM Generate button applies project commit rules
- Add explicit editor.formatOnSave: true to [jsonc] language block,
matching the existing [json] block for consistent behavior
Release-Notes: skip
User-Impact: none
Add .github/instructions/commit-messages.instructions.md with Conventional
Commit rules, Impact footer guidance, and release-notes skip trailers.
Wired to VS Code via github.copilot.chat.commitMessageGeneration.instructions
in devcontainer.json so the SCM Generate button uses these rules.
Release-Notes: skip
User-Impact: none
Consistent naming with the period_count_* family introduced in the
previous commit (period_count_total, period_count_today,
period_count_tomorrow).
periods_remaining was the last attribute in the navigation triplet
using the old plural form. Renamed to period_count_remaining to follow
the established pattern: all countable period metrics use the
period_count_* prefix.
BREAKING CHANGE: periods_remaining renamed to period_count_remaining.
Impact: All four period count attributes now share the same prefix
(period_count_total, period_count_today, period_count_tomorrow,
period_count_remaining), making automation templates more predictable.
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".
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.
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.