Rtop 100 opc ua#69
Merged
Merged
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ttps://github.com/Autonomy-Logic/openplc-runtime into RTOP-106-Create-multiple-addr-access-debug-function
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* get_var_list available at runtime api arg * adding get_var_list and var_size in python side * adding read and write function with typecheck * Update core/src/drivers/plugins/python/shared/python_plugin_types.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/src/drivers/plugins/python/shared/python_plugin_types.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * adding get_var_count to runtime api for python * Update core/src/drivers/plugin_utils.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/src/drivers/plugins/python/shared/python_plugin_types.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/src/drivers/plugins/python/shared/python_plugin_types.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * refact safe buffer access * Update core/src/drivers/plugins/python/shared/debug_utils.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * imports at top of the file accordingly with PEP 8 * deleting unecessary singleton logic for bufferType accessing --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…using refactored safebufferaccess
…ents - Introduced `opcua_memory.py` for direct memory access functions. - Created `opcua_types.py` for type definitions including `VariableNode` and `VariableMetadata`. - Added utility functions in `opcua_utils.py` for type mapping and value conversion. - Refactored `opcua_plugin.py` to utilize new memory access and utility functions.
…A and PLC runtime
…cua-time-variable
- DATE: Now extracts only the date portion, setting time to 00:00:00 (ignores HH:MM:SS from the IEC_TIMESPEC value) - TOD: Now uses current date (today) + time from IEC_TIMESPEC (ignores YYYY-MM-DD, only uses HH:MM:SS) Changed mapping from Int64 to DateTime for better OPC-UA client compatibility - DT: Unchanged - full DateTime conversion (both date and time) - TIME: Unchanged - Int64 milliseconds representation Updated tests to reflect the new behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: Add TIME type support for OPC-UA plugin Add support for IEC 61131-3 TIME, DATE, TOD, and DT types in the OPC-UA plugin: - Add IEC_TIMESPEC ctypes structure matching C definition (tv_sec, tv_nsec) - Implement TIME type mapping to OPC-UA Int64 (milliseconds) - Implement DATE/DT type mapping to OPC-UA DateTime - Add timespec_to_milliseconds and milliseconds_to_timespec conversion functions - Update convert_value_for_opcua/plc functions to handle TIME types - Add read_timespec_direct and write_timespec_direct memory access functions - Update synchronization to pass datatype hint for TIME handling - Add datatype validation in config model with VALID_DATATYPES constant - Add TIME variable examples to config template TIME values are represented as Int64 milliseconds in OPC-UA, which provides good compatibility with standard OPC-UA clients while maintaining reasonable precision for PLC applications. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Add unit tests for TIME type support Add comprehensive unit tests for the new TIME type support: Type conversion tests (test_type_conversions.py): - TIME/TOD/DATE/DT type mappings to OPC-UA types - TIME conversion from tuple to milliseconds - TIME conversion from milliseconds to tuple - TIME roundtrip conversion tests - timespec_to_milliseconds helper function tests - milliseconds_to_timespec helper function tests - TIME_DATATYPES constant tests Memory access tests (test_memory.py): - IEC_TIMESPEC structure tests (size, fields, initialization) - read_timespec_direct function tests - write_timespec_direct function tests - read_memory_direct with TIME datatype hint tests - Roundtrip read/write tests for TIME values All 127 tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Improve DATE and TOD type conversions for OPC-UA - DATE: Now extracts only the date portion, setting time to 00:00:00 (ignores HH:MM:SS from the IEC_TIMESPEC value) - TOD: Now uses current date (today) + time from IEC_TIMESPEC (ignores YYYY-MM-DD, only uses HH:MM:SS) Changed mapping from Int64 to DateTime for better OPC-UA client compatibility - DT: Unchanged - full DateTime conversion (both date and time) - TIME: Unchanged - Int64 milliseconds representation Updated tests to reflect the new behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update core/src/drivers/plugins/python/opcua/opcua_config_template.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update tests/pytest/plugins/opcua/test_type_conversions.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
psutil fails to install on MSYS2/Cygwin with "platform cygwin is not supported" error. Use pip environment marker to skip psutil on cygwin platforms while keeping it for Linux/macOS/native Windows. The opcua_endpoints_config.py code already has socket-based fallbacks when psutil is unavailable, so functionality is preserved on all platforms. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cryptography (required by asyncua) cannot be built from source on MSYS2/Cygwin. This adds two changes to enable OPC-UA plugin on MSYS2: 1. Install python-cryptography via pacman in install_deps_msys2() 2. Create plugin venvs with --system-site-packages on MSYS2 so pip can use the pre-built system cryptography package Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When existing venvs were created before the MSYS2 fix, they lack --system-site-packages and pip still tries to build cryptography. This adds detection to check pyvenv.cfg for system-site-packages flag and automatically recreates the venv with proper flags on MSYS2. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ckages" This reverts commit df7b066.
bcrypt is also a Rust-based package that cannot be built on MSYS2/Cygwin. Install it via pacman alongside cryptography. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
python-bcrypt package doesn't exist in MSYS2 repos and pip can't build it (Rust-based). The OPC-UA plugin already handles missing bcrypt gracefully by disabling password authentication - users can use certificate-based authentication instead. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use the correct MSYS2 package name for bcrypt (mingw-w64-x86_64-python-bcrypt). This enables password authentication on MSYS2 builds. Also reverts making bcrypt optional since it's now available via pacman. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ame issues (#86) * fix: Auto-detect local IPs for OPC-UA certificate SAN entries When running in Docker containers, the auto-generated OPC-UA server certificate only included the container hostname in the Subject Alternative Name (SAN). This caused BadCertificateHostNameInvalid errors when clients connected via IP address. Changes: - Add get_local_ip_addresses() to auto-detect all local IPs - Add generate_certificate_with_sans() for certificates with multiple DNS names and IP addresses in SANs - Update certificate generation to include all detected local IPs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Use PKCS8 format for private key to fix asyncua compatibility The TraditionalOpenSSL format caused parsing errors when asyncua tried to load the private key. PKCS8 format is required by asyncua. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Convert certificate to DER format for asyncua compatibility asyncua's load_certificate was failing with PEM format. Convert both certificate and private key to DER format before loading into the server. Also improved error messages for better debugging. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Add CLIENT_AUTH to certificate Extended Key Usage for OPC-UA OPC-UA certificates require both SERVER_AUTH and CLIENT_AUTH in the Extended Key Usage extension. Missing CLIENT_AUTH caused BadCertificateUseNotAllowed errors when clients connected. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Enable nonRepudiation (content_commitment) in certificate Key Usage OPC-UA specification (OPC 10000-6 6.2.2) requires certificates to have keyUsage including: digitalSignature, nonRepudiation, keyEncipherment, and dataEncipherment. The missing nonRepudiation flag caused BadCertificateUseNotAllowed errors. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Improve IP address detection code quality - Use ipaddress.is_link_local for proper link-local address filtering instead of string prefix check (handles both IPv4 and IPv6) - Add named constants for ioctl magic numbers (_SIOCGIFCONF, _SIZEOF_IFREQ, _MAX_INTERFACES) for better code readability Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Extend certificate validity to 10 years and auto-regenerate expired certs - Change default certificate validity from 365 days to 3650 days (10 years) - Add _is_certificate_valid() method to check if certificate is still valid - Add _remove_certificate_files() method to remove expired certificate files - Update _ensure_server_certificates() to check validity and regenerate if expired - Update _setup_server_certificates_for_asyncua() with same validity check logic - Remove unused iface_name variable to fix ruff lint warning Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Address Copilot PR review comments for certificate generation - Remove async from generate_certificate_with_sans (no await operations) - Remove deprecated default_backend() from all cryptography calls - Remove redundant imports in _validate_certificate_format - Add restricted permissions (0o600) for private key files - Document 10-year validity rationale in docstring Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…tibility Rust/pyo3-based packages like bcrypt cannot be built on plain MSYS environment due to fundamental linking issues with Python symbols. Changes: - requirements.txt: Add sys_platform marker to skip bcrypt on cygwin - install.sh: Only install mingw-w64-x86_64-python-bcrypt on MINGW64 On plain MSYS, password authentication for OPC-UA will be disabled. Users needing full functionality should use MINGW64 environment. The user_manager.py already has graceful fallback when bcrypt is unavailable. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… incompatibility" This reverts commit 7c8ee45.
bcrypt cannot be built on MSYS2/Cygwin due to Rust/pyo3 linking issues. This adds PBKDF2-HMAC-SHA256 as a fallback using Python's stdlib hashlib. Changes: - requirements.txt: Skip bcrypt on cygwin platform - user_manager.py: Add PBKDF2 hashing/verification functions - Automatically detects hash type (bcrypt vs PBKDF2) - Uses 600000 iterations per OWASP recommendation - Constant-time comparison to prevent timing attacks - install.sh: Remove mingw-w64-x86_64-python-bcrypt (doesn't work on plain MSYS) Behavior by platform: - Linux/macOS: Uses bcrypt (preferred) - MSYS2/Cygwin: Uses PBKDF2 (stdlib, no external dependencies) Both hash formats are supported for verification, enabling cross-platform password portability. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix validation error when adding Function Block instances to OPC-UA address space. The previous validation only checked the first level of fields, causing errors like "Invalid datatype 'TON'" for nested FB instances. Changes: - Add recursive validate_field_datatypes() that only validates leaf fields (those without nested children) - Complex types (FBs, nested structs) are skipped, only their leaf children are validated - Add missing IEC 61131-3 base types to VALID_DATATYPES: SINT, USINT, UINT, UDINT, ULINT, LREAL, WORD, DWORD, LWORD The validation now mirrors the recursive pattern used for index collection (collect_field_indices). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add null-check on datatype for defensive coding - Include full field path in error messages for easier debugging (e.g., "TON0.ET" instead of just "ET") Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…-validation fix: Add recursive validation for nested OPC-UA structures
Remove per-variable debug logging that would generate excessive output during sync cycles. Removed messages for variable changes, array element changes, and TIME variable writes. These debug messages add overhead to the hot sync path and clutter logs during development/testing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…y access Security fixes: - Fix username attribute mismatch: User object uses 'name' not 'username', causing audit logs to show "unknown" instead of actual username - Change permission default from fail-open to fail-closed: nodes without configured permissions now deny writes instead of allowing them - Add memory address validation to prevent segfaults from invalid addresses (NULL, negative, or reserved memory region) The fail-open issue was a security vulnerability where unconfigured nodes would allow writes from any authenticated user or anonymous client. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
thiagoralves
approved these changes
Jan 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces several improvements and new features to the plugin driver system and the OPC UA Python plugin. The main focus is on enhancing plugin variable access, improving resource management for plugins, and adding a well-structured OPC UA address space builder for Python plugins. The changes also include the addition of utility functions for variable access and updates to the build system to support these new utilities.
Plugin system enhancements:
get_var_list,get_var_size,get_var_count) for accessing PLC variables, exposed via the plugin driver and implemented in the newplugin_utils.candplugin_utils.hfiles. These functions allow plugins to efficiently query variable addresses, sizes, and counts. (core/src/drivers/plugin_utils.c[1]core/src/drivers/plugin_utils.h[2]core/src/drivers/plugin_types.h[3]core/src/drivers/plugin_driver.c[4]plugin_utils.csource file in the build process, ensuring the utility functions are available to the plugin system. (core/src/CMakeLists.txtcore/src/CMakeLists.txtR42)core/src/drivers/plugin_driver.c[1] [2] [3]stdint.hto support new utility function signatures. (core/src/drivers/plugin_types.h[1]core/src/drivers/plugin_driver.c[2]OPC UA Python plugin improvements:
__init__.pyto the OPC UA plugin package, documenting its architecture and re-exporting main entry points for runtime compatibility. (core/src/drivers/plugins/python/opcua/__init__.pycore/src/drivers/plugins/python/opcua/init.pyR1-R31)address_space.pymodule implementing theAddressSpaceBuilderclass. This class programmatically builds the OPC UA address space from configuration, including support for simple variables, structures, and arrays, and manages permissions and node mappings for efficient access and synchronization. (core/src/drivers/plugins/python/opcua/address_space.pycore/src/drivers/plugins/python/opcua/address_space.pyR1-R389)For testing purpose, there is a openplc-runtime/tests/pytest/plugins/opcua that contains the editor zip with the following images plc program variables. It also contains client certs to use with any uaclient software (uaexpert recommended)
You can upload the zip through postman and then connect to the opcua server following the this sequence
About configuration json, there is a guide (openplc-runtime/core/src/drivers/plugins/python/opcua/OPCUA_CONFIGURATION_GUIDE.md) that explains each field and also within the zipped project there is the current configuration file for this project that contains all data types and structures tested. It will help for a better understanding for the front-end creation.