bug(alarms): condition events emit null ConditionClassId/ConditionClassName #475
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Sibling of #473, found by the high-effort review on PR #474, in the same function and via the exact same mechanism.
MaterialiseAlarmCondition(src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/OtOpcUaNodeManager.cs) never assigns the mandatory Part 9ConditionTypefieldsConditionClassId/ConditionClassName, so they arrive unset on every condition event — native and scripted.#473 fixed the three
BaseEventTypeidentity fields (EventType/SourceNode/SourceName) but deliberately scoped itself to those; these two were left as-is.Evidence
ConditionClassIdandConditionClassNameare assigned nowhere insrc/ortests/:The single hit is an aspirational doc comment — the mapping it describes is not implemented.
An empirical probe against the real materialise path (during the PR #474 review) dumped the children
Create()builds:Same mechanism as #473:
Create()builds the mandatory children from the type's embedded definition but leaves.Valueunset, and nothing downstream synthesises them (ReportEvent/InstanceStateSnapshotcopy children verbatim).Impact
An alarm HMI or Part 9 client that selects
ConditionClassIdto bucket alarms into Process / Maintenance / System — the standard OPC UA categorization — gets null for every OtOpcUa alarm and drops them all into an unclassified bucket.Part 9 requires a server that does not model condition classes to still report
BaseConditionClassTyperather than null. The SDK's ownAlarmConditionServersample assignsalarm.ConditionClassId.Value = ObjectTypeIds.ProcessConditionClassType.Suggested fix
In
MaterialiseAlarmCondition, alongside the #473 assignments:Worth deciding deliberately (why this was not folded into #473):
BaseConditionClassTypeis the safe spec-conformant default.ProcessConditionClassTypeis arguably truer for device alarms — but it is a wire contract clients bucket on, so it deserves an explicit call rather than a default picked in passing.IAlarmSource.cs:79already claims the alarm's category (Process/Maintenance/System/Diagnostics) "maps to OPC UAConditionClassNamedownstream". Wiring that through would make the doc comment true, but it needs a category -> ConditionClass mapping and a way to carry the category to the materialise seam (it is not on the composition today).Why this survived
Same reason as #473: no test asserts these field values. The new wire-level
NativeAlarmEventIdentityFieldDeliveryTests(PR #474) selects only the six BaseEventType fields, so it would not catch these either.A fix should extend that wire-level test's select clause to assert
ConditionClassId/ConditionClassNameare populated on a live condition event.References