Aggregation reporter: select sensors by asset, name and unit - #2525
Ahmad-Wahid wants to merge 9 commits into
Conversation
Context: - Issue #2520: a site often wants one aggregated signal (all its PV, say), which so far meant naming every sensor in the report parameters by hand. Change: - The config gains `asset`, `sensors`, `sensor_name_pattern` and `sensor_units`, which select the sensors to aggregate; `asset` covers an asset and its offspring. - Values are converted to the unit of the output sensor, and read at its resolution, so sensors recording in different units and at different resolutions can be aggregated; `convert_units` turns the conversion off. - The output sensor is left out of the aggregation, so a report can be recorded on a sensor sitting below the very asset being aggregated. - `input_sensors` reports the selected sensors too, so the data source stays accountable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…lection Context: - Issue #2520 adds sensor selection, unit conversion and resampling to the AggregatorReporter, none of which the existing tests reach. Change: - Add a site fixture whose PV sensors sit on a child and a grandchild asset, record in kW and MW, and report at quarter-hourly and hourly resolutions, with a previous report already on the sensor the aggregate is recorded on. - Cover selection by asset, by sensor list, by name pattern and by units, the unit conversion and its `convert_units` switch, the refusal to aggregate a temperature onto a power sensor, an empty selection, an unparsable pattern, and the selection landing on the report's data source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Context: - Issue #2520 lets the AggregatorReporter select its own sensors, which the reporting feature page did not describe. Change: - Describe the `asset`, `sensors`, `sensor_name_pattern` and `sensor_units` config fields, the conversion to the output sensor's unit and resolution, and the exclusion of the output sensor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Context: - PR #2525 lets the AggregatorReporter aggregate everything below an asset. Change: - Add a New features entry naming the asset, the narrowing filters and the conversion to the output sensor's unit and resolution. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
Documentation build overview
17 files changed ·
|
Resolve the changelog conflict by keeping both entries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC Signed-off-by: F.N. Claessen <claessen@seita.nl>
Since #2547, a new field name that reaches the wire must use dashes, and the three this PR adds did not, which turned the field naming test red once main was merged in. They are unreleased, so this is a plain rename: the config now reads sensor-name-pattern, sensor-units and convert-units. Attribute names in Python are unchanged; only the data keys, the docs, the error messages naming them and the tests passing them move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC Signed-off-by: F.N. Claessen <claessen@seita.nl>
|
Can you check this comment about using the flex-config for lookup (as well), which probably expands the scope a bit? |
Context: - PR #2525 leaves the output sensor out of the aggregation, but `input_sensors` still listed it when the units filter selected it, so the property described a sensor the reporter would not read. Change: - Drop the sensors the report is recorded on from the selected set in `input_sensors`, matching what the computation does; a sensor named in `input` is still kept. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…nsor Context: - The units filter selects the output sensor, which the reporter then leaves out, so `input_sensors` should not name it either. Change: - Assert the output sensor is absent from `input_sensors` after a run that selects it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Ahmad-Wahid <ahmedwahid16101@gmail.com>
…r' into feature/2520-aggregation-reporter
|
Just commenting on the PR description: It feels strange to have created this whole mechanism (i.e. the flex-config) for defining a site topology, including how devices are nested, which sensors record aggregates and which sign corresponds to consumption/production, and then make/extend a second mechanism (the AggregatorReporter extended in this PR) for also aggregating across power sensors. Users would then have to keep the two topologies in sync themselves. It will lead to problems. I could imagine an AggregatorReporter being useful to aggregate sensor data other than power data, though. Or using it to subtract one sensor's power data from another's. But for the purpose of aggregating across a site, the flex-config should be the single source of truth imo. Related question: does the AggregatorReporter work with the VariableQuantity field, so that it gets all its source-filtering features? The flex-config does have that, which would become one likely source of discrepancies.
|
|
Having now looked at this and #2579 together, I don't think we should keep this PR. The site topology already lives in the flex-config, and this PR adds a second, name/unit-based mechanism for describing the same thing, with nothing to keep the two in sync. The regex/unit filters are guesswork (e.g. My proposal: close this one and carry the parts worth keeping into the reworked #2579:
Also note that defaulting |
Description
A site usually wants its sensors as one aggregated signal — all the PV on site, so it can be
forecast and used in flex scheduling. Until now the
AggregatorReportercould do that only if everysensor was named by hand in the report parameters, which does not survive an inverter being added.
The reporter now selects its own sensors, through four new config fields:
asset— aggregate the sensors of this asset and of all of its offspring, so pointing at a site asset covers everything below it.sensors— aggregate these sensors, listed by ID.sensor-name-pattern— keep only the sensors whose name matches this regular expression.sensor-units— keep only the sensors recording in one of these units, or in a unit measuring the same quantity, so["MW"]also keeps a sensor recording inkW, but not one recording inMWh.Sensors named in the
inputparameters still work, and are read as described there; the selectedsensors are added to them.
inputis therefore no longer required in the parameters — a selection inthe config is enough, and a reporter that selects nothing at all says so, rather than failing later
inside Pandas.
Units and resolutions are reconciled with the output sensor. A discovered sensor cannot be
hand-checked, so values are converted to the unit of the output sensor and read at its resolution.
That is what makes a roof recording 100 kW in quarter-hourly events and a carport recording 0.2 MW in
hourly events add up to 0.3 MW on an hourly MW sensor. Passing a
resolutionparameter still winsover the output sensor's,
convert-units: falseaggregates the raw values, a sensor without a unit isnever converted (an empty unit says nothing about what its values mean, so it draws a warning), and a
sensor whose quantity the output sensor cannot express — a temperature onto a power sensor — is
reported as an error instead of being silently added up.
The output sensor is left out of the aggregation. A report is often recorded on a sensor of the
very asset being aggregated, and reading it back in would fold each run's own previous output into the
next one.
input_sensorsleaves it out for the same reason, so the property names the sensors thereporter will actually read; a sensor named explicitly in
inputis still kept, because naming itthere asks for it to be read.
Accountability. The selection lives in the config, not in the parameters, so it is recorded on
the reporter's data source alongside the method and weights, and a changed selection yields a new data
source.
documentation/changelog.rstHow to test
Eight tests are added, on a fixture whose PV sensors sit on a child and a grandchild asset, record in
kW and MW at quarter-hourly and hourly resolutions, and whose output sensor already holds a previous
report of 99 MW.
Each was verified to fail with the code it covers disabled. The thirteen breaks used were: dropping
the name-pattern filter, dropping the units filter, including the output sensor in the aggregation,
listing the output sensor in
input_sensors, skipping the unit conversion, ignoringconvert-units,not defaulting the resolution to the output sensor's, dropping the empty-selection error, not
overriding
input_sensors, ignoring thesensorslist, not walkingasset.offspring, skipping theregex validation, and taking
assetas a plain int rather than an asset. Every new test went redunder at least one of them, and the whole set is green with the code in place.
The 15 pre-existing aggregator tests are untouched and still pass, as do the reporting, schema, CLI
and API report-trigger suites.
It was also run end to end against a real database, building a site by hand — an asset, a sub-asset,
four sensors in two units at two resolutions, a day of CSV data — and reporting onto a site-level
sensor. The roof's 400 kW at quarter-hourly and the carport's 0.15 MW hourly come out as 0.547 MW on
the hourly MW sensor, and a second run of the same command saves nothing, because the output sensor
is not read back in.
Notes for reviewers
The three multi-word config fields are spelled in kebab-case (
sensor-name-pattern,sensor-units,convert-units) since #2547 landed on main and c846835 renamed them here; the Python attribute namesare unchanged.
assetandsensorsare single words and were never affected.Further improvements
Two items of #2520 depend on PRs that have not landed yet, so they are noted rather than done here:
config, which is exactly what Reports as jobs and as automations #2297 pins on a report automation's data source, and
input_sensorsresolves the selected sensors so the output-scope check has something to check. Worth re-testing
end to end once Reports as jobs and as automations #2297 merges.
site-aggregatetemplate carrying this reporter, anasset/sensor-name-patternconfig and the recommended rolling window would fit Prepared report templates #2300's shape directly,and is left to that PR.
sensor-unitsmatches on dimension rather than on the exact spelling, which is what makes it usefulnext to the unit conversion; a caller wanting an exact-spelling filter would need a further option.
One rough edge found while testing, not introduced here and not fixed here: when a reporter raises,
flexmeasures add reportlets the exception escape, so the user gets a full Python traceback with themessage at the bottom rather than a clean CLI error. That applies to every reporter, so it deserves
its own issue.
Related items
Closes #2520.
Sign-off
🤖 Generated with Claude Code