def __search_nodes_and_subscribe(self, device_info):
     sub_nodes = []
     information_types = {"attributes": "attributes", "timeseries": "telemetry"}
     for information_type in information_types:
         for information in device_info["configuration"][information_type]:
             information_key = information["key"]
             config_path = TBUtility.get_value(information["path"], get_tag=True)
             information_path = self._check_path(config_path, device_info["deviceNode"])
             information["path"] = '${%s}' % information_path
             information_nodes = []
             self.__search_node(device_info["deviceNode"], information_path, result=information_nodes)
             for information_node in information_nodes:
                 if information_node is not None:
                     try:
                         information_value = information_node.get_value()
                     except:
                         log.error("Err get_value: %s", str(information_node))
                         continue
                     log.debug("Node for %s \"%s\" with path: %s - FOUND! Current values is: %s",
                               information_type,
                               information_key,
                               information_path,
                               str(information_value))
                     if device_info.get("uplink_converter") is None:
                         configuration = {**device_info["configuration"],
                                          "deviceName": device_info["deviceName"],
                                          "deviceType": device_info["deviceType"]}
                         if device_info["configuration"].get('converter') is None:
                             converter = OpcUaUplinkConverter(configuration)
                         else:
                             converter = TBModuleLoader.import_module(self._connector_type, configuration)
                         device_info["uplink_converter"] = converter
                     else:
                         converter = device_info["uplink_converter"]
                     self.subscribed[information_node] = {"converter": converter,
                                                          "path": information_path,
                                                          "config_path": config_path}
                     if not device_info.get(information_types[information_type]):
                         device_info[information_types[information_type]] = []
                     converted_data = converter.convert((config_path, information_path), information_value)
                     self.statistics['MessagesReceived'] = self.statistics['MessagesReceived'] + 1
                     self.data_to_send.append(converted_data)
                     self.statistics['MessagesSent'] = self.statistics['MessagesSent'] + 1
                     log.debug("Data to ThingsBoard: %s", converted_data)
                     if not self.__server_conf.get("disableSubscriptions", False):
                         sub_nodes.append(information_node)
                 else:
                     log.error("Node for %s \"%s\" with path %s - NOT FOUND!", information_type, information_key, information_path)
     if not self.__server_conf.get("disableSubscriptions", False):
         if self.__sub is None:
             self.__sub = self.client.create_subscription(self.__server_conf.get("subCheckPeriodInMillis", 500),
                                                          self.__sub_handler)
         if sub_nodes:
             self.__sub.subscribe_data_change(sub_nodes)
             log.debug("Added subscription to nodes: %s", str(sub_nodes))
Exemplo n.º 2
0
 def __search_nodes_and_subscribe(self, device_configuration, device_info):
     device_configuration.update(**device_info)
     information_types = {
         "attributes": "attributes",
         "timeseries": "telemetry"
     }
     for information_type in information_types:
         for information in device_configuration[information_type]:
             information_key = information["key"]
             config_path = TBUtility.get_value(information["path"],
                                               get_tag=True)
             information_path = self._check_path(config_path,
                                                 device_info["deviceNode"])
             information["path"] = '${%s}' % information_path
             information_node = self.__search_node(
                 device_info["deviceNode"], information_path)
             if information_node is not None:
                 information_value = information_node.get_value()
                 log.debug(
                     "Node for %s \"%s\" with path: %s - FOUND! Current values is: %s",
                     information_type, information_key, information_path,
                     str(information_value))
                 if device_configuration.get("uplink_converter") is None:
                     if device_configuration.get('converter') is None:
                         converter = OpcUaUplinkConverter(
                             device_configuration)
                     else:
                         converter = TBUtility.check_and_import(
                             self.__connector_type,
                             device_configuration['converter'])
                     device_configuration["uplink_converter"] = converter
                 else:
                     converter = device_configuration["uplink_converter"]
                 self.subscribed[information_node] = {
                     "converter": converter,
                     "path": information_path,
                     "config_path": config_path
                 }
                 if not device_info.get(
                         information_types[information_type]):
                     device_info[information_types[information_type]] = []
                 converted_data = converter.convert(
                     (config_path, information_path), information_value)
                 self.statistics['MessagesReceived'] += 1
                 self.data_to_send.append(converted_data)
                 self.statistics['MessagesSent'] += 1
                 self.__sub.subscribe_data_change(information_node)
                 log.debug("Data to ThingsBoard: %s", converted_data)
             else:
                 log.error("Node for %s \"%s\" with path %s - NOT FOUND!",
                           information_type, information_key,
                           information_path)
 def __search_tags(self, node, recursion_level, sub=None):
     try:
         for childId in node.get_children():
             ch = self.client.get_node(childId)
             current_var_path = '.'.join(x.split(":")[1] for x in ch.get_path(20000, True))
             if self.__interest_nodes:
                 if ch.get_node_class() == ua.NodeClass.Object:
                     for interest_node in self.__interest_nodes:
                         for int_node in interest_node:
                             if re.search(int_node.split('\\.')[recursion_level-2], ch.get_display_name().Text):
                                 try:
                                     methods = ch.get_methods()
                                     for method in methods:
                                         self.__available_object_resources[interest_node[int_node]["deviceName"]]["methods"].append({method.get_display_name().Text: method,
                                                                                                                                    "node": ch})
                                 except Exception as e:
                                     log.exception(e)
                                 self.__search_tags(ch, recursion_level+1, sub)
                 elif ch.get_node_class() == ua.NodeClass.Variable:
                     try:
                         for interest_node in self.__interest_nodes:
                             for int_node in interest_node:
                                 if interest_node[int_node].get("attributes_updates"):
                                     try:
                                         for attribute_update in interest_node[int_node]["attributes_updates"]:
                                             if attribute_update["attributeOnDevice"] == ch.get_display_name().Text:
                                                 self.__available_object_resources[interest_node[int_node]["deviceName"]]['variables'].append({attribute_update["attributeOnThingsBoard"]: ch, })
                                     except Exception as e:
                                         log.exception(e)
                                 if re.search(int_node.replace('$', ''), current_var_path):
                                     tags = []
                                     if interest_node[int_node].get("attributes"):
                                         tags.extend(interest_node[int_node]["attributes"])
                                     if interest_node[int_node].get("timeseries"):
                                         tags.extend(interest_node[int_node]["timeseries"])
                                     for tag in tags:
                                         target = TBUtility.get_value(tag["path"], get_tag=True)
                                         if ch.get_display_name().Text == target:
                                             sub.subscribe_data_change(ch)
                                             if interest_node[int_node].get("uplink_converter") is None:
                                                 if interest_node[int_node].get('converter') is None:
                                                     converter = OpcUaUplinkConverter(interest_node[int_node])
                                                 else:
                                                     converter = TBUtility.check_and_import(self.__connector_type, interest_node[int_node]['converter'])
                                                 interest_node[int_node]["uplink_converter"] = converter
                                             else:
                                                 converter = interest_node[int_node]["uplink_converter"]
                                             self.subscribed[ch] = {"converter": converter,
                                                                    "path": current_var_path}
                     except BadWaitingForInitialData:
                         pass
                 elif not self.__interest_nodes:
                     log.error("Nodes in mapping not found, check your settings.")
     except Exception as e:
         log.exception(e)
