Add SMARD quarter-hour price provider

This commit is contained in:
Andreas
2026-08-01 12:21:06 +02:00
parent f7e2ac3619
commit 69ef57d9c9
18 changed files with 1126 additions and 72 deletions
+131
View File
@@ -7,12 +7,15 @@
| Name | Environment Variable | Type | Read-Only | Default | Description |
| ---- | -------------------- | ---- | --------- | ------- | ----------- |
| charge_components_kwh | `EOS_ELECPRICE__CHARGE_COMPONENTS_KWH` | `dict[str, Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0)])]]` | `rw` | `required` | Named constant net charge components [€/kWh]. Their sum is added to charges_kwh, variable network fees, and the market price. |
| charges_kwh | `EOS_ELECPRICE__CHARGES_KWH` | `Optional[float]` | `rw` | `None` | Electricity price charges [€/kWh]. Will be added to variable market price. |
| elecpricefixed | `EOS_ELECPRICE__ELECPRICEFIXED` | `ElecPriceFixedCommonSettings` | `rw` | `required` | Fixed electricity price provider settings. |
| elecpriceimport | `EOS_ELECPRICE__ELECPRICEIMPORT` | `ElecPriceImportCommonSettings` | `rw` | `required` | Import provider settings. |
| energycharts | `EOS_ELECPRICE__ENERGYCHARTS` | `ElecPriceEnergyChartsCommonSettings` | `rw` | `required` | Energy Charts provider settings. |
| network_fees_kwh | `EOS_ELECPRICE__NETWORK_FEES_KWH` | `ValueTimeWindowSequence` | `rw` | `required` | Recurring time windows for variable network fees [€/kWh, net]. The first matching window is added to charges_kwh and the market price. |
| provider | `EOS_ELECPRICE__PROVIDER` | `Optional[str]` | `rw` | `None` | Electricity price provider id of provider to be used. |
| providers | | `list[str]` | `ro` | `N/A` | Available electricity price provider ids. |
| smard | `EOS_ELECPRICE__SMARD` | `ElecPriceSMARDCommonSettings` | `rw` | `required` | Direct SMARD electricity price provider settings. |
| tibber | `EOS_ELECPRICE__TIBBER` | `ElecPriceTibberCommonSettings` | `rw` | `required` | Tibber electricity price provider settings. |
| vat_rate | `EOS_ELECPRICE__VAT_RATE` | `Optional[float]` | `rw` | `1.19` | VAT rate factor applied to electricity price when charges are used. |
:::
@@ -44,6 +47,54 @@
"tibber": {
"access_token": null,
"home_id": null
},
"charge_components_kwh": {
"electricity_tax": 0.0205,
"concession_fee": 0.0132,
"kwkg_levy": 0.00446,
"section_19_levy": 0.01559,
"offshore_grid_levy": 0.00941,
"supplier_markup": 0.0
},
"smard": {
"filter_id": 4169,
"region": "DE"
},
"network_fees_kwh": {
"windows": [
{
"start_time": "00:00:00.000000",
"duration": "7 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0095
},
{
"start_time": "07:00:00.000000",
"duration": "8 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
},
{
"start_time": "15:00:00.000000",
"duration": "5 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.1565
},
{
"start_time": "20:00:00.000000",
"duration": "4 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
}
]
}
}
}
@@ -77,9 +128,58 @@
"access_token": null,
"home_id": null
},
"charge_components_kwh": {
"electricity_tax": 0.0205,
"concession_fee": 0.0132,
"kwkg_levy": 0.00446,
"section_19_levy": 0.01559,
"offshore_grid_levy": 0.00941,
"supplier_markup": 0.0
},
"smard": {
"filter_id": 4169,
"region": "DE"
},
"network_fees_kwh": {
"windows": [
{
"start_time": "00:00:00.000000",
"duration": "7 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0095
},
{
"start_time": "07:00:00.000000",
"duration": "8 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
},
{
"start_time": "15:00:00.000000",
"duration": "5 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.1565
},
{
"start_time": "20:00:00.000000",
"duration": "4 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
}
]
},
"providers": [
"ElecPriceAkkudoktor",
"ElecPriceEnergyCharts",
"ElecPriceSMARD",
"ElecPriceTibber",
"ElecPriceFixed",
"ElecPriceImport"
@@ -120,6 +220,37 @@
```
<!-- pyml enable line-length -->
### Common settings for the direct SMARD electricity-price provider
<!-- pyml disable line-length -->
:::{table} elecprice::smard
:widths: 10 10 5 5 30
:align: left
| Name | Type | Read-Only | Default | Description |
| ---- | ---- | --------- | ------- | ----------- |
| filter_id | `int` | `rw` | `4169` | SMARD filter id for the German/Luxembourg day-ahead price. |
| region | `str` | `rw` | `DE` | SMARD market region used in the chart-data endpoint. |
:::
<!-- pyml enable line-length -->
<!-- pyml disable no-emphasis-as-heading -->
**Example Input/Output**
<!-- pyml enable no-emphasis-as-heading -->
<!-- pyml disable line-length -->
```json
{
"elecprice": {
"smard": {
"filter_id": 4169,
"region": "DE"
}
}
}
```
<!-- pyml enable line-length -->
### Common settings for Energy Charts electricity price provider
<!-- pyml disable line-length -->
+53 -2
View File
@@ -114,6 +114,54 @@
"tibber": {
"access_token": null,
"home_id": null
},
"charge_components_kwh": {
"electricity_tax": 0.0205,
"concession_fee": 0.0132,
"kwkg_levy": 0.00446,
"section_19_levy": 0.01559,
"offshore_grid_levy": 0.00941,
"supplier_markup": 0.0
},
"smard": {
"filter_id": 4169,
"region": "DE"
},
"network_fees_kwh": {
"windows": [
{
"start_time": "00:00:00.000000",
"duration": "7 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0095
},
{
"start_time": "07:00:00.000000",
"duration": "8 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
},
{
"start_time": "15:00:00.000000",
"duration": "5 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.1565
},
{
"start_time": "20:00:00.000000",
"duration": "4 hours",
"day_of_week": null,
"date": null,
"locale": null,
"value": 0.0953
}
]
}
},
"ems": {
@@ -123,11 +171,14 @@
},
"feedintariff": {
"direct_marketing_enabled": false,
"provider": "FeedInTariffFixed",
"provider": "FeedInTariffAkkudoktor",
"provider_settings": {
"FeedInTariffAkkudoktor": null,
"FeedInTariffFixed": null,
"FeedInTariffEnergyCharts": null,
"FeedInTariffImport": null
"FeedInTariffImport": null,
"FeedInTariffTibber": null,
"FeedInTariffSMARD": null
}
},
"general": {
+117 -11
View File
@@ -23,11 +23,14 @@
{
"feedintariff": {
"direct_marketing_enabled": false,
"provider": "FeedInTariffFixed",
"provider": "FeedInTariffAkkudoktor",
"provider_settings": {
"FeedInTariffAkkudoktor": null,
"FeedInTariffFixed": null,
"FeedInTariffEnergyCharts": null,
"FeedInTariffImport": null
"FeedInTariffImport": null,
"FeedInTariffTibber": null,
"FeedInTariffSMARD": null
}
}
}
@@ -43,22 +46,87 @@
{
"feedintariff": {
"direct_marketing_enabled": false,
"provider": "FeedInTariffFixed",
"provider": "FeedInTariffAkkudoktor",
"provider_settings": {
"FeedInTariffAkkudoktor": null,
"FeedInTariffFixed": null,
"FeedInTariffEnergyCharts": null,
"FeedInTariffImport": null
"FeedInTariffImport": null,
"FeedInTariffTibber": null,
"FeedInTariffSMARD": null
},
"providers": [
"FeedInTariffEnergyCharts",
"FeedInTariffAkkudoktor",
"FeedInTariffFixed",
"FeedInTariffImport"
"FeedInTariffImport",
"FeedInTariffSMARD",
"FeedInTariffTibber"
]
}
}
```
<!-- pyml enable line-length -->
### Settings for SMARD feed-in prices shared with ``elecprice.smard``
<!-- pyml disable line-length -->
:::{table} feedintariff::provider_settings::FeedInTariffSMARD
:widths: 10 10 5 5 30
:align: left
| Name | Type | Read-Only | Default | Description |
| ---- | ---- | --------- | ------- | ----------- |
:::
<!-- pyml enable line-length -->
<!-- pyml disable no-emphasis-as-heading -->
**Example Input/Output**
<!-- pyml enable no-emphasis-as-heading -->
<!-- pyml disable line-length -->
```json
{
"feedintariff": {
"provider_settings": {
"FeedInTariffSMARD": {}
}
}
}
```
<!-- pyml enable line-length -->
### Settings for the Tibber feed-in tariff provider
Authentication is shared with ``elecprice.tibber`` so the access token and
home id do not have to be configured twice.
<!-- pyml disable line-length -->
:::{table} feedintariff::provider_settings::FeedInTariffTibber
:widths: 10 10 5 5 30
:align: left
| Name | Type | Read-Only | Default | Description |
| ---- | ---- | --------- | ------- | ----------- |
:::
<!-- pyml enable line-length -->
<!-- pyml disable no-emphasis-as-heading -->
**Example Input/Output**
<!-- pyml enable no-emphasis-as-heading -->
<!-- pyml disable line-length -->
```json
{
"feedintariff": {
"provider_settings": {
"FeedInTariffTibber": {}
}
}
}
```
<!-- pyml enable line-length -->
### Common settings for feed in tariff data import from file or JSON string
<!-- pyml disable line-length -->
@@ -154,18 +222,19 @@
```
<!-- pyml enable line-length -->
### Feed In Tariff Prediction Provider Configuration
### Settings for the Akkudoktor feed-in tariff provider
The public Akkudoktor price endpoint only needs the timezone already
configured in ``general.timezone``, so no provider-specific values are
currently required.
<!-- pyml disable line-length -->
:::{table} feedintariff::provider_settings
:::{table} feedintariff::provider_settings::FeedInTariffAkkudoktor
:widths: 10 10 5 5 30
:align: left
| Name | Type | Read-Only | Default | Description |
| ---- | ---- | --------- | ------- | ----------- |
| FeedInTariffEnergyCharts | `Optional[akkudoktoreos.prediction.feedintariffenergycharts.FeedInTariffEnergyChartsCommonSettings]` | `rw` | `None` | FeedInTariffEnergyCharts settings |
| FeedInTariffFixed | `Optional[akkudoktoreos.prediction.feedintarifffixed.FeedInTariffFixedCommonSettings]` | `rw` | `None` | FeedInTariffFixed settings |
| FeedInTariffImport | `Optional[akkudoktoreos.prediction.feedintariffimport.FeedInTariffImportCommonSettings]` | `rw` | `None` | FeedInTariffImport settings |
:::
<!-- pyml enable line-length -->
@@ -178,9 +247,46 @@
{
"feedintariff": {
"provider_settings": {
"FeedInTariffAkkudoktor": {}
}
}
}
```
<!-- pyml enable line-length -->
### Feed In Tariff Prediction Provider Configuration
<!-- pyml disable line-length -->
:::{table} feedintariff::provider_settings
:widths: 10 10 5 5 30
:align: left
| Name | Type | Read-Only | Default | Description |
| ---- | ---- | --------- | ------- | ----------- |
| FeedInTariffAkkudoktor | `Optional[akkudoktoreos.prediction.feedintariffakkudoktor.FeedInTariffAkkudoktorCommonSettings]` | `rw` | `None` | FeedInTariffAkkudoktor settings |
| FeedInTariffEnergyCharts | `Optional[akkudoktoreos.prediction.feedintariffenergycharts.FeedInTariffEnergyChartsCommonSettings]` | `rw` | `None` | FeedInTariffEnergyCharts settings |
| FeedInTariffFixed | `Optional[akkudoktoreos.prediction.feedintarifffixed.FeedInTariffFixedCommonSettings]` | `rw` | `None` | FeedInTariffFixed settings |
| FeedInTariffImport | `Optional[akkudoktoreos.prediction.feedintariffimport.FeedInTariffImportCommonSettings]` | `rw` | `None` | FeedInTariffImport settings |
| FeedInTariffSMARD | `Optional[akkudoktoreos.prediction.feedintariffsmard.FeedInTariffSMARDCommonSettings]` | `rw` | `None` | FeedInTariffSMARD settings |
| FeedInTariffTibber | `Optional[akkudoktoreos.prediction.feedintarifftibber.FeedInTariffTibberCommonSettings]` | `rw` | `None` | FeedInTariffTibber settings |
:::
<!-- pyml enable line-length -->
<!-- pyml disable no-emphasis-as-heading -->
**Example Input/Output**
<!-- pyml enable no-emphasis-as-heading -->
<!-- pyml disable line-length -->
```json
{
"feedintariff": {
"provider_settings": {
"FeedInTariffAkkudoktor": null,
"FeedInTariffFixed": null,
"FeedInTariffEnergyCharts": null,
"FeedInTariffImport": null
"FeedInTariffImport": null,
"FeedInTariffTibber": null,
"FeedInTariffSMARD": null
}
}
}
+4 -2
View File
@@ -1,6 +1,6 @@
# Akkudoktor-EOS
**Version**: `v0.3.0.dev2607071966322885`
**Version**: `v0.3.0.dev2608010951962828`
<!-- 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.
@@ -122,7 +122,9 @@ Note:
- `start_hour` (query, optional): Defaults to current hour of the day.
- `ngen` (query, optional): Number of indivuals to generate for genetic algorithm.
- `ngen` (query, optional): Deprecated alias for the number of genetic generations. Defaults to optimization.genetic.generations.
- `individuals` (query, optional): Override optimization.genetic.individuals for this run.
**Request Body**:
+26 -3
View File
@@ -136,10 +136,13 @@ Configuration options:
- `ElecPriceAkkudoktor`: Retrieves from Akkudoktor.net.
- `ElecPriceEnergyCharts`: Retrieves from Energy-Charts.info.
- `ElecPriceSMARD`: Retrieves German/Luxembourg day-ahead prices directly from SMARD.de.
- `ElecPriceFixed`: Caluclates from configured time window prices.
- `ElecPriceImport`: Imports from a file or JSON string or by endpoint data provision.
- `charges_kwh`: Electricity price charges (€/kWh).
- `charge_components_kwh`: Named constant net-charge components (€/kWh), summed automatically.
- `network_fees_kwh.windows`: Recurring time windows with variable net-grid fees (€/kWh).
- `vat_rate`: VAT rate factor applied to electricity price when charges are used (default: 1.19).
- `elecpricefixed.time_windows.windows`: The time windows with associated electricity prices.
- `elecpriceimport.import_file_path`: Path to the file to import electricity price forecast data from.
@@ -166,12 +169,32 @@ forecasting by combining real-time market data with historical price trends.
Charges and VAT
- If `charges_kwh` configuration option is greater than 0, the electricity price is calculated as:
`(market price + charges_kwh) * vat_rate` where `vat_rate` is configurable (default: 1.19 for 19% VAT).
- If `charges_kwh` is set to 0, the electricity price is simply: `market_price` (no VAT applied).
- If constant charges or a matching `network_fees_kwh` window is greater than 0, the electricity
price is calculated as: `(market price + charges_kwh + sum(charge components) + network fee)
* vat_rate` where
`vat_rate` is configurable (default: 1.19 for 19% VAT).
- If all constant charges and network-fee windows are empty or zero, the electricity price is
simply `market_price` (no VAT applied, preserving the existing raw-market-price behaviour).
`charges_kwh`, every `charge_components_kwh` value, and `network_fees_kwh` are net values. Time
windows repeat daily unless their optional `date` or `day_of_week` constraints are set. The first
matching window is used. Named components make statutory levies and the supplier markup auditable
instead of hiding them in one aggregate. The supplier-specific markup defaults to zero in the
example and must be taken from the electricity supply contract.
**Note:** For the most accurate forecasts, it is recommended to set the `historic_hours` parameter to 840.
### ElecPriceSMARD Provider
The `ElecPriceSMARD` provider retrieves quarter-hourly German/Luxembourg day-ahead prices directly from
the public SMARD chart-data endpoint. It requests the required weekly chunks only and caches the
combined response for one hour. Missing quarter-hour slots beyond the published day-ahead horizon are generated
with the same daily or weekly seasonal ETS forecast as the Energy-Charts provider. Constant charges,
time-variable network fees, and VAT are applied after forecasting the underlying market price.
The same raw SMARD series is also available as `FeedInTariffSMARD` for direct-marketing feed-in
revenue. Import-only charges, network fees, and VAT are deliberately not applied there.
### ElecPriceFixed Provider
The `ElecPriceFixed` provider calculates the day-ahead electricity market prices from the configuration