Skip to content

fix(opctreemanager): resolve OpcFbPath exactly - #147

Merged
mrcsin merged 1 commit into
masterfrom
opctreemanager-opcfbpath-resolution
Sep 22, 2026
Merged

mrcsin merged 1 commit into
masterfrom
opctreemanager-opcfbpath-resolution

Conversation

@mrcsin

@mrcsin mrcsin commented Sep 22, 2026

Copy link
Copy Markdown
Member

Summary

GetProtocol took the configured OpcFbPath, and when no OPC UA FB node sat there it stripped the last segment and searched the parent, up to the tree root. A path naming a child of the FB node, or any path with a wrong segment in the middle, silently resolved to an ancestor: the module then worked against a node the operator never wrote, and the log reported that node rather than the setting. A wrong first segment walked to the root and failed with or any of its ancestors, which says nothing about where the path went wrong.

The operator names the node directly in the property grid, so the path is now taken as written. A miss fails with No OPC UA FB node at path 'X'. OpcFbPath must name the OPC UA FB node itself.

No new setting and nothing to fill in differently: OpcFbPath is the same property, with the same default Система.АРМ.OPC UA Siemens. Only the behaviour on a wrong value changes.

Type of change

  • fix — bug fix

Changes

  • GetProtocol takes a Func<string, ITreeItemHlp?> resolver instead of IProjectHlp, matching the seam already used by TreeReshaper, PlanExecutor and ProjectSubtreeDisconnector. That is what makes the refusal testable.
  • the property description in the FB says the path must name the node itself

Changes touching FB code

  • XML pin IDs match the const int *PinId constants in the FB class
  • New runtime-only fields carry [NonSerialized]
  • [ComVisible(true)] + [Guid] untouched on existing FBs
  • Read Docs/architecture/masterscada-fb-primer.md and Docs/architecture/architecture.md
  • Checked Docs/known_issues/

Testing

  • dotnet build NtoLib.sln — 0 errors, 0 warnings
  • dotnet test NtoLib.sln — 373 passed
  • dotnet format NtoLib.sln --verify-no-changes — exit 0
  • Manual host smoke 2026-09-22 with a correct path: group resolved, 23 nodes constructed

GetProtocol_PathBelowTheFbNode_Fails asserts the refusal sentence, not just IsFailed. Verified by experiment: reinstating the ancestor walk restores the old behaviour and the test goes red. Asserting IsFailed alone did not discriminate, because the walk found the node and then failed later on Instance is null.

GetProtocol took the configured OpcFbPath, and when no OPC UA FB node sat there
it stripped the last segment and searched the parent, up to the tree root. A
path naming a child of the FB node, or any path with a wrong segment in the
middle, silently resolved to an ancestor: the module then worked against a node
the operator never wrote, and the log reported that node rather than the
setting. A wrong first segment walked to the root and failed with "or any of its
ancestors", which says nothing about where the path went wrong.

The operator names the node directly in the property grid, so the path is now
taken as written. A miss fails with "No OPC UA FB node at path 'X'. OpcFbPath
must name the OPC UA FB node itself."

GetProtocol takes a Func<string, ITreeItemHlp?> resolver instead of IProjectHlp,
matching the seam used by TreeReshaper, PlanExecutor and
ProjectSubtreeDisconnector, which is what makes the refusal testable.
@mrcsin
mrcsin merged commit 1d8eb4c into master Sep 22, 2026
1 check passed
@mrcsin
mrcsin deleted the opctreemanager-opcfbpath-resolution branch September 22, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant