namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa; /// Optional capability on an address-space sink: surgical in-place attribute updates on an /// EXISTING variable node, used by AddressSpaceApplier to avoid a full RebuildAddressSpace for pure-property /// tag changes (Writable / Historizing / DataType / array-shape). A sink that does not implement it ⇒ caller /// falls back to a full rebuild (safe default). public interface ISurgicalAddressSpaceSink { /// Update an existing variable node's surgically-updatable attributes IN PLACE, notifying /// subscribers (ClearChangeMasks) without a rebuild — so client MonitoredItems on the node survive. /// Covers Writable (AccessLevel + inbound-write handler), Historizing (+ historian-tagname binding), /// and the node's presentation shape: (the OPC UA DataType) and /// / (ValueRank + ArrayDimensions). When the /// shape actually changes, the implementation resets the node's value to BadWaitingForInitialData /// (no stale wrong-typed value is exposed until the driver republishes) and raises a Part 3 /// GeneralModelChangeEvent (verb=DataTypeChanged) so model-aware clients re-read the node definition. /// Returns false if the node does not exist (caller should rebuild instead). /// The folder-scoped node id of the variable to update in place. /// When true the node becomes read/write (with the inbound-write handler); otherwise read-only. /// null ⇒ not historized; non-null ⇒ Historizing with the HistoryRead bit and tagname binding. /// The OPC UA built-in data type name (e.g. "Boolean", "Int32", "Float"). /// When true the node is a 1-D array (ValueRank=OneDimension); when false scalar. /// The declared length of the 1-D array when is true; ignored for scalars. /// The namespace realm lives in — the sink resolves the /// namespace index from the realm rather than parsing it out of the id string. /// True when the in-place update was applied; false when the node is missing (caller rebuilds). bool UpdateTagAttributes(string variableNodeId, bool writable, string? historianTagname, string dataType, bool isArray, uint? arrayLength, AddressSpaceRealm realm); /// Update an existing folder node's DisplayName IN PLACE, notifying subscribers /// (ClearChangeMasks) without a rebuild — used by AddressSpaceApplier to apply a UNS Area / Line /// rename without tearing down + repopulating the whole address space (which would drop every /// client's MonitoredItems). The folder's NodeId is unchanged (a rename only touches the friendly /// browse/display name, not the logical id). Returns false if the folder does not exist (caller /// should rebuild instead). /// The node id of the folder whose display name to update in place. /// The new display name to apply. /// The namespace realm lives in. /// True when the in-place update was applied; false when the folder is missing (caller rebuilds). bool UpdateFolderDisplayName(string folderNodeId, string displayName, AddressSpaceRealm realm); /// Remove ONE existing value-variable node IN PLACE (detach from its parent, drop it from the /// predefined-node set, drop any historized-tagname registration), then raise a Part 3 /// GeneralModelChangeEvent (verb=NodeDeleted) outside the lock — so subscribers of OTHER nodes are /// untouched and their MonitoredItems survive. The caller has already written a final Bad quality to the /// node so in-flight MonitoredItems on the removed node observe the removal; after the node is gone, /// re-subscription attempts get BadNodeIdUnknown from the SDK. Returns false when the node id is unknown /// (the node-manager maps drifted from the plan — caller falls back to a full rebuild). /// The folder-scoped node id of the variable to remove in place. /// The namespace realm lives in. /// True when the node was removed; false when the id is unknown (caller rebuilds). bool RemoveVariableNode(string variableNodeId, AddressSpaceRealm realm); /// Remove ONE existing Part 9 alarm-condition node IN PLACE (detach, drop from the /// predefined-node set, clear the native-alarm flag), then raise NodeDeleted outside the lock. The /// caller has already written the terminal RemovedConditionState (Retain=false) so a removed condition /// stops replaying on ConditionRefresh. Returns false when the condition id is unknown (caller /// rebuilds). /// The alarm condition node id (== ScriptedAlarmId, or a native alarm tag's folder-scoped id). /// The namespace realm lives in. /// True when the condition was removed; false when the id is unknown (caller rebuilds). bool RemoveAlarmConditionNode(string alarmNodeId, AddressSpaceRealm realm); /// Remove an equipment folder AND its entire descendant subtree (sub-folders, value variables, /// condition nodes) IN PLACE: per-descendant map/registration cleanup (variables, historized tagnames, /// conditions, native flags), notifier demotion (sever the Server↔folder root-notifier ref + /// notifier-folder + event-notifier-source registrations for the equipment id), then one NodeDeleted for /// the equipment folder outside the lock. Returns false when the folder id is unknown (caller /// rebuilds). /// The equipment folder node id whose entire subtree to remove. /// The namespace realm lives in. /// True when the subtree was removed; false when the id is unknown (caller rebuilds). bool RemoveEquipmentSubtree(string equipmentNodeId, AddressSpaceRealm realm); }