@@ -203,11 +203,68 @@ class FormulaEngine(
203203 QuantityT ,
204204 ],
205205):
206- """
207- The FormulaEngine evaluates formulas and streams the results.
208-
209- Use the `FormulaBuilder` to create `FormulaEngine` instances.
210- """
206+ """[`FormulaEngine`][frequenz.sdk.timeseries.formula_engine.FormulaEngine]s are a
207+ part of the SDK's data pipeline, and provide a way for the SDK to apply formulas on
208+ resampled data streams.
209+
210+ They are used in the SDK to calculate and stream metrics like
211+ [`grid_power`][frequenz.sdk.timeseries.logical_meter.LogicalMeter.grid_power],
212+ [`consumer_power`][frequenz.sdk.timeseries.logical_meter.LogicalMeter.consumer_power],
213+ etc., which are building blocks of the
214+ [Frequenz SDK Microgrid Model][frequenz.sdk.microgrid--frequenz-sdk-microgrid-model].
215+
216+ The SDK creates the formulas by analysing the configuration of components in the
217+ {{glossary("Component Graph")}}.
218+
219+ ### Streaming Interface
220+
221+ The
222+ [`FormulaEngine.new_receiver()`][frequenz.sdk.timeseries.formula_engine.FormulaEngine.new_receiver]
223+ method can be used to create a
224+ [Receiver](https://frequenz-floss.github.io/frequenz-channels-python/latest/reference/frequenz/channels/#frequenz.channels.Receiver)
225+ that streams the [Sample][frequenz.sdk.timeseries.Sample]s calculated by the formula
226+ engine.
227+
228+ ```python
229+ from frequenz.sdk import microgrid
230+
231+ battery_pool = microgrid.battery_pool()
232+
233+ async for power in battery_pool.power.new_receiver():
234+ print(f"{power=}")
235+ ```
236+
237+ ### Composition
238+
239+ Composite `FormulaEngine`s can be built using arithmetic operations on
240+ `FormulaEngine`s streaming the same type of data.
241+
242+ For example, if you're interested in particular composite metric that can be
243+ calculated by subtracting
244+ [`battery_pool().power`][frequenz.sdk.timeseries.battery_pool.BatteryPool.power] and
245+ [`ev_charger_pool().power`][frequenz.sdk.timeseries.ev_charger_pool.EVChargerPool]
246+ from the
247+ [`logical_meter().grid_power`][frequenz.sdk.timeseries.logical_meter.LogicalMeter.grid_power],
248+ we can build a `FormulaEngine` that provides a stream of this calculated metric as
249+ follows:
250+
251+ ```python
252+ from frequenz.sdk import microgrid
253+
254+ logical_meter = microgrid.logical_meter()
255+ battery_pool = microgrid.battery_pool()
256+ ev_charger_pool = microgrid.ev_charger_pool()
257+
258+ # apply operations on formula engines to create a formula engine that would
259+ # apply these operations on the corresponding data streams.
260+ net_power = (
261+ logical_meter.grid_power - (battery_pool.power + ev_charger_pool.power)
262+ ).build("net_power")
263+
264+ async for power in net_power.new_receiver():
265+ print(f"{power=}")
266+ ```
267+ """ # noqa: D400, D205
211268
212269 def __init__ (
213270 self ,
0 commit comments