Skip to content

feat(opcua): populate order_code identity field from the device nameplate#499

Open
mfaferek93 wants to merge 2 commits into
mainfrom
feat/opcua-identity-order-code
Open

feat(opcua): populate order_code identity field from the device nameplate#499
mfaferek93 wants to merge 2 commits into
mainfrom
feat/opcua-identity-order-code

Conversation

@mfaferek93

Copy link
Copy Markdown
Collaborator

Adds a typed order_code identity field and populates it from the OPC UA device nameplate.

  • AssetIdentity: new order_code field (AAS ManufacturerOrderCode, distinct from model = ManufacturerProductDesignation), wired through to_json (orderCode), from_json, empty(), equality, and the merge field set so it merges with per-field provenance.
  • OPC UA device-info reader: reads the OrderNumber nameplate node by BrowseName across namespaces (vendors expose it outside the standard DI namespace), trimming fixed-width padding on that vendor field. Standard DI fields are still read raw (no regression).
  • Manifest / CSV inventory: order_code / order_number alias maps to the typed field.
  • test_alarm_server fixture now exposes a vendor-namespace, space-padded OrderNumber, so the cross-namespace read and trim are covered by the identity tests.

Closes #498.

Copilot AI review requested due to automatic review settings July 4, 2026 17:02
Add a typed order_code field (AAS ManufacturerOrderCode) to AssetIdentity,
distinct from model, and read it from the DI device OrderNumber node by
BrowseName across namespaces. Verified on a Siemens CPU 1505SP F.
@mfaferek93 mfaferek93 force-pushed the feat/opcua-identity-order-code branch from a4622ae to 276b66b Compare July 4, 2026 17:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an order_code field to the gateway’s asset identity model and wires it end-to-end (OPC UA device-info read → identity mapping/merge → REST JSON), including manifest/CSV import and expanded test coverage to validate cross-namespace OrderNumber reads and per-field provenance behavior.

Changes:

  • Extend AssetIdentity with typed order_code (AAS ManufacturerOrderCode) and include it in JSON serialization, merge, and inventory/manifest parsing.
  • Enhance the OPC UA plugin/client to read device nameplate (BuildInfo + DI nameplate + vendor OrderNumber), cache it per session, and refresh after reconnect with trust-gated source precedence.
  • Add/expand unit + integration tests and docs to cover the new identity behavior and stability in CI.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tsan_suppressions.txt Suppresses a benign TSan race triggered by open62541/glibc timezone lazy init.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/yaml_utils.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/vector_utils.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/typesupport.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/types.h Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/string_utils.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/msg_parser.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/message_reading.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_serialization/include/ros2_medkit_serialization/vendored/dynmsg/config.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_plugins/ros2_medkit_opcua/test/test_opcua_identity.cpp New end-to-end identity test using the alarm-server fixture to validate device-info reads, trimming, and reconnect refresh.
