-
Notifications
You must be signed in to change notification settings - Fork 958
feat(opcua): support constant datapoints (attributes + one-time telemetry) #1982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(opcua): support constant datapoints (attributes + one-time telemetry) #1982
Conversation
…emetry) Parse/store type: constant datapoints; send constant attributes on device creation and reconnection; send constant telemetry once per device per process; type inference (bool/int/float/string) with gateway timestamp; respect reportStrategy via TBUtility.convert_key_to_datapoint_key; backward compatible path/identifier behavior.
…ime telemetry) Add fixture config and unit test validating parsing buckets and idempotent constant telemetry send.
|
Hi @palandri, thanks for your contribution! We really appreciate it. |
|
Hello @samson0v. Do not worry, there is no hurry. Cheers. |
|
Hi @palandri, I am reviewing your PR and have a question about this: Why did you decide to use different strategies for sending? |
| new_device = Device(path=device_path, name=device_name, device_profile=device_profile, | ||
| config=device_config, | ||
| converter=converter(device_config, self.__converter_log), | ||
| converter_for_sub=converter(device_config, self.__converter_log) if self.__enable_subscriptions else None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, fix formatting
| has_attributes = False | ||
| has_telemetry = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can check these using ConvertedData telemetry_datapoints_count and attributes_datapoints_count
| converted_data = ConvertedData(device_name=device.name, device_type=device.device_profile) | ||
|
|
||
| # Constant attributes | ||
| for entry in getattr(device, 'constant_attributes', []): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to check?
| # Constant telemetry (send once per device name per process) | ||
| if device.name not in self.__constant_telemetry_sent_devices: | ||
| telemetry_values = {} | ||
| for entry in getattr(device, 'constant_timeseries', []): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to check?
| has_telemetry = True | ||
| self.__constant_telemetry_sent_devices.add(device.name) | ||
|
|
||
| if has_attributes or has_telemetry: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment above
|
📢 a little announcement: |
feat(opcua): support constant datapoints (attributes + one-time telemetry)
Summary
Adds first-class support for constant datapoints in the OPC-UA connector:
Motivation
Previously, OPC-UA mapping handled datapoints backed by NodeId or path expressions but ignored constants. This feature enables:
Implementation Details
python.Device.load_values().python.OpcUaConnector.__send_constants_for_device().python.OpcUaConnector._create_new_devices().thingsboard_gateway/connectors/opcua/opcua_connector.py.python.TBUtility.convert_key_to_datapoint_key().python.OpcUaConnector.__guess_type_and_cast().python.TelemetryEntry.__init__().Behavior
Configuration Example (new mapping format)
{ "mapping": [ { "deviceNodePattern": "Root\\.Objects\\.Device1", "deviceInfo": { "deviceNameExpressionSource": "path", "deviceNameExpression": "Device ${Root\\.Objects\\.Device1\\.serialNumber}", "deviceProfileExpressionSource": "constant", "deviceProfileExpression": "default" }, "attributes": [ { "key": "Customer", "type": "constant", "value": "ACME Corp" } ], "timeseries": [ { "key": "InitialBatchSize", "type": "constant", "value": "12" } ] } ] }Casting Rules
Backward Compatibility
Tests / Verification
tests/unit/connectors/opcua/test_constants.pytests/unit/connectors/opcua/data/constants/opcua_config_constants.jsontests/blackbox/data/opcua/configs/uplink_configs/constants_config.jsonDocumentation Impact
Touched Code
thingsboard_gateway/connectors/opcua/device.pypython.Device.load_values()python.OpcUaConnector.__send_constants_for_device()python.OpcUaConnector._create_new_devices()python.OpcUaConnector.__guess_type_and_cast()python.TBUtility.convert_key_to_datapoint_key()python.TelemetryEntry.__init__()tests/unit/connectors/opcua/test_constants.pytests/unit/connectors/opcua/data/constants/opcua_config_constants.jsontests/blackbox/data/opcua/configs/uplink_configs/constants_config.jsonChecklist