mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-07-19 08:18:50 +00:00
feat: add cloud PV forecast providers: pvnode.com, forecast-solar and solcast (#1150)
Some checks failed
Bump Version / Bump Version Workflow (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
Some checks failed
Bump Version / Bump Version Workflow (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
This PR adds three native PV power forecast providers, giving operators more
cloud forecast sources to choose from via pvforecast.provider, alongside the
existing PVForecastAkkudoktor, PVForecastVrm and PVForecastImport:
PVForecastPVNode — native 15-minute forecasts from the pvnode.com
V2 API. Saved-site mode (GET /v2/forecast/{site_id}) where the operator enters their API key +
site id, or inline mode (POST /v2/forecast/inline) using the configured planes.
PVForecastForecastSolar — the free Forecast.Solar API (no key
required for the public endpoint). Multi-plane systems issue one request per plane and the
instantaneous powers are summed per timestamp.
PVForecastSolcast — the Solcast rooftop-site API (API key + resource id).
Implementation notes
All three populate the existing pvforecast_ac_power (and mirror pvforecast_dc_power)
prediction keys, so they slot into the optimizer unchanged.
Timezone handling: pvnode and Forecast.Solar return site-local wall-clock timestamps with an
IANA timezone field, which are resolved to absolute instants before resampling; Solcast returns
UTC period_end and is normalised to the period start.
Each provider follows the existing provider pattern (provider_id(), _request_forecast() with
@cache_in_file, _update_data()), is registered in pvforecast.py and prediction.py, and is
upstream-neutral.
Validation
27 unit tests (timezone resolution, null/zero handling, kW→W and period-start conversion,
azimuth conversion, multi-plane summation, request URL/auth, HTTP-error handling).
ruff check (F/D/S/bandit) and ruff format clean.
Each provider was additionally validated against its live API with a real plant, confirming
the response shapes (pvnode: 288 native 15-min slots; Forecast.Solar: instantaneous watts;
Solcast: kW estimates with period_end/PT30M).
Documentation
Provider descriptions and configuration examples added to docs/akkudoktoreos/prediction.md.
CHANGELOG.md entry under Unreleased.
Regenerated docs/_generated/configpvforecast.md and configexample.md.
Notes for reviewers
Forecast.Solar's free endpoint is rate-limited (12 req/hour) and Solcast's free tier limits daily
calls; both providers rely on the standard 1-hour cache_in_file TTL to stay within budget.
Authors:
The code is created by Christin. Only minor adaptions by Bobby.
Signed-off-by: Christin <info@bikinibottom.capital>
Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
Co-authored-by: Christin <info@bikinibottom.capital>
This commit is contained in:
@@ -187,7 +187,10 @@
|
||||
"provider": "PVForecastAkkudoktor",
|
||||
"provider_settings": {
|
||||
"PVForecastImport": null,
|
||||
"PVForecastVrm": null
|
||||
"PVForecastVrm": null,
|
||||
"PVForecastPVNode": null,
|
||||
"PVForecastForecastSolar": null,
|
||||
"PVForecastSolcast": null
|
||||
},
|
||||
"planes": [
|
||||
{
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
"provider": "PVForecastAkkudoktor",
|
||||
"provider_settings": {
|
||||
"PVForecastImport": null,
|
||||
"PVForecastVrm": null
|
||||
"PVForecastVrm": null,
|
||||
"PVForecastPVNode": null,
|
||||
"PVForecastForecastSolar": null,
|
||||
"PVForecastSolcast": null
|
||||
},
|
||||
"planes": [
|
||||
{
|
||||
@@ -96,7 +99,10 @@
|
||||
"provider": "PVForecastAkkudoktor",
|
||||
"provider_settings": {
|
||||
"PVForecastImport": null,
|
||||
"PVForecastVrm": null
|
||||
"PVForecastVrm": null,
|
||||
"PVForecastPVNode": null,
|
||||
"PVForecastForecastSolar": null,
|
||||
"PVForecastSolcast": null
|
||||
},
|
||||
"planes": [
|
||||
{
|
||||
@@ -148,6 +154,9 @@
|
||||
"providers": [
|
||||
"PVForecastAkkudoktor",
|
||||
"PVForecastVrm",
|
||||
"PVForecastPVNode",
|
||||
"PVForecastForecastSolar",
|
||||
"PVForecastSolcast",
|
||||
"PVForecastImport"
|
||||
],
|
||||
"planes_peakpower": [
|
||||
@@ -183,6 +192,105 @@
|
||||
```
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
### Common settings for the Solcast PV forecast provider
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
:::{table} pvforecast::provider_settings::PVForecastSolcast
|
||||
:widths: 10 10 5 5 30
|
||||
:align: left
|
||||
|
||||
| Name | Type | Read-Only | Default | Description |
|
||||
| ---- | ---- | --------- | ------- | ----------- |
|
||||
| api_key | `str` | `rw` | `` | Solcast API key (Bearer auth). Required. |
|
||||
| site_id | `str` | `rw` | `` | Solcast rooftop site (resource) id. Required. |
|
||||
:::
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
<!-- pyml disable no-emphasis-as-heading -->
|
||||
**Example Input/Output**
|
||||
<!-- pyml enable no-emphasis-as-heading -->
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
```json
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider_settings": {
|
||||
"PVForecastSolcast": {
|
||||
"api_key": "your-solcast-key",
|
||||
"site_id": "abcd-1234-efgh-5678"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
### Common settings for the Forecast.Solar PV forecast provider
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
:::{table} pvforecast::provider_settings::PVForecastForecastSolar
|
||||
:widths: 10 10 5 5 30
|
||||
:align: left
|
||||
|
||||
| Name | Type | Read-Only | Default | Description |
|
||||
| ---- | ---- | --------- | ------- | ----------- |
|
||||
| api_key | `Optional[str]` | `rw` | `None` | Forecast.Solar API key. Optional — the public endpoint works without a key (lower rate limit). |
|
||||
:::
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
<!-- pyml disable no-emphasis-as-heading -->
|
||||
**Example Input/Output**
|
||||
<!-- pyml enable no-emphasis-as-heading -->
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
```json
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider_settings": {
|
||||
"PVForecastForecastSolar": {
|
||||
"api_key": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
### Common settings for the pvnode.com PV forecast provider
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
:::{table} pvforecast::provider_settings::PVForecastPVNode
|
||||
:widths: 10 10 5 5 30
|
||||
:align: left
|
||||
|
||||
| Name | Type | Read-Only | Default | Description |
|
||||
| ---- | ---- | --------- | ------- | ----------- |
|
||||
| api_key | `str` | `rw` | `` | pvnode.com API key (Bearer auth). Required. |
|
||||
| forecast_days | `int` | `rw` | `2` | Forecast horizon in days (1-7, capped by the pvnode plan). |
|
||||
| site_id | `Optional[str]` | `rw` | `None` | pvnode.com site id of the saved plant ('Anlagen-ID'). When set, the saved (possibly calibrated) site is used. Leave empty to send the configured pvforecast.planes inline instead. |
|
||||
:::
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
<!-- pyml disable no-emphasis-as-heading -->
|
||||
**Example Input/Output**
|
||||
<!-- pyml enable no-emphasis-as-heading -->
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
```json
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider_settings": {
|
||||
"PVForecastPVNode": {
|
||||
"api_key": "pvn_live_xxxxxxxxxxxxxxxx",
|
||||
"site_id": "abcd-1234",
|
||||
"forecast_days": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
### Common settings for PV forecast VRM API
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
@@ -258,7 +366,10 @@
|
||||
|
||||
| Name | Type | Read-Only | Default | Description |
|
||||
| ---- | ---- | --------- | ------- | ----------- |
|
||||
| PVForecastForecastSolar | `Optional[akkudoktoreos.prediction.pvforecastforecastsolar.PVForecastForecastSolarCommonSettings]` | `rw` | `None` | PVForecastForecastSolar settings |
|
||||
| PVForecastImport | `Optional[akkudoktoreos.prediction.pvforecastimport.PVForecastImportCommonSettings]` | `rw` | `None` | PVForecastImport settings |
|
||||
| PVForecastPVNode | `Optional[akkudoktoreos.prediction.pvforecastpvnode.PVForecastPVNodeCommonSettings]` | `rw` | `None` | PVForecastPVNode settings |
|
||||
| PVForecastSolcast | `Optional[akkudoktoreos.prediction.pvforecastsolcast.PVForecastSolcastCommonSettings]` | `rw` | `None` | PVForecastSolcast settings |
|
||||
| PVForecastVrm | `Optional[akkudoktoreos.prediction.pvforecastvrm.PVForecastVrmCommonSettings]` | `rw` | `None` | PVForecastVrm settings |
|
||||
:::
|
||||
<!-- pyml enable line-length -->
|
||||
@@ -273,7 +384,10 @@
|
||||
"pvforecast": {
|
||||
"provider_settings": {
|
||||
"PVForecastImport": null,
|
||||
"PVForecastVrm": null
|
||||
"PVForecastVrm": null,
|
||||
"PVForecastPVNode": null,
|
||||
"PVForecastForecastSolar": null,
|
||||
"PVForecastSolcast": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Akkudoktor-EOS
|
||||
|
||||
**Version**: `v0.3.0.dev2607161418098328`
|
||||
**Version**: `v0.3.0.dev2607161979035365`
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
**Description**: This project provides a comprehensive solution for simulating and optimizing an energy system based on renewable energy sources. With a focus on photovoltaic (PV) systems, battery storage (batteries), load management (consumer requirements), heat pumps, electric vehicles, and consideration of electricity price data, this system enables forecasting and optimization of energy flow and costs over a specified period.
|
||||
|
||||
@@ -373,6 +373,9 @@ Configuration options:
|
||||
|
||||
- `PVForecastAkkudoktor`: Retrieves from Akkudoktor.net.
|
||||
- `PVForecastVrm`: Retrieves data from the VRM API by Victron Energy.
|
||||
- `PVForecastPVNode`: Retrieves native 15-minute forecasts from the pvnode.com API.
|
||||
- `PVForecastForecastSolar`: Retrieves forecasts from the free Forecast.Solar API.
|
||||
- `PVForecastSolcast`: Retrieves forecasts from the Solcast rooftop-site API.
|
||||
- `PVForecastImport`: Imports from a file or JSON string or by endpoint data provision.
|
||||
|
||||
- `planes[].surface_tilt`: Tilt angle from horizontal plane. Ignored for two-axis tracking.
|
||||
@@ -401,6 +404,12 @@ Configuration options:
|
||||
- `planes[].strings_per_inverter`: Number of the strings of the inverter of this plane.
|
||||
- `provider_settings.import_file_path`: Path to the file to import PV forecast data from.
|
||||
- `provider_settings.import_json`: JSON string, dictionary of PV forecast value lists.
|
||||
- `provider_settings.PVForecastPVNode.api_key`: pvnode.com API key.
|
||||
- `provider_settings.PVForecastPVNode.site_id`: pvnode.com saved-site id. Leave empty for inline mode.
|
||||
- `provider_settings.PVForecastPVNode.forecast_days`: Forecast horizon in days (1-7).
|
||||
- `provider_settings.PVForecastForecastSolar.api_key`: Forecast.Solar API key (optional).
|
||||
- `provider_settings.PVForecastSolcast.api_key`: Solcast API key.
|
||||
- `provider_settings.PVForecastSolcast.site_id`: Solcast rooftop resource (site) id.
|
||||
|
||||
---
|
||||
|
||||
@@ -604,6 +613,84 @@ The PV forecast data must be provided in one of the formats described in
|
||||
The data may additionally or solely be provided by the
|
||||
**PUT** `/v1/prediction/import/PVForecastImport` endpoint.
|
||||
|
||||
### PVForecastPVNode Provider
|
||||
|
||||
The `PVForecastPVNode` provider retrieves native 15-minute PV power forecasts from the
|
||||
[pvnode.com](https://pvnode.com) V2 API. Register a site in the pvnode web app and store the API
|
||||
key together with the site id in the EOS configuration (saved-site mode). Alternatively, leave the
|
||||
site id empty to send the configured `planes` geometry inline.
|
||||
|
||||
```python
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider": "PVForecastPVNode",
|
||||
"provider_settings": {
|
||||
"PVForecastPVNode": {
|
||||
"api_key": "your-pvnode-key",
|
||||
"site_id": "your-site-id",
|
||||
"forecast_days": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The prediction keys for the PV forecast data are:
|
||||
|
||||
- `pvforecast_ac_power`: Total AC power (W).
|
||||
- `pvforecast_dc_power`: Total DC power (W).
|
||||
|
||||
### PVForecastForecastSolar Provider
|
||||
|
||||
The `PVForecastForecastSolar` provider retrieves PV power forecasts from the free
|
||||
[Forecast.Solar](https://forecast.solar) API. No API key is required for the public endpoint; an
|
||||
optional key raises the rate limit. The location is taken from `general.latitude`/`longitude` and
|
||||
the system geometry from the configured `planes` (one request per plane, summed per timestamp).
|
||||
|
||||
```python
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider": "PVForecastForecastSolar",
|
||||
"provider_settings": {
|
||||
"PVForecastForecastSolar": {
|
||||
"api_key": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The prediction keys for the PV forecast data are:
|
||||
|
||||
- `pvforecast_ac_power`: Total AC power (W).
|
||||
- `pvforecast_dc_power`: Total DC power (W).
|
||||
|
||||
### PVForecastSolcast Provider
|
||||
|
||||
The `PVForecastSolcast` provider retrieves PV power forecasts from the
|
||||
[Solcast](https://solcast.com) rooftop-site API. Register a rooftop site in the Solcast web app and
|
||||
store the API key together with the resource (site) id in the EOS configuration. Note that the free
|
||||
tier limits the number of API calls per day.
|
||||
|
||||
```python
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider": "PVForecastSolcast",
|
||||
"provider_settings": {
|
||||
"PVForecastSolcast": {
|
||||
"api_key": "your-solcast-key",
|
||||
"site_id": "your-resource-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The prediction keys for the PV forecast data are:
|
||||
|
||||
- `pvforecast_ac_power`: Total AC power (W).
|
||||
- `pvforecast_dc_power`: Total DC power (W).
|
||||
|
||||
## Weather Prediction
|
||||
|
||||
Prediction keys:
|
||||
|
||||
Reference in New Issue
Block a user