mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-16 21:02:51 +08:00
2ba58a8cbf
Fixes #4669. OPC 10000-3 §7.15 says the SourceNode of `GeneratesEvent` "shall be an ObjectType, a VariableType or a Method". CTT `Base Info Core Structure 2 001.js` flags every Object that is the source of one. #4667 fixed this in the source generator. This PR fixes the three remaining WoT places. ### 1. WotCon asset registry - `AssetRegistry.BuildEventNode` / `RemoveEventTypes` no longer add or remove `GeneratesEvent` from the asset Object. Event delivery already relies on `EventNotifier = SubscribeToEvents` and root-notifier registration. - Tests now assert the reference is **absent** and the notifier bit is set. The re-apply test asserts that the old EventType node is gone. ### 2. WoT NodeSet converter (`src/Opc.Ua.Types/Wot`) - **TD → NodeSet:** a last pass (`RelocateInstanceGeneratesEvent`) moves forward `GeneratesEvent` references off an Object/Variable root: - An event the bound type already declares needs nothing more. Matching is by qualified BrowseName against the local context's declarations, the same rule as the declaration merge. - Any other event is declared by a synthesized non-abstract `<rootLocal>Type`. It derives from the bound type (or from `BaseObjectType` / `BaseDataVariableType` when the TD binds none) and becomes the instance's `HasTypeDefinition`. A Variable root gets a `UAVariableType` with the instance's DataType and ValueRank. - Thing Models are unchanged: the projected type keeps its `GeneratesEvent`. - **NodeSet → TD:** - An instance's event affordances are now collected from its type definition and that type's supertypes. Instance-level `GeneratesEvent` is still read for third-party NodeSets. - In a single readable document, a type that only carries one instance's events (only `HasSubtype` + `GeneratesEvent`, typing exactly one instance) is not chosen as root. It is folded back: its supertype becomes the type binding, and no link is written when that supertype is the default base type. The TD → NodeSet → TD round trip stays readable, with no `uav:nodes` fallback. - A document set gives the carrier its own Thing Model, and the instance TD binds to it. - **Archive check:** an event affordance is accepted when the root's type definition, or one of its supertypes, generates it. - `docs/WoTNodeSetConversion.md` documents the behaviour in a new "Event source" row. ### 3. Aggregation sample - `SamplePump.NodeSet2.xml`: each pump is typed by its own `PumpType` subtype, `ns=1;s=Pump1.Type` (`Pump_1Type`) and `Pump2.Type`, which declares its alarm EventTypes. - It is per pump because each pump owns its alarm EventTypes. `Pump2.Type` is cloned with the rest of Pump2. - The pumps keep `EventNotifier="1"` and no longer carry `GeneratesEvent`. - The checked-in documents are regenerated, adding `sample-pump-pump-1type.json` / `-2type.json`. The pump TDs still list the alarm event affordances. - The sample binding lookup ignores Thing Models, because the type's TM declares the same EventType as the pump TD. A declaration missing from the instance still fails as before. - Docs: `WoTConnectivity.md` (asset event affordances, §12.4.2) and `WotBindings.md`. The `GeneratesEvent` clause in the sample-limitation note was already stale, so I removed it. ### Runtime check `WotNativeOwnershipIndex` only uses `GeneratesEvent` in its alias table. Projected event routing takes the owner from `uav:componentOf` / `uav:id` and the notifier from Parent/`HasNotifier`. Nothing in `Opc.Ua.WotCon.Server` reads an instance-level `GeneratesEvent`. ### Tests (net10.0) - `Opc.Ua.Types.Tests`: 11446 passed, 1 skipped. New `WotInstanceEventSourceTests` covers object and variable roots, TMs, the TD with no events, the folded round trip, the legacy instance reference and the document set. Two bound-type cases were added to `WotDeclarationMergeBoundaryTests`. - `Opc.Ua.WotCon.Bindings.Tests`: 714 passed. - `Opc.Ua.WotCon.Tests`: 1496 passed, including the byte-exact sample regeneration tests. - net48 build of both test projects is clean, and `dotnet format whitespace` is clean. Not run: CTT `Base Info Core Structure 2 001.js` (p02-base-info) against a WotCon server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>