Skip to content

fix: implement missing "timeseries" PV forecast source dispatch - #271

Merged
ohAnd merged 1 commit into
ohAnd:developfrom
muxodo:fix/timeseries-pv-source
Jul 13, 2026
Merged

fix: implement missing "timeseries" PV forecast source dispatch#271
ohAnd merged 1 commit into
ohAnd:developfrom
muxodo:fix/timeseries-pv-source

Conversation

@muxodo

@muxodo muxodo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

pv_forecast_source.source: timeseries was accepted by config validation and configurable in the UI (data_url, data_path, data_token), but PvInterface.__get_pv_forecast() had no case for it, silently falling back to the synthetic default triangle forecast instead of fetching data_url.

Adds __get_pv_forecast_timeseries(), reusing the same standardized [{start, end, value}] format PriceInterface's timeseries source already uses, with a PV-appropriate twist: 15-min-to-hourly conversion sums (not averages, since values are energy-per-slot rather than a rate), and incomplete data pads with 0 instead of the last known value.

Fetched once globally (not per pv_forecast.N array entry) and aligned by absolute "start" timestamp to a midnight-anchored slot grid - both match __get_pv_forecast_evcc_api's existing behaviour, and are required because get_ems_data() in eos_connect.py indexes pv_forcast_array by slots-since-midnight-today, not by position.

Tested against a self-hosted forecast service returning real 15-minute-resolution PV data; verified end to end against the running optimizer (matching totals between the service and EOS_connect's own computed values).

Fixes #270

pv_forecast_source.source: timeseries was accepted by config validation
and configurable in the UI (data_url, data_path, data_token), but
PvInterface.__get_pv_forecast() had no case for it, silently falling
back to the synthetic default triangle forecast instead of fetching
data_url.

Adds __get_pv_forecast_timeseries(), reusing the same standardized
[{start, end, value}] format PriceInterface's timeseries source already
uses, with a PV-appropriate twist: 15-min-to-hourly conversion sums
(not averages, since values are energy-per-slot rather than a rate),
and incomplete data pads with 0 instead of the last known value.

Fetched once globally (not per pv_forecast.N array entry) and aligned
by absolute "start" timestamp to a midnight-anchored slot grid - both
match __get_pv_forecast_evcc_api's existing behaviour, and are required
because get_ems_data() in eos_connect.py indexes pv_forcast_array by
slots-since-midnight-today, not by position.

Tested against a self-hosted forecast service returning real
15-minute-resolution PV data; verified end to end against the running
optimizer (matching totals between the service and EOS_connect's own
computed values).
ohAnd added a commit that referenced this pull request Jul 13, 2026
Enhance timeseries PV forecast handling to be truly robust:

Robustness improvement:
- Timestamps now aligned to resolution boundaries before slot lookup
- Handles data starting at midnight, "now", or any arbitrary time
- Maintains midnight-indexed output for optimizer compatibility
- Fixes silent data loss when HA templates generated "now"-aligned slots

Original implementation:
- HTTP fetch with Bearer token auth, 3-retry mechanism
- Auto-detect 15min vs hourly resolution
- 15-to-60min conversion via energy summing
- Validation at startup (data_url checks, URL format)
- Context-aware error messages with recovery status
- Diagnostic logging (entry counts, value ranges, failure hints)

Test coverage:
- 15 parsing tests (format, resolution, alignment)
- 8 validation tests (config scenarios, URL validation)
- 45 existing PV tests (no regressions)
- Full 988-test suite passing

Fixes: #270
Related: #271
@ohAnd
ohAnd merged commit 97ee9ba into ohAnd:develop Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants