diff --git a/flexmeasures/api/v3_0/tests/test_sensor_schedules_fresh_db.py b/flexmeasures/api/v3_0/tests/test_sensor_schedules_fresh_db.py index c7450e9a81..bc24638294 100644 --- a/flexmeasures/api/v3_0/tests/test_sensor_schedules_fresh_db.py +++ b/flexmeasures/api/v3_0/tests/test_sensor_schedules_fresh_db.py @@ -329,6 +329,7 @@ def test_inflexible_device_sensors_priority( fresh_db, add_market_prices_fresh_db, add_battery_assets_fresh_db, + setup_fresh_test_forecast_data, battery_soc_sensor_fresh_db, add_charging_station_assets_fresh_db, keep_scheduling_queue_empty, @@ -346,6 +347,9 @@ def test_inflexible_device_sensors_priority( "consumption-price": {"sensor": price_sensor_id}, "production-price": {"sensor": price_sensor_id}, "site-power-capacity": "1 TW", # should be big enough to avoid any infeasibilities + "curtailable-device-sensors": [ + setup_fresh_test_forecast_data["solar-sensor"].id + ], } if context_sensor_num: other_asset = add_battery_assets_fresh_db["Test small battery"] diff --git a/flexmeasures/data/schemas/scheduling/__init__.py b/flexmeasures/data/schemas/scheduling/__init__.py index 78d067a858..b6042d71a8 100644 --- a/flexmeasures/data/schemas/scheduling/__init__.py +++ b/flexmeasures/data/schemas/scheduling/__init__.py @@ -304,6 +304,12 @@ class FlexContextSchema(Schema): metadata=metadata.AGGREGATE_POWER.to_dict(), ) + curtailable_device_sensors = fields.List( + SensorIdField(), + data_key="curtailable-device-sensors", + metadata=metadata.CURTAILABLE_DEVICE_SENSORS.to_dict(), + ) + def set_default_breach_prices( self, data: dict, fields: list[str], price: ur.Quantity ): diff --git a/flexmeasures/data/schemas/scheduling/metadata.py b/flexmeasures/data/schemas/scheduling/metadata.py index 39204d1bc3..a5feb63a0c 100644 --- a/flexmeasures/data/schemas/scheduling/metadata.py +++ b/flexmeasures/data/schemas/scheduling/metadata.py @@ -30,7 +30,7 @@ def to_dict(self): INFLEXIBLE_DEVICE_SENSORS = MetaData( description="""Power sensors representing devices that are relevant, but not flexible in the timing of their demand/supply. For example, a sensor recording rooftop solar power that is connected behind the main meter, and whose production falls under the same contract as the flexible device(s) being scheduled. -Their power demand cannot be adjusted but still matters for finding the best schedule for other devices. +Their power generation (or demand) cannot be adjusted but still matters for finding the best schedule for other devices. Must be a list of integers. """, example=[3, 4], @@ -39,6 +39,14 @@ def to_dict(self): description="""Sensor used to record the aggregate power schedule of all flexible and inflexible devices involved when scheduling this asset.""", example={"sensor": 9}, ) +CURTAILABLE_DEVICE_SENSORS = MetaData( + description="""Power sensors representing devices that are curtailable. +For example, a sensor recording rooftop solar power that is connected behind the main meter, and whose production falls under the same contract as the flexible device(s) being scheduled. +Their power generation (or demand) can be reduced. +Must be a list of integers. +""", + example=[5, 6], +) COMMITMENTS = MetaData( description="Prior commitments. Support for this field in the UI is still under further development, but you can find more information in :ref:`commitments`.", example=[],