fix: price interpolation (#1154)

Use forward fill to interpolate time series data that represents prices:
- elecprice_marketprice_wh
- feed_in_tariff_wh

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
Bobby Noelte
2026-07-17 18:05:29 +02:00
committed by GitHub
parent 75548990e1
commit 4381948f13
11 changed files with 19 additions and 9 deletions

2
.env
View File

@@ -11,7 +11,7 @@ DOCKER_COMPOSE_DATA_DIR=${HOME}/.local/share/net.akkudoktor.eos
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Image / build # Image / build
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
VERSION=0.3.0.dev2607161979035365 VERSION=0.3.0.dev2607171078037437
PYTHON_VERSION=3.13.9 PYTHON_VERSION=3.13.9
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------

View File

@@ -6,7 +6,7 @@
# the root directory (no add-on folder as usual). # the root directory (no add-on folder as usual).
name: "Akkudoktor-EOS" name: "Akkudoktor-EOS"
version: "0.3.0.dev2607161979035365" version: "0.3.0.dev2607171078037437"
slug: "eos" slug: "eos"
description: "Akkudoktor-EOS add-on" description: "Akkudoktor-EOS add-on"
url: "https://github.com/Akkudoktor-EOS/EOS" url: "https://github.com/Akkudoktor-EOS/EOS"

View File

@@ -1,6 +1,6 @@
# Akkudoktor-EOS # Akkudoktor-EOS
**Version**: `v0.3.0.dev2607161979035365` **Version**: `v0.3.0.dev2607171078037437`
<!-- pyml disable line-length --> <!-- 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. **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.

View File

@@ -8,7 +8,7 @@
"name": "Apache 2.0", "name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html" "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
}, },
"version": "v0.3.0.dev2607161979035365" "version": "v0.3.0.dev2607171078037437"
}, },
"paths": { "paths": {
"/v1/admin/cache/clear": { "/v1/admin/cache/clear": {

View File

@@ -582,7 +582,7 @@ class GeneticSolution(ConfigMixin, GeneticParametersBaseModel):
), ),
( (
"feed_in_tariff_wh", "feed_in_tariff_wh",
"linear", "ffill",
"feed_in_tariff_amt_kwh", "feed_in_tariff_amt_kwh",
1000.0, 1000.0,
), ),

View File

@@ -1203,6 +1203,7 @@ async def fastapi_strompreis() -> list[float]:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=start_datetime, start_datetime=start_datetime,
end_datetime=end_datetime, end_datetime=end_datetime,
fill_method="ffill",
) )
elecprice_list = elecprice_array.tolist() elecprice_list = elecprice_array.tolist()
except Exception as e: except Exception as e:

View File

@@ -153,6 +153,7 @@ async def prepare_optimization_real_parameters() -> GeneticOptimizationParameter
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=prediction_eos.ems_start_datetime, start_datetime=prediction_eos.ems_start_datetime,
end_datetime=prediction_eos.end_datetime, end_datetime=prediction_eos.end_datetime,
fill_method="ffill",
) )
print(f"strompreis_euro_pro_wh: {strompreis_euro_pro_wh}") print(f"strompreis_euro_pro_wh: {strompreis_euro_pro_wh}")

View File

@@ -127,11 +127,12 @@ class TestElecPriceAkkudokor:
len(provider) == 73 len(provider) == 73
) # we have 48 datasets in the api response, we want to know 48h into the future. The data we get has already 23h into the future so we need only 25h more. 48+25=73 ) # we have 48 datasets in the api response, we want to know 48h into the future. The data we get has already 23h into the future so we need only 25h more. 48+25=73
# Assert we get hours prioce values by resampling # Assert we get hours price values by resampling
np_price_array = await provider.key_to_array( np_price_array = await provider.key_to_array(
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=provider.ems_start_datetime, start_datetime=provider.ems_start_datetime,
end_datetime=provider.end_datetime, end_datetime=provider.end_datetime,
fill_method="ffill",
) )
assert len(np_price_array) == provider.total_hours assert len(np_price_array) == provider.total_hours
@@ -204,6 +205,7 @@ class TestElecPriceAkkudokor:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=provider.ems_start_datetime, start_datetime=provider.ems_start_datetime,
end_datetime=provider.end_datetime, end_datetime=provider.end_datetime,
fill_method="ffill",
) )
assert isinstance(array, np.ndarray) assert isinstance(array, np.ndarray)
assert len(array) == provider.total_hours assert len(array) == provider.total_hours

View File

@@ -129,6 +129,7 @@ class TestElecPriceEnergyCharts:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=provider.ems_start_datetime, start_datetime=provider.ems_start_datetime,
end_datetime=provider.end_datetime, end_datetime=provider.end_datetime,
fill_method="ffill",
) )
assert len(np_price_array) == provider.total_hours assert len(np_price_array) == provider.total_hours
@@ -195,6 +196,7 @@ class TestElecPriceEnergyCharts:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=provider.ems_start_datetime, start_datetime=provider.ems_start_datetime,
end_datetime=provider.end_datetime, end_datetime=provider.end_datetime,
fill_method="ffill",
) )
assert isinstance(array, np.ndarray) assert isinstance(array, np.ndarray)
assert len(array) == provider.total_hours assert len(array) == provider.total_hours

View File

@@ -241,7 +241,8 @@ class TestElecPriceFixed:
hourly_array = await provider.key_to_array( hourly_array = await provider.key_to_array(
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=start_dt, start_datetime=start_dt,
end_datetime=start_dt.add(hours=24) end_datetime=start_dt.add(hours=24),
fill_method="ffill",
) )
assert len(hourly_array) == 24 assert len(hourly_array) == 24
@@ -253,7 +254,8 @@ class TestElecPriceFixed:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=start_dt, start_datetime=start_dt,
end_datetime=start_dt.add(hours=24), end_datetime=start_dt.add(hours=24),
interval="15 minutes" interval="15 minutes",
fill_method="ffill",
) )
assert len(quarter_hour_array) == 96 # 24 * 4 assert len(quarter_hour_array) == 96 # 24 * 4
@@ -266,7 +268,8 @@ class TestElecPriceFixed:
key="elecprice_marketprice_wh", key="elecprice_marketprice_wh",
start_datetime=start_dt, start_datetime=start_dt,
end_datetime=start_dt.add(hours=24), end_datetime=start_dt.add(hours=24),
interval="30 minutes" interval="30 minutes",
fill_method="ffill",
) )
assert len(half_hour_array) == 48 # 24 * 2 assert len(half_hour_array) == 48 # 24 * 2

View File

@@ -112,6 +112,7 @@ class TestElecPriceImport:
start_datetime=provider.ems_start_datetime, start_datetime=provider.ems_start_datetime,
end_datetime=provider.ems_start_datetime + to_duration(f"{len(expected_values)} hours"), end_datetime=provider.ems_start_datetime + to_duration(f"{len(expected_values)} hours"),
interval=to_duration("1 hour"), interval=to_duration("1 hour"),
fill_method="ffill",
) )
# Allow for some difference due to value calculation on DST change # Allow for some difference due to value calculation on DST change
npt.assert_allclose(result_values, expected_values, rtol=0.001) npt.assert_allclose(result_values, expected_values, rtol=0.001)