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))
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)
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)
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)