Exemplo n.º 4
0
    def test_opcua_getting_values(self):
        test_opcua_config = {
            'deviceNodePattern':
            'Root\\.Objects\\.Device1',
            'deviceNamePattern':
            'Device ${Root\\.Objects\\.Device1\\.serialNumber}',
            'attributes': [{
                'key': 'temperature °C',
                'path': '${ns=2;i=5}'
            }],
            'timeseries': [{
                'key':
                'humidity',
                'path':
                '${Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity}'
            }, {
                'key': 'batteryLevel',
                'path': '${Battery\\.batteryLevel}'
            }],
            'deviceName':
            'Device Number One',
            'deviceType':
            'default'
        }
        test_data_list = [24.1, 25.8, 59.8]
        test_configs = [
            ('ns=2;i=5', 'ns=2;i=5'),
            ('Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity',
             'Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity'
             ),
            ('Battery\\.batteryLevel',
             'Root\\\\.Objects\\\\.Device1\\\\.Battery\\\\.batteryLevel')
        ]
        test_opcua_result = [{
            'deviceName': 'Device Number One',
            'deviceType': 'default',
            'attributes': [{
                'temperature °C': '24.1'
            }],
            'telemetry': []
        }, {
            'deviceName': 'Device Number One',
            'deviceType': 'default',
            'attributes': [],
            'telemetry': [{
                'humidity': '25.8'
            }]
        }, {
            'deviceName': 'Device Number One',
            'deviceType': 'default',
            'attributes': [],
            'telemetry': [{
                'batteryLevel': '59.8'
            }]
        }]

        converter = OpcUaUplinkConverter(test_opcua_config)
        result = []
        for index, config in enumerate(test_configs):
            result.append(converter.convert(config, test_data_list[index]))
        self.assertListEqual(result, test_opcua_result)
