1515from ...actor import ChannelRegistry , ComponentMetricRequest
1616from ...microgrid import ComponentGraph
1717from ...microgrid .component import ComponentMetricId
18- from ._formula_engine import FormulaEngine , FormulaReceiver
18+ from ._formula_engine import (
19+ FormulaEngine ,
20+ FormulaEngine3Phase ,
21+ FormulaReceiver ,
22+ FormulaReceiver3Phase ,
23+ _GenericEngine ,
24+ _GenericFormulaReceiver ,
25+ )
1926from ._formula_generators import (
2027 BatteryPowerFormula ,
2128 BatterySoCFormula ,
29+ EVChargerCurrentFormula ,
2230 FormulaGenerator ,
31+ GridCurrentFormula ,
2332 GridPowerFormula ,
2433 PVPowerFormula ,
2534)
@@ -110,7 +119,7 @@ def __init__(
110119 # meter to use when communicating with the resampling actor.
111120 self ._namespace = f"logical-meter-{ uuid .uuid4 ()} "
112121 self ._component_graph = component_graph
113- self ._engines : Dict [str , FormulaEngine ] = {}
122+ self ._engines : Dict [str , FormulaEngine | FormulaEngine3Phase ] = {}
114123 self ._tasks : List [asyncio .Task [None ]] = []
115124
116125 async def _engine_from_formula_string (
@@ -163,8 +172,8 @@ async def start_formula(
163172 async def _get_formula_stream (
164173 self ,
165174 channel_key : str ,
166- generator : Type [FormulaGenerator ],
167- ) -> FormulaReceiver :
175+ generator : Type [FormulaGenerator [ _GenericEngine ] ],
176+ ) -> _GenericFormulaReceiver :
168177 if channel_key in self ._engines :
169178 return self ._engines [channel_key ].new_receiver ()
170179
@@ -187,6 +196,34 @@ async def grid_power(self) -> FormulaReceiver:
187196 """
188197 return await self ._get_formula_stream ("grid_power" , GridPowerFormula )
189198
199+ async def grid_current (self ) -> FormulaReceiver3Phase :
200+ """Fetch the grid power for the microgrid.
201+
202+ If a formula engine to calculate grid current is not already running, it
203+ will be started. Else, we'll just get a new receiver to the already
204+ existing data stream.
205+
206+ Returns:
207+ A *new* receiver that will stream grid_current values.
208+
209+ """
210+ return await self ._get_formula_stream ("grid_current" , GridCurrentFormula )
211+
212+ async def ev_charger_current (self ) -> FormulaReceiver3Phase :
213+ """Fetch the cumulative ev charger current for the microgrid.
214+
215+ If a formula engine to calculate ev charger current is not already
216+ running, it will be started. Else, we'll just get a new receiver to the
217+ already existing data stream.
218+
219+ Returns:
220+ A *new* receiver that will stream ev_charger_current values.
221+
222+ """
223+ return await self ._get_formula_stream (
224+ "ev_charger_current" , EVChargerCurrentFormula
225+ )
226+
190227 async def battery_power (self ) -> FormulaReceiver :
191228 """Fetch the cumulative battery power in the microgrid.
192229
0 commit comments