Skip to content

Commit 55f7a2a

Browse files
Flix6xclaude
andcommitted
fix: gather inflexible device sensors from nested commodities entries too
Addresses Copilot review on #2358: get_inflexible_device_sensors only inspected the top-level flex-context keys, omitting inflexible devices configured within per-commodity contexts from sensor status/metadata. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TaMepbxRYzJxQKFtu6Hq4p Signed-off-by: F.N. Claessen <felix@seita.nl>
1 parent cd914e4 commit 55f7a2a

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

flexmeasures/data/models/generic_assets.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,20 +847,23 @@ def get_inflexible_device_sensors(self):
847847
"""
848848
Searches for inflexible device sensors upwards on the asset tree, across the
849849
deprecated ``inflexible-device-sensors`` key (bare sensor IDs) and the
850-
``inflexible-consumption``/``inflexible-production`` keys (sensor references).
850+
``inflexible-consumption``/``inflexible-production`` keys (sensor references),
851+
both top-level and within each nested ``commodities`` entry.
851852
This search will stop once any sensors are found (will not aggregate towards the top of the tree)
852853
"""
853854

854855
from flexmeasures.data.models.time_series import Sensor
855856
from flexmeasures.data.models.planning.devices import INFLEXIBLE_DEVICE_KEYS
856857

857858
flex_context = self.get_flex_context()
859+
contexts = [flex_context] + list(flex_context.get("commodities") or [])
858860
# Need to load inflexible device sensors manually as generic_asset does not get to SQLAlchemy session context.
859861
sensor_ids = list(
860862
dict.fromkeys( # dedupe, preserving order
861863
entry["sensor"] if isinstance(entry, dict) else entry
864+
for context in contexts
862865
for key in INFLEXIBLE_DEVICE_KEYS
863-
for entry in (flex_context.get(key) or [])
866+
for entry in (context.get(key) or [])
864867
)
865868
)
866869
if sensor_ids:

flexmeasures/data/tests/test_generic_assets.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ def test_get_inflexible_device_sensors_across_keys(
354354
fresh_db, setup_generic_asset_types_fresh_db, setup_accounts_fresh_db
355355
):
356356
"""Inflexible device sensors are gathered from all three flex-context keys,
357-
walking up the asset tree until any of them is found."""
357+
both top-level and within nested commodities entries, walking up the asset
358+
tree until any of them is found."""
358359
db = fresh_db
359360
asset_type = setup_generic_asset_types_fresh_db["battery"]
360361
owner = setup_accounts_fresh_db["Prosumer"]
@@ -365,13 +366,20 @@ def test_get_inflexible_device_sensors_across_keys(
365366
db.session.flush()
366367
load_sensor = Sensor(name="a load", generic_asset=site, unit="kW")
367368
pv_sensor = Sensor(name="a pv", generic_asset=site, unit="kW")
368-
db.session.add_all([load_sensor, pv_sensor])
369+
boiler_sensor = Sensor(name="a boiler", generic_asset=site, unit="kW")
370+
db.session.add_all([load_sensor, pv_sensor, boiler_sensor])
369371
db.session.flush()
370372
site.flex_context = {
371373
"inflexible-consumption": [{"sensor": load_sensor.id}],
372374
"inflexible-production": [
373375
{"sensor": pv_sensor.id, "exclude-source-types": ["scheduler"]}
374376
],
377+
"commodities": [
378+
{
379+
"commodity": "gas",
380+
"inflexible-consumption": [{"sensor": boiler_sensor.id}],
381+
}
382+
],
375383
}
376384
leaf = GenericAsset(
377385
name="gathering battery",
@@ -382,5 +390,6 @@ def test_get_inflexible_device_sensors_across_keys(
382390
db.session.add(leaf)
383391
db.session.commit()
384392

385-
assert set(leaf.get_inflexible_device_sensors()) == {load_sensor, pv_sensor}
386-
assert set(site.get_inflexible_device_sensors()) == {load_sensor, pv_sensor}
393+
expected_sensors = {load_sensor, pv_sensor, boiler_sensor}
394+
assert set(leaf.get_inflexible_device_sensors()) == expected_sensors
395+
assert set(site.get_inflexible_device_sensors()) == expected_sensors

0 commit comments

Comments
 (0)