Exemplo n.º 5
0
 def __search_tags(self, node, recursion_level, sub=None):
     print(
         "__search_tags -----------------------------------------__search_tags node=",
         node, "recursion_level=", recursion_level, "node.get_children()=",
         node.get_children())
     try:
         for childId in node.get_children():
             ch = self.client.get_node(childId)
             current_var_path = '.'.join(
                 x.split(":")[1] for x in ch.get_path(20000, True))
             print("__search_tags current_var_path=", current_var_path,
                   "ch.get_node_class()=", ch.get_node_class())
             if self.__interest_nodes:
                 if ch.get_node_class() == ua.NodeClass.Object:
                     for interest_node in self.__interest_nodes:
                         for int_node in interest_node:
                             try:
                                 name_to_check = int_node.split('\\.')[
                                     recursion_level +
                                     1] if '\\.' in int_node else int_node
                                 # name_to_check = int_node.split('.')[recursion_level] if '.' in int_node else name_to_check
                             except IndexError:
                                 name_to_check = int_node.split(
                                     '\\.'
                                 )[-1] if '\\.' in int_node else int_node
                                 # name_to_check = int_node.split('.')[-1] if '.' in int_node else name_to_check
                             log.debug("%s\t%s", name_to_check,
                                       ch.get_display_name().Text)
                             print("__search_tags ch.get_methods()",
                                   ch.get_methods(), "int_node=", int_node)
                             if re.search(
                                     name_to_check.replace("\\", "\\\\"),
                                     ch.get_display_name().Text):
                                 try:
                                     methods = ch.get_methods()
                                     for method in methods:
                                         self.__available_object_resources[
                                             interest_node[int_node]
                                             ["deviceName"]][
                                                 "methods"].append({
                                                     method.get_display_name(
                                                     ).Text:
                                                     method,
                                                     "node":
                                                     ch
                                                 })
                                 except Exception as e:
                                     log.exception(e)
                             # for tag in interest_node[int_node]["timeseries"] + interest_node[int_node]["attributes"]:
                             #     subrecursion_level = recursion_level
                             #     if subrecursion_level != recursion_level + len(tag["path"].split("\\.")):
                             #         self.__search_tags(ch, subrecursion_level+1, sub)
                             #     else:
                             #         return
                             self.__search_tags(ch, recursion_level + 1,
                                                sub)
                 elif ch.get_node_class() == ua.NodeClass.Variable:
                     try:
                         for interest_node in self.__interest_nodes:
                             for int_node in interest_node:
                                 if interest_node[int_node].get(
                                         "attributes_updates"):
                                     try:
                                         for attribute_update in interest_node[
                                                 int_node][
                                                     "attributes_updates"]:
                                             if attribute_update[
                                                     "attributeOnDevice"] == ch.get_display_name(
                                                     ).Text:
                                                 self.__available_object_resources[
                                                     interest_node[int_node]
                                                     ["deviceName"]][
                                                         'variables'].append({
                                                             attribute_update["attributeOnThingsBoard"]:
                                                             ch,
                                                         })
                                     except Exception as e:
                                         log.exception(e)
                                 name_to_check = int_node.split(
                                     '\\.'
                                 )[-1] if '\\.' in int_node else int_node
                                 # name_to_check = int_node.split('.')[-1] if '.' in int_node else name_to_check
                                 print(
                                     "__search_tags name_to_check.replace('$', '')=",
                                     name_to_check.replace('$', ''),
                                     "current_var_path.split=",
                                     current_var_path.split(".")[-2])
                                 if re.search(
                                         name_to_check.replace('$', ''),
                                         current_var_path.split(".")[-2]):
                                     print("__search_tags search!!!")
                                     tags = []
                                     if interest_node[int_node].get(
                                             "attributes"):
                                         tags.extend(interest_node[int_node]
                                                     ["attributes"])
                                     if interest_node[int_node].get(
                                             "timeseries"):
                                         tags.extend(interest_node[int_node]
                                                     ["timeseries"])
                                     for tag in tags:
                                         target = TBUtility.get_value(
                                             tag["path"], get_tag=True)
                                         try:
                                             tag_name_for_check = target.split(
                                                 '\\.'
                                             )[recursion_level] if '\\.' in target else target
                                             # tag_name_for_check = target.split('.')[recursion_level] if '.' in target else tag_name_for_check
                                         except IndexError:
                                             tag_name_for_check = target.split(
                                                 '\\.'
                                             )[-1] if '\\.' in target else target
                                             # tag_name_for_check = target.split('.')[-1] if '.' in target else tag_name_for_check
                                         current_node_name = ch.get_display_name(
                                         ).Text
                                         print(
                                             "__search_tags current_node_name=",
                                             current_node_name,
                                             "tag_name_for_check=",
                                             tag_name_for_check)
                                         if current_node_name == tag_name_for_check:
                                             print(
                                                 "__search_tags subscribe_data_change"
                                             )
                                             sub.subscribe_data_change(ch)
                                             if interest_node[int_node].get(
                                                     "uplink_converter"
                                             ) is None:
                                                 if interest_node[
                                                         int_node].get(
                                                             'converter'
                                                         ) is None:
                                                     converter = OpcUaUplinkConverter(
                                                         interest_node[
                                                             int_node])
                                                 else:
                                                     converter = TBUtility.check_and_import(
                                                         self.
                                                         __connector_type,
                                                         interest_node[
                                                             int_node]
                                                         ['converter'])
                                                 interest_node[int_node][
                                                     "uplink_converter"] = converter
                                             else:
                                                 converter = interest_node[
                                                     int_node][
                                                         "uplink_converter"]
                                             self.subscribed[ch] = {
                                                 "converter": converter,
                                                 "path": current_var_path
                                             }
                                 else:
                                     return
                     except BadWaitingForInitialData:
                         pass
                 elif not self.__interest_nodes:
                     log.error(
                         "Nodes in mapping not found, check your settings.")
     except Exception as e:
         log.exception(e)