Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Scheduling] convert the units of inflexible power sensors MW #1007

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ New features

* Add command ``flexmeasures edit transfer-ownership`` to transfer the ownership of an asset and its children from one account to another[see `PR #983 <https://github.com/FlexMeasures/flexmeasures/pull/983>`_]
* Support defining the ``site-power-capacity``, ``site-consumption-capacity`` and ``site-production-capacity`` as a sensor in the API and CLI [see `PR #985 <https://github.com/FlexMeasures/flexmeasures/pull/985>`_]
* Support defining inflexible power sensors with arbitrary power and energy units [see `PR #1007 <https://github.com/FlexMeasures/flexmeasures/pull/1007>`_]
* Support saving beliefs with a ``belief_horizon`` in the ``PandasReporter``[see `PR #1013 <https://github.com/FlexMeasures/flexmeasures/pull/1013>`_]
* Skip the check of the output event resolution in any ``Reporter`` with the field ``check_output_resolution`` [see `PR #1009 <https://github.com/FlexMeasures/flexmeasures/pull/1009>`_]

Bugfixes
-----------

* Use minimum event resolution of the input (instead of the output) sensors for the belief search parameters [see `PR #1010 <https://github.com/FlexMeasures/flexmeasures/pull/1010>`_]


Expand Down
2 changes: 1 addition & 1 deletion documentation/features/scheduling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ With the flexibility context, we aim to describe the system in which the flexibl
- Description
* - ``inflexible-device-sensors``
- ``[3,4]``
- Power sensors that are relevant, but not flexible, such as a sensor recording rooftop solar power connected behind the main meter, whose production falls under the same contract as the flexible device(s) being scheduled. * Note:* For now, the inflexible-device-sensors need to have MW units.
- Power sensors that are relevant, but not flexible, such as a sensor recording rooftop solar power connected behind the main meter, whose production falls under the same contract as the flexible device(s) being scheduled.
* - ``consumption-price-sensor``
- ``5``
- The sensor that defines the price of consuming energy. This sensor can be recording market prices, but also CO₂ - whatever fits your optimization problem.
Expand Down
6 changes: 3 additions & 3 deletions flexmeasures/data/models/planning/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def inflexible_devices(db, building) -> dict[str, Sensor]:
name="PV power sensor",
generic_asset=building,
event_resolution=timedelta(hours=1),
unit="kW",
unit="MW",
attributes={"capacity_in_mw": 2},
)
db.session.add(pv_sensor)
Expand Down Expand Up @@ -186,9 +186,9 @@ def add_inflexible_device_forecasts(
) * (len(time_slots) // (24 * 4))
add_as_beliefs(db, pv_sensor, pv_values, time_slots, setup_sources["Seita"])

# Residual demand (1 MW continuously)
# Residual demand (1 MW = 1000 kW continuously)
residual_demand_sensor = inflexible_devices["residual demand power sensor"]
residual_demand_values = [-1] * len(time_slots)
residual_demand_values = [-1000] * len(time_slots)
add_as_beliefs(
db,
residual_demand_sensor,
Expand Down
15 changes: 13 additions & 2 deletions flexmeasures/data/models/planning/tests/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
integrate_time_series,
)
from flexmeasures.tests.utils import get_test_sensor

from flexmeasures.utils.unit_utils import convert_units

TOLERANCE = 0.00001

Expand Down Expand Up @@ -586,9 +586,20 @@ def test_building_solver_day_2(
with pd.option_context("display.max_rows", None, "display.max_columns", 3):
print(soc_schedule)

unit_factors = np.expand_dims(
[
convert_units(1, s.unit, "MW")
for s in add_inflexible_device_forecasts.keys()
],
axis=1,
)
inflexible_devices_power = np.array(list(add_inflexible_device_forecasts.values()))

# Check if constraints were met
capacity = pd.DataFrame(
data=np.sum(np.array(list(add_inflexible_device_forecasts.values())), axis=0),
data=inflexible_devices_power.T.dot(
unit_factors
), # convert to MW and sum column-wise
columns=["inflexible"],
).tail(
-4 * 24
Expand Down
8 changes: 5 additions & 3 deletions flexmeasures/data/models/planning/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def get_power_values(
beliefs_before: datetime | None,
sensor: Sensor,
) -> np.ndarray:
"""Get measurements or forecasts of an inflexible device represented by a power sensor.
"""Get measurements or forecasts of an inflexible device represented by a power or energy sensor as an array of power values in MW.

If the requested schedule lies in the future, the returned data will consist of (the most recent) forecasts (if any exist).
If the requested schedule lies in the past, the returned data will consist of (the most recent) measurements (if any exist).
Expand Down Expand Up @@ -208,12 +208,14 @@ def get_power_values(
)
df = df.fillna(0)

series = convert_units(df.values, sensor.unit, "MW")

if sensor.get_attribute(
"consumption_is_positive", False
): # FlexMeasures default is to store consumption as negative power values
return df.values
return series

return -df.values
return -series


def fallback_charging_policy(
Expand Down
Loading