Fix power sensor output for disabled appliances - #1540
Conversation
Return null output for power sensors whose measured appliance is disabled, while preserving topology-based branch behavior. Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
Document how sensor output derives energized from the measured object and add symmetric/asymmetric C++ coverage for appliance status and branch topology semantics. Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
Keep the sensor section focused on how its output reflects the measured object's energized state and residual behavior. Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
Adopt the maintainer's concise sensor-output wording and remove the temporary Python test now that the C++ migration thread is resolved. Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes state-estimation power-sensor outputs so that sensors measuring disabled appliances (source, shunt, load, generator) return a null output (energized = 0 and zero residuals), while preserving topology-governed energized semantics for branch/branch3 power sensors and leaving current-sensor behavior unchanged.
Changes:
- Update main-core power-sensor output logic to additionally gate energized output on the measured appliance’s
status()(for appliance terminal types). - Re-enable previously xfailed regression datasets by updating expected outputs to reflect null residuals when measured appliances are disabled.
- Add C++ unit tests for energized/null-output behavior across appliance-vs-branch topology semantics and document the
energizedderivation in the user manual.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/data/state_estimation/dummy-test-line-into-itself/params.json | Removes xfail now that appliance-disabled behavior is fixed. |
| tests/data/state_estimation/dummy-test-line-into-itself/asym_output_batch.json | Updates expected residuals to zeros for null (energized=0) outputs. |
| tests/data/state_estimation/dummy-test-line-into-itself-minimal/sym_output_batch.json | Updates expected null-output residuals to zero for disabled measured appliance. |
| tests/data/state_estimation/dummy-test-line-into-itself-minimal/params.json | Removes xfail now that appliance-disabled behavior is fixed. |
| tests/cpp_unit_tests/main_core/test_main_core_output.cpp | Adds focused unit tests for power/current sensor energized semantics. |
| power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp | Implements measured-object status gating for appliance-measured power sensors. |
| docs/user_manual/components.md | Documents how energized is derived and that null outputs have zero residuals. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Guard appliance lookups for reduced component containers and add a compile regression test. Signed-off-by: Weiping Yan <vipinapple986@gmail.com>
…noreply.github.com> I, Weiping Yan <152196713+appleweiping@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 7999511 Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
|
Hi @appleweiping, Something seems to have gone wrong with the base branch. I had to change the base branch due to some blocking things in the root, but the base branch was not automatically updated. Can you please re-open the PR and point the base branch to |
|
I see this PR got closed because underlying branch was deleted. That branch and PR is now merged. |
|
Nevermind, resolved! We will continue with review here. |
|
Hi @appleweiping, It looks like compilation is failing for MSVC and clang-tidy for unreachable code and misc-include-cleaner reasons, respectively. If you need any help, please let us know and we'll have a look. |
Use an explicit constexpr else branch to avoid MSVC's unreachable-code warning and directly include headers required by include-cleaner. Signed-off-by: Weiping Yan <152196713+appleweiping@users.noreply.github.com>
| case branch_from: | ||
| [[fallthrough]]; | ||
| case branch_to: | ||
| [[fallthrough]]; | ||
| case branch3_1: | ||
| [[fallthrough]]; | ||
| case branch3_2: | ||
| [[fallthrough]]; | ||
| case branch3_3: | ||
| [[fallthrough]]; | ||
| case node: | ||
| return true; |
There was a problem hiding this comment.
@mgovers @appleweiping Does this PR only partially fixes problem?
With this PR, you indeed solve the problem with sensors on disconnected appliances. But for energized branch or branch3, if one side is disconnected and there is a sensor on this side, even after this PR, the sensor value will still be wrongfully calculated instead of getting a null output.
To fix that part also, you cannot use fall through here for all branch switch cases. Instead, you need to check the actual status of that side of the branch/branch3.
There was a problem hiding this comment.
Thanks for raising this, Tony. I intentionally kept partially disconnected branch/branch3 sensors topology-governed based on the scope previously confirmed in #1464 and the earlier review guidance in #1468: when the component still contributes to the mathematical grid, the sensor remains energized.
This proposed terminal-specific behavior would change that agreed contract. @mgovers, could you please confirm which behavior should apply? If terminal-specific behavior is intended, should it apply only to power sensors, or to current sensors as well? I’ll wait for alignment before changing the implementation and tests.
Summary
energizedis derived from the measured object.Root cause
Power-sensor output only checked whether the measured object had a connected mathematical topology group. Status-only updates for shunts, loads, and generators do not rebuild that topology, so a disabled appliance could still produce
energized == 1and non-zero residuals. The output path now also checks the actual status of measured appliances while preserving topology-only semantics for branches, branch3 components, and nodes.Because the measured terminal is selected at runtime, direct appliance lookups would otherwise be instantiated even for reduced component containers that omit unused appliance types. Compile-time type guards retain the previous topology-only behavior for those unreachable paths.
Validation
uv run --frozen pytest— 1778 passed, 4 skipped, 7 xfailed; 97.13% coverage.uv run --frozen pre-commit run --files <changed files>— all applicable hooks passed, including REUSE, pytest, clang-format, and markdownlint.The temporary Python migration reference was removed after the maintainer resolved the C++ test-migration thread.
No public API, schema, generated file, or current-sensor implementation is changed.
Closes #1464
Assisted-by: OpenAI Codex