Commit graph

6 commits

Author SHA1 Message Date
Julian Pawlowski
96f36a3339 feat(services): add plan_charging service for battery/EV scheduling
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.
2026-04-20 21:43:41 +00:00
Julian Pawlowski
1d065b11cd fix(services): use injected now in resolve_search_range day offset
_resolve_time_with_day_offset() was calling dt_util.now() internally
instead of using the injected now parameter. This caused incorrect date
calculations in tests and any caller that passes a specific reference time.

Also add missing price_rank_* sensor keys to TIME_SENSITIVE_ENTITY_KEYS
in coordinator/constants.py so quarter-hour refresh is registered for all
11 price rank sensors (current/next/previous interval and hour variants).

Rename dt as dt_utils → dt as dt_util (ICN001) across 11 files to follow
the project-wide import alias convention. Apply ruff auto-fixes for import
ordering and collapsing single-item imports throughout the codebase.

Released-Bug: no
2026-04-14 19:33:24 +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
9b34d416bc feat(services): add debug_clear_tomorrow for testing refresh cycle
Add debug service to clear tomorrow data from interval pool, enabling
testing of tomorrow data refresh cycle without waiting for next day.

Service available only in DevContainer (TIBBER_PRICES_DEV=1 env var).
Removes intervals from both Pool index and coordinator.data["priceInfo"]
so sensors properly show "unknown" state.

Changes:
- Add debug_clear_tomorrow.py service handler
- Register conditionally based on TIBBER_PRICES_DEV env var
- Add service schema and translations
- Set TIBBER_PRICES_DEV=1 in devcontainer.json

Usage: Developer Tools → Services → tibber_prices.debug_clear_tomorrow

Impact: Enables rapid testing of tomorrow data refresh cycle during
development without waiting or restarting HA.
2025-12-23 14:13:51 +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
ac24f6a8cb refactor(services): split monolithic services.py into package
Split services.py (1,097 lines) into modular package (6 files, ~200-600 lines each):

Structure:
- services/__init__.py: Service registration (70 lines)
- services/helpers.py: Entry validation (55 lines)
- services/formatters.py: Data transformation (380 lines)
- services/chartdata.py: Chart data export handler (600 lines)
- services/apexcharts.py: ApexCharts YAML generator (240 lines)
- services/refresh_user_data.py: User data refresh (110 lines)

Benefits:
- Clear separation of concerns (helpers, formatters, handlers)
- Each service isolated and independently testable
- Consistent handler naming (handle_* pattern)
- Better code reuse through formatters module

All services working identically (get_chartdata, get_apexcharts_yaml,
refresh_user_data). Updated __init__.py to import from services package.

Impact: Improved maintainability, reduced max file size from 1,097
to 600 lines. Architecture quality improved from 7.5/10 to ~8.5/10.
2025-11-18 20:07:05 +00:00