src/ros2_medkit_plugins/ros2_medkit_opcua/test/test_device_identity.cpp New unit tests for DeviceInfo→AssetIdentity mapping and trust-gated identity precedence.
src/ros2_medkit_plugins/ros2_medkit_opcua/test/integration/test_opcua_secured.test.py Relaxes a wait deadline to reduce flakes on slow CI runners.
src/ros2_medkit_plugins/ros2_medkit_opcua/test/fixtures/test_alarm_server/test_alarm_server.cpp Extends the fixture with pinned BuildInfo, DI nameplate, vendor OrderNumber, and browse paging controls.
src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_plugin.cpp Populates component identity from OPC UA device-info with per-session caching and trust-gated source.
src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp Adds per-session generation counter and implements BuildInfo + DI + vendor OrderNumber device-info reads (with BrowseNext continuation handling).
src/ros2_medkit_plugins/ros2_medkit_opcua/src/device_identity.cpp New mapping/trust-gate implementation for OPC UA device identity.
src/ros2_medkit_plugins/ros2_medkit_opcua/README.md Documents identity population and trust-gated precedence for the OPC UA plugin.
src/ros2_medkit_plugins/ros2_medkit_opcua/include/ros2_medkit_opcua/opcua_poller.hpp Disables move operations (likely to avoid accidental moves of threaded state).
src/ros2_medkit_plugins/ros2_medkit_opcua/include/ros2_medkit_opcua/opcua_plugin.hpp Stores cached device identity + generation; disables copy/move.
src/ros2_medkit_plugins/ros2_medkit_opcua/include/ros2_medkit_opcua/opcua_client.hpp Adds connection_generation() API and DeviceInfo + read_device_info() interface; disables move.
src/ros2_medkit_plugins/ros2_medkit_opcua/include/ros2_medkit_opcua/device_identity.hpp New public header for DeviceInfo→AssetIdentity mapping and trust gating.
src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt Adds new sources/tests, and marks open62541 headers as SYSTEM for warning hygiene; adjusts test timeouts.
src/ros2_medkit_gateway/test/test_manifest_parser.cpp Adds coverage for manifest identity: parsing and provenance stamping.
src/ros2_medkit_gateway/test/test_discovery_handlers.cpp Adds coverage for emitting x-medkit.identity and provenance in list/detail component endpoints.
src/ros2_medkit_gateway/test/test_asset_inventory.cpp Adds CSV header aliasing tests for order_code/order_number mapping and provenance.
src/ros2_medkit_gateway/test/test_asset_identity.cpp Adds serialization/round-trip and merge tests for the new order_code field and trust-gated plugin precedence.
src/ros2_medkit_gateway/src/vendored/tl_expected/include/tl/expected.hpp Marks vendored header region with NOLINT to avoid lint noise.
src/ros2_medkit_gateway/src/http/handlers/discovery_handlers.cpp Emits x-medkit.identity in component list/detail responses when present.
src/ros2_medkit_gateway/src/discovery/manifest/manifest_parser.cpp Parses optional manifest identity: into AssetIdentity and stamps provenance.
src/ros2_medkit_gateway/src/core/discovery/manifest/asset_inventory.cpp Maps order_code/order_number into structured identity + provenance via inventory parsing.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/dto/x_medkit.hpp Adds optional identity field to x-medkit DTO output.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/discovery/models/asset_identity.hpp Adds typed order_code field and includes it in JSON/empty/equality logic.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/discovery/manifest/manifest_parser.hpp Declares manifest identity parsing API.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/discovery/manifest/asset_inventory.hpp Extends inventory model/schema with order_code and alias documentation.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/discovery/identity_merge.hpp Updates merge precedence and adds order_code to merge field set.
docs/config/manifest-schema.rst Documents manifest identity: block (needs update for order_code).
docs/api/rest.rst Documents x-medkit.identity REST shape and provenance behavior.
Comments suppressed due to low confidence (1)

src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp:792

  • In create_subscription(), the newly created Subscription is copied into subscriptions, and the local sub is then destroyed when the function returns. Elsewhere in this file you rely on the open62541pp Subscription destructor / deleteSubscription semantics (see remove_subscriptions()), so copying here risks the stored subscription being torn down immediately (or double-deleted later). This should be moved into the container as before.
    auto sub = impl_->client.createSubscription(params);
    uint32_t sub_id = sub.subscriptionId();

    std::lock_guard<std::mutex> sub_lock(impl_->sub_mutex);
    impl_->subscriptions.push_back({sub, std::move(callback)});

@mfaferek93 mfaferek93 self-assigned this Jul 4, 2026

@bburda bburda left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs not updated for the new order_code field. It is a distinct typed field now, so several places that enumerate the identity or column set are stale, and two still label model as the order code, which contradicts the code:

  • src/ros2_medkit_gateway/README.md, Asset Identity nameplate table: no row for order_code / orderCode / ManufacturerOrderCode, and the model row is still marked "(order code)".
  • docs/config/manifest-schema.rst: the identity: block, the identity-keys list, the assets: block, the alias list, and the CSV "canonical columns" list all omit order_code / order_number; the model lines still say "model / order code".
  • asset_inventory.hpp: the parse_asset_csv canonical-names docstring and the asset_entry_to_component identity-map docstring both omit order_code, but the code maps it.
  • src/ros2_medkit_gateway/src/gateway_node.cpp: the discovery.inventory.csv_path parameter comment lists the columns without order_code.

The E2E order-code fixture only padded the trailing edge with no internal
space, so a whitespace-collapsing trim would not have failed any test. Use
the real Siemens MLFB with leading + trailing pad and an internal space, and
assert the read order_code keeps that space.
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.

opcua: asset identity is missing the device order code

3 participants