Skip to content

Commit

Permalink
Merge pull request #1419 from samson0v/issues/iotgw-184
Browse files Browse the repository at this point in the history
Deleted deprecated OPC-UA connector and made OPC-UA async default connector
  • Loading branch information
imbeacon committed Jun 3, 2024
2 parents e6044fe + d7ba7b1 commit 48fa3af
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 1,423 deletions.
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@
'thingsboard_gateway.storage', 'thingsboard_gateway.storage.memory', 'thingsboard_gateway.gateway.shell',
'thingsboard_gateway.storage.file', 'thingsboard_gateway.storage.sqlite',
'thingsboard_gateway.connectors', 'thingsboard_gateway.connectors.ble', 'thingsboard_gateway.connectors.socket',
'thingsboard_gateway.connectors.mqtt', 'thingsboard_gateway.connectors.opcua_asyncio', 'thingsboard_gateway.connectors.xmpp',
'thingsboard_gateway.connectors.mqtt', 'thingsboard_gateway.connectors.xmpp',
'thingsboard_gateway.connectors.opcua', 'thingsboard_gateway.connectors.request', 'thingsboard_gateway.connectors.ocpp',
'thingsboard_gateway.connectors.modbus', 'thingsboard_gateway.connectors.can', 'thingsboard_gateway.connectors.bacnet',
'thingsboard_gateway.connectors.bacnet.bacnet_utilities', 'thingsboard_gateway.connectors.odbc',
'thingsboard_gateway.connectors.rest', 'thingsboard_gateway.connectors.snmp', 'thingsboard_gateway.connectors.ftp',
'thingsboard_gateway.tb_utility', 'thingsboard_gateway.extensions',
'thingsboard_gateway.extensions.mqtt', 'thingsboard_gateway.extensions.modbus', 'thingsboard_gateway.extensions.opcua',
'thingsboard_gateway.extensions.opcua_asyncio', 'thingsboard_gateway.extensions.ocpp',
'thingsboard_gateway.extensions.ble', 'thingsboard_gateway.extensions.serial', 'thingsboard_gateway.extensions.request',
'thingsboard_gateway.extensions.ocpp', 'thingsboard_gateway.extensions.ble',
'thingsboard_gateway.extensions.serial', 'thingsboard_gateway.extensions.request',
'thingsboard_gateway.extensions.can', 'thingsboard_gateway.extensions.bacnet', 'thingsboard_gateway.extensions.odbc',
'thingsboard_gateway.extensions.rest', 'thingsboard_gateway.extensions.snmp', 'thingsboard_gateway.extensions.ftp',
'thingsboard_gateway.extensions.socket', 'thingsboard_gateway.extensions.xmpp',
Expand Down
13 changes: 0 additions & 13 deletions thingsboard_gateway/connectors/opcua/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +0,0 @@
# Copyright 2024. ThingsBoard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
1,085 changes: 460 additions & 625 deletions thingsboard_gateway/connectors/opcua/opcua_connector.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion thingsboard_gateway/connectors/opcua/opcua_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@

class OpcUaConverter(Converter):
@abstractmethod
def convert(self, config, val, data = None):
def convert(self, config, val):
pass
105 changes: 67 additions & 38 deletions thingsboard_gateway/connectors/opcua/opcua_uplink_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,79 @@
from datetime import timezone

from thingsboard_gateway.connectors.opcua.opcua_converter import OpcUaConverter
from thingsboard_gateway.tb_utility.tb_utility import TBUtility
from thingsboard_gateway.gateway.statistics_service import StatisticsService
from asyncua.ua.uatypes import LocalizedText, VariantType

DATA_TYPES = {
'attributes': 'attributes',
'timeseries': 'telemetry'
}


class OpcUaUplinkConverter(OpcUaConverter):
def __init__(self, config, logger):
self._log = logger
self.__config = config
self.data = {
'deviceName': self.__config['device_name'],
'deviceType': self.__config['device_type'],
'attributes': [],
'telemetry': [],
}
self._last_node_timestamp = 0

def clear_data(self):
self.data = {
'deviceName': self.__config['device_name'],
'deviceType': self.__config['device_type'],
'attributes': [],
'telemetry': [],
}

def get_data(self):
if len(self.data['attributes']) or len(self.data['telemetry']):
data_list = []
device_names = self.__config.get('device_names')
if device_names:
for device in device_names:
self.data['deviceName'] = device
data_list.append(self.data)

return data_list

return [self.data]

return None

@property
def config(self):
return self.__config

@config.setter
def config(self, value):
self.__config = value

@StatisticsService.CollectStatistics(start_stat_type='receivedBytesFromDevices',
end_stat_type='convertedBytesFromDevice')
def convert(self, config, val, data=None, key=None):
information = config[0]
information_type = config[1]
device_name = self.__config["deviceName"]
result = {"deviceName": device_name,
"deviceType": self.__config.get("deviceType", "OPC-UA Device"),
"attributes": [],
"telemetry": [], }
try:
information_types = {"attributes": "attributes", "timeseries": "telemetry"}
path = TBUtility.get_value(information["path"], get_tag=True)
full_key = key if key else information["key"]
full_value = information["path"].replace("${"+path+"}", str(val))
if information_type == 'timeseries' and data is not None and not self.__config.get(
'subOverrideServerTime', False):
# Note: SourceTimestamp and ServerTimestamp may be naive datetime objects, hence for the timestamp() the tz must first be overwritten to UTC (which it is according to the spec)
if data.monitored_item.Value.SourceTimestamp is not None:
timestamp = int(data.monitored_item.Value.SourceTimestamp.replace(tzinfo=timezone.utc).timestamp()*1000)
elif data.monitored_item.Value.ServerTimestamp is not None:
timestamp = int(data.monitored_item.Value.ServerTimestamp.replace(tzinfo=timezone.utc).timestamp()*1000)
def convert(self, config, val):
if not val:
return

data = val.Value.Value

if data is not None:
if isinstance(data, LocalizedText):
data = data.Text
elif val.Value.VariantType == VariantType.ExtensionObject:
data = str(data)
elif val.Value.VariantType == VariantType.DateTime:
if data.tzinfo is None:
data = data.replace(tzinfo=timezone.utc)
data = data.isoformat()

if config['section'] == 'timeseries':
if val.SourceTimestamp and int(val.SourceTimestamp.replace(
tzinfo=timezone.utc).timestamp() * 1000) != self._last_node_timestamp:
timestamp = int(val.SourceTimestamp.replace(tzinfo=timezone.utc).timestamp() * 1000)
self._last_node_timestamp = timestamp
elif val.ServerTimestamp and int(val.ServerTimestamp.replace(
tzinfo=timezone.utc).timestamp() * 1000) != self._last_node_timestamp:
timestamp = int(val.ServerTimestamp.replace(tzinfo=timezone.utc).timestamp() * 1000)
self._last_node_timestamp = timestamp
else:
timestamp = int(time()*1000)
result[information_types[information_type]].append({"ts": timestamp, 'values': {full_key: full_value}})
timestamp = int(time() * 1000)

self.data[DATA_TYPES[config['section']]].append({'ts': timestamp, 'values': {config['key']: data}})
else:
result[information_types[information_type]].append({full_key: full_value})
return result
except Exception as e:
self._log.exception(e)
self.data[DATA_TYPES[config['section']]].append({config['key']: data})

self._log.debug('Converted data: %s', self.data)
Empty file.
Loading

0 comments on commit 48fa3af

Please sign in to comment.