Advertise only the aggregates the configured historian backend serves (HistoryServerCapabilities/AggregateFunctions) #682

Closed
opened 2026-10-11 15:23:24 -04:00 by dohertj2 · 1 comment
Owner

Found during #679. OtOpcUaSdkServer never overrides CreateAggregateManager, so ServerCapabilities/AggregateFunctions (i=2997) and HistoryServerCapabilities/AggregateFunctions (i=11201) list the SDK's full default set (37 on the docker-dev rig) regardless of backend. Gateway serves 4 (TimeAverage/Minimum/Maximum/Total), SqlServer/QuestDB 17; the rest answer BadAggregateNotSupported per node.

Proposal: IHistorianDataSource.SupportedAggregates (default = all) and prune the advertised AggregateFunctions nodes to match. Caveat: AggregateManager also drives subscription AggregateFilter calculators on live data — trim only the advertised nodes, not the calculator factories.

Found during #679. `OtOpcUaSdkServer` never overrides `CreateAggregateManager`, so `ServerCapabilities/AggregateFunctions` (i=2997) and `HistoryServerCapabilities/AggregateFunctions` (i=11201) list the SDK's full default set (37 on the docker-dev rig) regardless of backend. Gateway serves 4 (TimeAverage/Minimum/Maximum/Total), SqlServer/QuestDB 17; the rest answer `BadAggregateNotSupported` per node. Proposal: `IHistorianDataSource.SupportedAggregates` (default = all) and prune the advertised AggregateFunctions nodes to match. Caveat: `AggregateManager` also drives subscription `AggregateFilter` calculators on live data — trim only the advertised nodes, not the calculator factories.
Author
Owner

Fixed — merged 113f1eaf (+ Gateway set from #681 197246c3). Each backend declares IHistorianDataSource.SupportedAggregates (SqlServer/QuestDB 17 from AggregateFamilies.Served; Gateway 12; no historian = none; null from an out-of-tree source = all). HistoryServerCapabilities/AggregateFunctions (i=11201) now lists exactly that set, re-synced at boot and on every source assignment. ServerCapabilities/AggregateFunctions (i=2997) deliberately keeps the SDK's full 37 — Part 5 defines it as everything the server supports, and live AggregateFilter subscriptions still accept all 37 (calculator factories untouched). One AggregateFunctionMap table now drives both HistoryRead and advertising; processed reads refuse out-of-set aggregates up front.

⚠️ Client-visible: with no historian configured a Processed HistoryRead returns BadAggregateNotSupported (was GoodNoData); Raw/AtTime/Events still GoodNoData.

Verification: 7 over-the-wire tests (both folders per backend, empty-from-boot, re-sync both directions, live AggregateFilter for unadvertised aggregates); live gate 9 G1 on both centrals: i=11201 = 17/17/12/0, i=2997 = 37 always, every advertised aggregate served and every other one refused. HistoryServerCapabilities booleans were not audited (noted in docs).

**Fixed — merged `113f1eaf` (+ Gateway set from #681 `197246c3`).** Each backend declares `IHistorianDataSource.SupportedAggregates` (SqlServer/QuestDB 17 from `AggregateFamilies.Served`; Gateway 12; no historian = none; null from an out-of-tree source = all). `HistoryServerCapabilities/AggregateFunctions` (i=11201) now lists exactly that set, re-synced at boot and on every source assignment. `ServerCapabilities/AggregateFunctions` (i=2997) deliberately keeps the SDK's full 37 — Part 5 defines it as everything the server supports, and live `AggregateFilter` subscriptions still accept all 37 (calculator factories untouched). One `AggregateFunctionMap` table now drives both HistoryRead and advertising; processed reads refuse out-of-set aggregates up front. ⚠️ Client-visible: with no historian configured a Processed HistoryRead returns `BadAggregateNotSupported` (was `GoodNoData`); Raw/AtTime/Events still `GoodNoData`. Verification: 7 over-the-wire tests (both folders per backend, empty-from-boot, re-sync both directions, live AggregateFilter for unadvertised aggregates); live gate 9 G1 on both centrals: i=11201 = 17/17/12/0, i=2997 = 37 always, every advertised aggregate served and every other one refused. HistoryServerCapabilities booleans were not audited (noted in docs).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#682