Skip to content

feat: Add TIME type support for OPC-UA plugin#82

Merged
marconetsf merged 6 commits into
RTOP-100-OPC-UAfrom
feature/opcua-time-variable
Jan 21, 2026
Merged

feat: Add TIME type support for OPC-UA plugin#82
marconetsf merged 6 commits into
RTOP-100-OPC-UAfrom
feature/opcua-time-variable

Conversation

@marconetsf
Copy link
Copy Markdown
Contributor

@marconetsf marconetsf commented Jan 20, 2026

Summary

  • Add support for IEC 61131-3 TIME, DATE, TOD, and DT types in the OPC-UA plugin
  • TIME/TOD types are represented as Int64 milliseconds in OPC-UA for broad client compatibility
  • DATE/DT types map to native OPC-UA DateTime
  • Includes comprehensive unit tests (71 new tests, all 127 tests pass)

Changes

Core Implementation

  • opcua_memory.py: Added IEC_TIMESPEC ctypes structure, read_timespec_direct(), write_timespec_direct(), updated read_memory_direct() with datatype hint
  • opcua_utils.py: Added TIME_DATATYPES, conversion helpers (timespec_to_milliseconds, milliseconds_to_timespec), TIME type mappings, TIME handling in value conversions
  • synchronization.py: Updated to pass datatype for TIME handling, added TIME-specific write logic via direct memory access

Configuration

  • opcua_config_model.py: Added VALID_DATATYPES constant with TIME types, datatype validation in config
  • opcua_config_template.json: Added TIME variable examples

Tests

  • test_type_conversions.py: Added 48 new TIME tests (mappings, conversions, roundtrips, helper functions)
  • test_memory.py: Added 23 new TIME tests (structure, read/write, datatype hint)

Design Decisions

Decision Rationale
TIME -> Int64 (ms) Broad OPC-UA client compatibility, sufficient precision for PLC apps
DATE/DT -> DateTime Native OPC-UA type for date values
Millisecond precision Nanoseconds truncated when converting to OPC-UA (acceptable tradeoff)
IEC_TIMESPEC struct Matches C runtime definition (tv_sec, tv_nsec)

Test plan

  • All 127 unit tests pass
  • Manual test with OPC-UA client (UaExpert) to verify TIME variable read/write
  • Test with actual PLC program using TIME variables

🤖 Generated with Claude Code

marconetsf and others added 4 commits January 19, 2026 10:08
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>
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>
- 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>
Copy link
Copy Markdown
Contributor Author

@marconetsf marconetsf left a comment

Choose a reason for hiding this comment

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

PR Review Summary

Great work on this PR! The implementation is solid, well-tested, and follows the project's coding standards. I've added a few inline comments for minor improvements that can be addressed in a follow-up if desired.

Overall Assessment:APPROVED

See full review document: docs/pr-reviews/PR_82_REVIEW.md

Strengths

  • Well-designed architecture matching IEC 61131-3 specification
  • Excellent test coverage (71 new tests)
  • Comprehensive development plan document
  • Backward compatible API changes
  • Good error handling with safe defaults

Minor Issues (non-blocking)

  1. Duplicate TIME_DATATYPES constant in two files
  2. Type hints could be more precise (tuple -> tuple[int, int])
  3. Silent error handling in TOD conversion could benefit from logging

@marconetsf
Copy link
Copy Markdown
Contributor Author

Minor Issues Found (Non-blocking)

These are suggestions for future improvement - not blocking merge.


1. Duplicate constant definition

  • File: core/src/drivers/plugins/python/opcua/opcua_utils.py:22
  • Issue: TIME_DATATYPES is also defined in opcua_memory.py:54
  • Suggestion: Import from a single location to avoid duplication:
# Option: Import from opcua_memory instead of defining here
from .opcua_memory import TIME_DATATYPES

2. Type hint could be more precise

  • File: core/src/drivers/plugins/python/opcua/opcua_utils.py:199
  • Function: milliseconds_to_timespec
  • Suggestion: Use tuple[int, int] instead of tuple:
def milliseconds_to_timespec(ms: int) -> tuple[int, int]:

3. Type hint could be more precise

  • File: core/src/drivers/plugins/python/opcua/opcua_memory.py:114
  • Function: read_timespec_direct
  • Suggestion: Use tuple[int, int] instead of tuple:
def read_timespec_direct(address: int) -> tuple[int, int]:

4. Silent error handling in TOD conversion

  • File: core/src/drivers/plugins/python/opcua/opcua_utils.py:156
  • Issue: Invalid TOD values (e.g., hours >= 24) silently default to midnight
  • Suggestion: Add warning log for debugging:
except (ValueError, OverflowError) as e:
    log_warn(f"Invalid TOD value (hours={hours}), using midnight: {e}")
    return datetime(today.year, today.month, today.day, tzinfo=timezone.utc)

Full review document available at: docs/pr-reviews/PR_82_REVIEW.md

@marconetsf marconetsf requested a review from Copilot January 21, 2026 17:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive support for IEC 61131-3 TIME-related data types (TIME, DATE, TOD, DT) to the OPC-UA plugin. TIME/TOD types are represented as Int64 milliseconds in OPC-UA for broad client compatibility, while DATE/DT types map to native OPC-UA DateTime. The implementation includes ctypes structure definitions, memory access functions, type conversions, and extensive test coverage.

Changes:

  • Added IEC_TIMESPEC ctypes structure and TIME-specific memory read/write functions
  • Implemented TIME type mappings and bidirectional conversion helpers between PLC timespec format and OPC-UA representations
  • Updated synchronization logic to handle TIME values via direct memory access and pass datatype hints for proper TIME handling
  • Added datatype validation and TIME variable examples to configuration

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/pytest/plugins/opcua/test_type_conversions.py Added 48 comprehensive unit tests covering TIME type mappings, conversions, roundtrips, and helper functions
tests/pytest/plugins/opcua/test_memory.py Added 23 unit tests for IEC_TIMESPEC structure, TIME memory operations, and datatype hint handling
docs/plans/TIME_TYPE_SUPPORT_PLAN.md Added detailed development and test plan documenting TIME type support implementation
core/src/drivers/plugins/python/shared/plugin_config_decode/opcua_config_model.py Added VALID_DATATYPES constant and datatype validation for TIME types in configuration
core/src/drivers/plugins/python/opcua/synchronization.py Updated to pass datatype hints and handle TIME writes via direct memory access
core/src/drivers/plugins/python/opcua/opcua_utils.py Added TIME_DATATYPES constant, conversion helpers, type mappings, and TIME handling in value conversions
core/src/drivers/plugins/python/opcua/opcua_memory.py Added IEC_TIMESPEC structure, read/write functions, and datatype parameter to read_memory_direct
core/src/drivers/plugins/python/opcua/opcua_config_template.json Added three TIME variable examples demonstrating usage patterns

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/src/drivers/plugins/python/opcua/opcua_config_template.json Outdated
Comment thread tests/pytest/plugins/opcua/test_type_conversions.py Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Autonomy-Logic Autonomy-Logic deleted a comment from Copilot AI Jan 21, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@marconetsf marconetsf merged commit a7d4199 into RTOP-100-OPC-UA Jan 21, 2026
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.

2 participants