Skip to content

Gate no-telemetry components out of formulas via operational mode#44

Merged
shsms merged 6 commits into
frequenz-floss:v0.x.xfrom
shsms:operational-mode
Jul 24, 2026
Merged

Gate no-telemetry components out of formulas via operational mode#44
shsms merged 6 commits into
frequenz-floss:v0.x.xfrom
shsms:operational-mode

Conversation

@shsms

@shsms shsms commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Components can be active without providing telemetry (control-only or
inactive). Their readings never arrive, so formulas that include them
never resolve. This branch adds the microgrid API's operational mode to
the Node trait and excludes no-telemetry components as measurement
sources throughout the formula engine.

Changes

  • New public OperationalMode enum, exposed on the Node trait via a
    defaulted operational_mode() method. The default (Unspecified) is
    treated as providing telemetry, so existing implementations keep
    their behavior.
  • The fallback engine drops no-telemetry components from every sum and
    difference of readings; they are measured through a reporting meter
    above them, which they still classify. A no-telemetry meter is
    measured through its reporting children; a no-telemetry grid meter's
    term is null.
  • The coalesce and consumer formulas skip no-telemetry components. The
    meterless consumer formula descends past a no-telemetry consumer
    meter to its reporting descendant meters, without double counting a
    line another collected meter already measures.
  • component_formula() returns a 0.0 formula and
    component_ac_coalesce_formula() returns None for a no-telemetry
    component; both now return an error for an id not in the graph.
  • Update the trait example implementations to microgrid API v0.18.1.

Breaking

  • component_formula() and component_ac_coalesce_formula() now
    return an error when the given component id is not in the graph;
    before, they returned a formula for any id. See the ## Upgrading
    entry in the release notes.

shsms added 6 commits July 9, 2026 09:50
A component whose operational mode provides no telemetry has no reading to
emit, so drop it from every sum or difference of component readings in the
fallback engine: it is instead measured through a telemetry-providing meter
above it, which it still classifies (e.g. as a PV meter). A meter with a
no-telemetry child stands alone on its own reading — no child sum is exact
for its group — backed by the children's best-effort sum.

Meters are gated the same way: a meter that provides no telemetry is not a
usable measurement source, and drilling it never emits its own reading. It
is measured by the best-effort sum of its children instead, so a reporting
meter above it resolves through it to its reporting descendants. A silent
meter whose children are fed around it, and one with nothing reporting
below, are dropped whole; components under a silent meter are measured
directly. A no-telemetry grid meter's term is null: its children never
carry the site's unmodeled load, so a children sum would read as a false
value. Existing all-telemetry behavior is unchanged.

A child meter that feeds a sibling of the same parent normally has no
term of its own, because the sibling's reading already carries its
flow. When that sibling contributes nothing — it provides no telemetry and
nothing below it reports — there is nothing to double count, so the child
meter keeps its term: it is the only source for that line.

Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
The grid, PV and battery AC coalesce formulas and both consumer formula
variants enumerate component readings directly; skip any component that
provides no telemetry, since it has no reading to include. A skipped
component is still used to classify the meter that measures it, which
remains in the formula.

In the meterless consumer formula, discovery descends past a no-telemetry
consumer meter, so its reporting descendant meters are summed in its place.
A descendant meter that another collected meter already measures is left
out: its line is already counted once, and what it gets through the silent
feed alone has no reading that separates it.
In the phantom-loads variant, a no-telemetry meter contributes no residual
term (its residual is unknowable), a no-telemetry diamond sibling is left
out of the diamond sum, and a no-telemetry non-meter successor is not
subtracted, so its share counts as phantom load.

Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
component_formula and component_ac_coalesce_formula emit a single component's
reading directly. When that component provides no telemetry it has no reading,
so return 0.0 (None for the AC coalesce variant) instead. Looking the component
up also validates that it exists in the graph.

Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
The Node and Edge doc examples targeted microgrid API v0.17's
common::v1::microgrid::components types. Retarget them to v0.18.1's
common::v1alpha8::microgrid::electrical_components, whose ElectricalComponent
and ElectricalComponentConnection are the current API surface; its category
enum also maps 1:1 onto ComponentCategory now.

Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
Introduce the OperationalMode enum, mirroring the microgrid API's
ElectricalComponentOperationalMode, and expose it on the Node trait via a
defaulted operational_mode() method. The default is Unspecified, treated as
providing telemetry, so existing Node implementations keep their behavior.

Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
@shsms

shsms commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

Based on #43

@shsms
shsms force-pushed the operational-mode branch 4 times, most recently from 7b488dd to 5f2f804 Compare July 16, 2026 14:47
@shsms
shsms force-pushed the operational-mode branch from 5f2f804 to 3ce386a Compare July 23, 2026 13:05
@shsms
shsms marked this pull request as ready for review July 23, 2026 13:07
@shsms
shsms requested a review from llucax July 23, 2026 13:07
@shsms
shsms force-pushed the operational-mode branch 2 times, most recently from a75aefa to ca0e0cc Compare July 24, 2026 11:01
@llucax llucax added the scope:breaking-change Breaking change, users will need to update their code label Jul 24, 2026

@llucax llucax left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 rAIview (AI review here!)

The operational-mode behavior is broadly well documented and thoroughly tested, but two medium-severity issues should be addressed before merging: the updated public integration example does not compile, and consumer-formula de-duplication can perform quadratic numbers of whole-graph traversals.

Comment thread src/graph_traits.rs
Comment thread src/graph/formulas/generators/consumer.rs
@shsms
shsms added this pull request to the merge queue Jul 24, 2026
Merged via the queue into frequenz-floss:v0.x.x with commit 985c5a4 Jul 24, 2026
4 checks passed
@shsms
shsms deleted the operational-mode branch July 24, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope:breaking-change Breaking change, users will need to update their code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants