99from collections import abc
1010
1111from ....microgrid import connection_manager
12- from ....microgrid .component import ComponentCategory , ComponentMetricId , InverterType
12+ from ....microgrid .component import ComponentCategory , ComponentMetricId
1313from ..._quantities import Power
1414from .._formula_engine import FormulaEngine
15- from ._formula_generator import (
16- NON_EXISTING_COMPONENT_ID ,
17- FormulaGenerationError ,
18- FormulaGenerator ,
19- FormulaType ,
20- )
15+ from ._formula_generator import NON_EXISTING_COMPONENT_ID , FormulaGenerator , FormulaType
2116
2217_logger = logging .getLogger (__name__ )
2318
@@ -38,8 +33,8 @@ def generate(self) -> FormulaEngine[Power]:
3833 "pv-power" , ComponentMetricId .ACTIVE_POWER , Power .from_watts
3934 )
4035
41- pv_meters = self ._get_pv_meters ()
42- if not pv_meters :
36+ pv_components = self ._get_pv_power_components ()
37+ if not pv_components :
4338 _logger .warning (
4439 "Unable to find any PV inverters in the component graph. "
4540 "Subscribing to the resampling actor with a non-existing "
@@ -55,7 +50,7 @@ def generate(self) -> FormulaEngine[Power]:
5550
5651 builder .push_oper ("(" )
5752 builder .push_oper ("(" )
58- for idx , comp_id in enumerate (pv_meters ):
53+ for idx , comp_id in enumerate (pv_components ):
5954 if idx > 0 :
6055 builder .push_oper ("+" )
6156
@@ -71,39 +66,30 @@ def generate(self) -> FormulaEngine[Power]:
7166
7267 return builder .build ()
7368
74- def _get_pv_meters (self ) -> abc .Set [int ]:
75- component_graph = connection_manager . get (). component_graph
69+ def _get_pv_power_components (self ) -> abc .Set [int ]:
70+ """Get the component ids of the PV inverters or meters in the component graph.
7671
77- pv_inverters = list (
78- comp
79- for comp in component_graph .components ()
80- if comp .category == ComponentCategory .INVERTER
81- and comp .type == InverterType .SOLAR
82- )
83- pv_meters : set [int ] = set ()
72+ Returns:
73+ A set of component ids of the PV inverters or meters in the component graph.
8474
85- if not pv_inverters :
86- return pv_meters
75+ Raises:
76+ RuntimeError: if the grid component has no PV inverters or meters as successors.
77+ """
78+ component_graph = connection_manager .get ().component_graph
79+ grid_successors = self ._get_grid_component_successors ()
8780
88- for pv_inverter in pv_inverters :
89- predecessors = component_graph .predecessors (pv_inverter .component_id )
90- if len (predecessors ) != 1 :
91- raise FormulaGenerationError (
92- "Expected exactly one predecessor for PV inverter "
93- f"{ pv_inverter .component_id } , but found { len (predecessors )} ."
81+ if len (grid_successors ) == 1 :
82+ successor = next (iter (grid_successors ))
83+ if successor .category != ComponentCategory .METER :
84+ raise RuntimeError (
85+ "Only grid successor in the component graph is not a meter."
9486 )
95- meter = next (iter (predecessors ))
96- if meter .category != ComponentCategory .METER :
97- raise FormulaGenerationError (
98- f"Expected predecessor of PV inverter { pv_inverter .component_id } "
99- f"to be a meter, but found { meter .category } ."
100- )
101- meter_successors = component_graph .successors (meter .component_id )
102- if len (meter_successors ) != 1 :
103- raise FormulaGenerationError (
104- f"Expected exactly one successor for meter { meter .component_id } "
105- f", connected to PV inverter { pv_inverter .component_id } "
106- f", but found { len (meter_successors )} ."
107- )
108- pv_meters .add (meter .component_id )
109- return pv_meters
87+ grid_successors = component_graph .successors (successor .component_id )
88+
89+ pv_meters_or_inverters : set [int ] = set ()
90+
91+ for successor in grid_successors :
92+ if component_graph .is_pv_chain (successor ):
93+ pv_meters_or_inverters .add (successor .component_id )
94+
95+ return pv_meters_or_inverters
0 commit comments