def __load_converters(self):
     try:
         for device in self.__config["devices"]:
             if self.__config.get("converter") is not None:
                 converter = TBUtility.check_and_import(self._connector_type, self.__config["converter"])(device)
             else:
                 converter = BytesModbusUplinkConverter(device)
             if self.__config.get("downlink_converter") is not None:
                 downlink_converter = TBUtility.check_and_import(self._connector_type, self.__config["downlink_converter"])(device)
             else:
                 downlink_converter = BytesModbusDownlinkConverter(device)
             if device.get('deviceName') not in self.__gateway.get_devices():
                 self.__gateway.add_device(device.get('deviceName'), {"connector": self}, device_type=device.get("deviceType"))
             self.__devices[device["deviceName"]] = {"config": device,
                                                     "converter": converter,
                                                     "downlink_converter": downlink_converter,
                                                     "next_attributes_check": 0,
                                                     "next_timeseries_check": 0,
                                                     "telemetry": {},
                                                     "attributes": {},
                                                     "last_telemetry": {},
                                                     "last_attributes": {}
                                                     }
     except Exception as e:
         log.exception(e)
Exemple #2
0
    def addDevices(self, config, connector):
        token = config['accessToken']
        self._tokens.add(token)
        if token is not None:
            for device in config['devices']:
                if config.get("converter") is not None:
                    converter = TBUtility.check_and_import(
                        'tcp', self._config["converter"])(device)
                else:
                    converter = BytesModbusUplinkConverter(device)
                if config.get("downlink_converter") is not None:
                    downlink_converter = TBUtility.check_and_import(
                        'tcp', self._config["downlink_converter"])(device)
                else:
                    downlink_converter = BytesModbusDownlinkConverter(device)
                if device.get('deviceName') not in self._gateway.get_devices():
                    self._gateway.add_device(
                        device.get('deviceName'), {"connector": connector},
                        device_type=device.get("deviceType"))
                    self._devices[device["deviceName"]] = {
                        "config": device,
                        "token": token,
                        "converter": converter,
                        "downlink_converter": downlink_converter,
                        "next_attributes_check": 0,
                        "next_timeseries_check": 0,
                        "telemetry": {},
                        "attributes": {},
                        "last_telemetry": {},
                        "last_attributes": {}
                    }

                break
Exemple #3
0
    def _load_connectors(self, config, from_file=True):
        self._connectors_configs = {}
        if not config.get("connectors"):
            raise Exception(
                "Configuration for connectors not found, check your config file."
            )
        for connector in config['connectors']:
            try:
                if connector.get('class') is not None:
                    try:
                        connector_class = TBUtility.check_and_import(
                            connector['type'], connector['class'])
                        self._implemented_connectors[
                            connector['type']] = connector_class
                    except Exception as e:
                        log.error(
                            "Exception when loading the custom connector:")
                        log.exception(e)
                elif connector.get("type") is not None and connector[
                        "type"] in self._default_connectors:
                    try:
                        connector_class = TBUtility.check_and_import(
                            connector["type"],
                            self._default_connectors[connector["type"]],
                            default=True)
                        self._implemented_connectors[
                            connector["type"]] = connector_class
                    except Exception as e:
                        log.error("Error on loading default connector:")
                        log.exception(e)
                else:
                    log.error("Connector with config %s - not found",
                              safe_dump(connector))
                if from_file:
                    with open(self._config_dir + connector['configuration'],
                              'r') as conf_file:
                        try:
                            connector_conf = load(conf_file)
                            if not self._connectors_configs.get(
                                    connector['type']):
                                self._connectors_configs[
                                    connector['type']] = []
                            self._connectors_configs[connector['type']].append(
                                {
                                    "name": connector["name"],
                                    "config": {
                                        connector['configuration']:
                                        connector_conf
                                    }
                                })
                        except Exception as e:
                            log.exception(e)

            except Exception as e:
                log.exception(e)
 def __get_converter(self, config, need_uplink):
     if config is None:
         return BytesNmeaUplinkConverter() if need_uplink else BytesNmeaDownlinkConverter()
     else:
         if need_uplink:
             uplink = config.get("uplink")
             return BytesNmeaUplinkConverter() if uplink is None \
                 else TBUtility.check_and_import(self.__connector_type, uplink)
         else:
             downlink = config.get("downlink")
             return BytesNmeaDownlinkConverter() if downlink is None \
                 else TBUtility.check_and_import(self.__connector_type, downlink)
Exemple #5
0
 def __fill_converters(self):
     try:
         for device in self.__devices:
             device["uplink_converter"] = TBUtility.check_and_import(
                 "snmp",
                 device.get('converter',
                            self._default_converters["uplink"]))(device)
             device["downlink_converter"] = TBUtility.check_and_import(
                 "snmp",
                 device.get('converter',
                            self._default_converters["downlink"]))(device)
     except Exception as e:
         log.exception(e)
Exemple #6
0
    def updateDevices(self, config, connector):
        token = config['accessToken']
        self._tokens.add(token)
        if token is not None:
            # 1. 先删除之前添加的设备,避免存在脏设备。
            pre_gateway_devices = filter(
                lambda x: self._gateway[x]["connector"].get_name() == connector
                .get_name(), self._gateway.get_devices())
            if pre_gateway_devices is not None:
                for pre_device in pre_gateway_devices:
                    self._gateway.del_device(pre_device.get('deviceName'))

            devices = {
                k: v
                for k, v in self._devices.items() if v['token'] == token
            }
            for device in list(devices.keys()):
                del self._devices[device]

            # 2. 新增设备,重置所有的信息
            for device in config['devices']:
                if config.get("converter") is not None:
                    converter = TBUtility.check_and_import(
                        'tcp', self._config["converter"])(device)
                else:
                    converter = BytesModbusUplinkConverter(device)
                if config.get("downlink_converter") is not None:
                    downlink_converter = TBUtility.check_and_import(
                        'tcp', self._config["downlink_converter"])(device)
                else:
                    downlink_converter = BytesModbusDownlinkConverter(device)

                if device.get('deviceName') not in self._gateway.get_devices():
                    self._gateway.add_device(
                        device.get('deviceName'), {"connector": connector},
                        device_type=device.get("deviceType"))
                if device.get('deviceName') not in self._devices:
                    self._devices[device["deviceName"]] = {
                        "config": device,
                        "token": token,
                        "converter": converter,
                        "downlink_converter": downlink_converter,
                        "next_attributes_check": 0,
                        "next_timeseries_check": 0,
                        "telemetry": {},
                        "attributes": {},
                        "last_telemetry": {},
                        "last_attributes": {}
                    }

                break
Exemple #7
0
 def __prepare_connectors_configuration(self, input_connector_config):
     try:
         self.__gateway.connectors_configs = {}
         for connector in input_connector_config['thingsboard'][
                 'connectors']:
             for input_connector in input_connector_config[
                     connector['type']]:
                 if input_connector['name'] == connector['name']:
                     if not self.__gateway.connectors_configs.get(
                             connector['type']):
                         self.__gateway.connectors_configs[
                             connector['type']] = []
                     self.__gateway.connectors_configs[
                         connector['type']].append({
                             "name": connector["name"],
                             "config": {
                                 connector['configuration']:
                                 input_connector["config"]
                             }
                         })
                     connector_class = TBUtility.check_and_import(
                         connector["type"],
                         self.__gateway._default_connectors.get(
                             connector["type"], connector.get("class")))
                     self.__gateway._implemented_connectors[
                         connector["type"]] = connector_class
     except Exception as e:
         log.exception(e)
    def __init__(self, gateway, config, connector_type):
        super().__init__()
        self.daemon = True
        self.setName(config.get("name", 'ODBC Connector ' + ''.join(choice(ascii_lowercase) for _ in range(5))))

        self.statistics = {'MessagesReceived': 0,
                           'MessagesSent': 0}
        self.__gateway = gateway
        self.__connector_type = connector_type
        self.__config = config
        self.__stopped = False

        self.__config_dir = "thingsboard_gateway/config/odbc/"

        self.__connection = None
        self.__cursor = None
        self.__rpc_cursor = None
        self.__iterator = None
        self.__iterator_file_name = ""

        self.__devices = {}

        self.__column_names = []
        self.__attribute_columns = []
        self.__timeseries_columns = []

        self.__converter = OdbcUplinkConverter() if not self.__config.get("converter", "") else \
            TBUtility.check_and_import(self.__connector_type, self.__config["converter"])

        self.__configure_pyodbc()
        self.__parse_rpc_config()
 def __fill_requests(self):
     log.debug(self.__config["mapping"])
     for endpoint in self.__config["mapping"]:
         try:
             log.debug(endpoint)
             converter = None
             if endpoint["converter"]["type"] == "custom":
                 module = TBUtility.check_and_import(
                     self.__connector_type,
                     endpoint["converter"]["extension"])
                 if module is not None:
                     log.debug('Custom converter for url %s - found!',
                               endpoint["url"])
                     converter = module(endpoint)
                 else:
                     log.error(
                         "\n\nCannot find extension module for %s url.\nPlease check your configuration.\n",
                         endpoint["url"])
             else:
                 converter = JsonRequestUplinkConverter(endpoint)
             self.__requests_in_progress.append({
                 "config": endpoint,
                 "converter": converter,
                 "next_time": time(),
                 "request": request
             })
         except Exception as e:
             log.exception(e)
Exemple #10
0
 def _load_connectors(self, main_config):
     self.connectors_configs = {}
     if main_config.get("connectors"):
         for connector in main_config['connectors']:
             try:
                 connector_class = TBUtility.check_and_import(
                     connector["type"],
                     self._default_connectors.get(connector["type"],
                                                  connector.get("class")))
                 self._implemented_connectors[
                     connector["type"]] = connector_class
                 with open(self._config_dir + connector['configuration'],
                           'r') as conf_file:
                     connector_conf = load(conf_file)
                     if not self.connectors_configs.get(connector['type']):
                         self.connectors_configs[connector['type']] = []
                     connector_conf["name"] = connector["name"]
                     self.connectors_configs[connector['type']].append({
                         "name":
                         connector["name"],
                         "config": {
                             connector['configuration']: connector_conf
                         }
                     })
             except Exception as e:
                 log.error("Error on loading connector:")
                 log.exception(e)
     else:
         log.error("Connectors - not found! Check your configuration!")
         main_config["remoteConfiguration"] = True
         log.info("Remote configuration is enabled forcibly!")
Exemple #11
0
 def load_converters(self):  # Function for search a converter and save it.
     devices_config = self.__config.get('devices')
     try:
         if devices_config:
             for device_config in devices_config:
                 if device_config.get('converter') is not None:
                     converter = TBUtility.check_and_import(
                         self.__connector_type, device_config['converter'])
                     self.devices[device_config['name']] = {
                         'converter': converter(device_config),
                         'device_config': device_config
                     }
                 else:
                     converter = CustomOpcdaUplinkConverter(device_config)
                     self.devices[device_config['name']] = {
                         'converter': converter,
                         'device_config': device_config
                     }
         else:
             log.error(
                 'Section "devices" in the configuration not found. A custom connector %s has being stopped.',
                 self.get_name())
             self.close()
     except Exception as e:
         log.exception(e)
Exemple #12
0
 def _load_connectors(self, main_config):
     self.connectors_configs = {}
     if not main_config.get("connectors"):
         raise Exception(
             "Configuration for connectors not found, check your config file."
         )
     for connector in main_config['connectors']:
         try:
             connector_class = TBUtility.check_and_import(
                 connector["type"],
                 self._default_connectors.get(connector["type"],
                                              connector.get("class")))
             self._implemented_connectors[
                 connector["type"]] = connector_class
             with open(self._config_dir + connector['configuration'],
                       'r') as conf_file:
                 connector_conf = load(conf_file)
                 if not self.connectors_configs.get(connector['type']):
                     self.connectors_configs[connector['type']] = []
                 self.connectors_configs[connector['type']].append({
                     "name":
                     connector["name"],
                     "config": {
                         connector['configuration']: connector_conf
                     }
                 })
         except Exception as e:
             log.error("Error on loading connector:")
             log.exception(e)
 def __fill_attribute_updates(self):
     for attribute_request in self.__config.get("attributeUpdates", []):
         if attribute_request.get("converter") is not None:
             converter = TBUtility.check_and_import("request", attribute_request["converter"])(attribute_request)
         else:
             converter = JsonRequestDownlinkConverter(attribute_request)
         attribute_request_dict = {**attribute_request, "converter": converter}
         self.__attribute_updates.append(attribute_request_dict)
 def __fill_rpc_requests(self):
     for rpc_request in self.__config.get("serverSideRpc", []):
         if rpc_request.get("converter") is not None:
             converter = TBUtility.check_and_import("request", rpc_request["converter"])(rpc_request)
         else:
             converter = JsonRequestDownlinkConverter(rpc_request)
         rpc_request_dict = {**rpc_request, "converter": converter}
         self.__rpc_requests.append(rpc_request_dict)
    def _on_connect(self, client, userdata, flags, rc, *extra_params):
        result_codes = {
            1: "incorrect protocol version",
            2: "invalid client identifier",
            3: "server unavailable",
            4: "bad username or password",
            5: "not authorised",
        }
        if rc == 0:
            self._connected = True
            self.__log.info('%s connected to %s:%s - successfully.',
                     self.get_name(),
                     self.__broker["host"],
                     self.__broker.get("port", "1883"))
            for mapping in self.__mapping:
                try:
                    converter = None
                    if mapping["converter"]["type"] == "custom":
                        try:
                            module = TBUtility.check_and_import(self.__connector_type, mapping["converter"]["extension"])
                            if module is not None:
                                self.__log.debug('Custom converter for topic %s - found!', mapping["topicFilter"])
                                converter = module(mapping)
                            else:
                                self.__log.error("\n\nCannot find extension module for %s topic.\n\Please check your configuration.\n", mapping["topicFilter"])
                        except Exception as e:
                            self.__log.exception(e)
                    else:
                        converter = JsonMqttUplinkConverter(mapping)
                    if converter is not None:
                        regex_topic = TBUtility.topic_to_regex(mapping.get("topicFilter"))
                        if not self.__sub_topics.get(regex_topic):
                            self.__sub_topics[regex_topic] = []

                        self.__sub_topics[regex_topic].append({converter: None})
                        # self._client.subscribe(TBUtility.regex_to_topic(regex_topic))
                        self.__subscribe(mapping["topicFilter"])
                        self.__log.info('Connector "%s" subscribe to %s',
                                 self.get_name(),
                                 TBUtility.regex_to_topic(regex_topic))
                    else:
                        self.__log.error("Cannot find converter for %s topic", mapping["topicFilter"])
                except Exception as e:
                    self.__log.exception(e)
            try:
                for request in self.__service_config:
                    if self.__service_config.get(request) is not None:
                        for request_config in self.__service_config.get(request):
                            self.__subscribe(request_config["topicFilter"])
            except Exception as e:
                self.__log.error(e)

        else:
            if rc in result_codes:
                self.__log.error("%s connection FAIL with error %s %s!", self.get_name(), rc, result_codes[rc])
            else:
                self.__log.error("%s connection FAIL with unknown error!", self.get_name())
 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 _create_connector(self, config_filename, connector_type=None):
     if connector_type is None:
         class_name = self.__class__.__name__.lower()
         connector_type = class_name[0:class_name.find("connector")]
     self._connector_type = connector_type
     self.config = self._load_data_file(config_filename, connector_type)
     self.assertTrue(self.config is not None)
     connector = TBUtility.check_and_import(
         connector_type, DEFAULT_CONNECTORS[connector_type])
     self.assertTrue(connector is not None)
     self.connector = connector(self.gateway, self.config, connector_type)
     sleep(1)
Exemple #18
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 load_endpoints(self):
     endpoints = {}
     for mapping in self.__config.get("mapping"):
         converter = TBUtility.check_and_import(
             self._connector_type,
             mapping.get("extension", self._default_converters["uplink"]))
         endpoints.update({
             mapping['endpoint']: {
                 "config": mapping,
                 "converter": converter
             }
         })
     return endpoints
 def __fill_interest_devices(self):
     if self.__config.get('devices') is None:
         log.error('Devices not found in configuration file. BLE Connector stopped.')
         self._connected = False
         return None
     for interest_device in self.__config.get('devices'):
         keys_in_config = ['attributes', 'telemetry']
         if interest_device.get('MACAddress') is not None:
             default_converter = BytesBLEUplinkConverter(interest_device)
             interest_uuid = {}
             for key_type in keys_in_config:
                 for type_section in interest_device.get(key_type):
                     if type_section.get("characteristicUUID") is not None:
                         converter = None
                         if type_section.get('converter') is not None:
                             try:
                                 module = TBUtility.check_and_import(self.__connector_type,
                                                                     type_section['converter'])
                                 if module is not None:
                                     log.debug('Custom converter for device %s - found!',
                                               interest_device['MACAddress'])
                                     converter = module(interest_device)
                                 else:
                                     log.error(
                                         "\n\nCannot find extension module for device %s .\nPlease check your configuration.\n",
                                         interest_device['MACAddress'])
                             except Exception as e:
                                 log.exception(e)
                         else:
                             converter = default_converter
                         if converter is not None:
                             if interest_uuid.get(type_section["characteristicUUID"].upper()) is None:
                                 interest_uuid[type_section["characteristicUUID"].upper()] = [
                                     {'section_config': type_section,
                                      'type': key_type,
                                      'converter': converter}]
                             else:
                                 interest_uuid[type_section["characteristicUUID"].upper()].append(
                                     {'section_config': type_section,
                                      'type': key_type,
                                      'converter': converter})
                     else:
                         log.error("No characteristicUUID found in configuration section for %s:\n%s\n", key_type,
                                   pformat(type_section))
             if self.__devices_around.get(interest_device['MACAddress'].upper()) is None:
                 self.__devices_around[interest_device['MACAddress'].upper()] = {}
             self.__devices_around[interest_device['MACAddress'].upper()]['device_config'] = interest_device
             self.__devices_around[interest_device['MACAddress'].upper()]['interest_uuid'] = interest_uuid
         else:
             log.error("Device address not found, please check your settings.")
 def __init__(self, gateway, config, connector_type):
     self.__connector_type = connector_type
     self.statistics = {'MessagesReceived': 0, 'MessagesSent': 0}
     super().__init__()
     self.__config = config
     self.setName(
         config.get(
             'name',
             'BACnet ' + ''.join(choice(ascii_lowercase)
                                 for _ in range(5))))
     self.__devices = []
     self.__device_indexes = {}
     self.__devices_address_name = {}
     self.__gateway = gateway
     self._application = TBBACnetApplication(self, self.__config)
     self.__bacnet_core_thread = Thread(target=run,
                                        name="BACnet core thread")
     self.__bacnet_core_thread.start()
     self.__stopped = False
     self.__config_devices = self.__config["devices"]
     self.default_converters = {
         "uplink_converter":
         TBUtility.check_and_import(self.__connector_type,
                                    "BACnetUplinkConverter"),
         "downlink_converter":
         TBUtility.check_and_import(self.__connector_type,
                                    "BACnetDownlinkConverter")
     }
     self.__request_functions = {
         "writeProperty": self._application.do_write_property,
         "readProperty": self._application.do_read_property
     }
     self.__available_object_resources = {}
     self.rpc_requests_in_progress = {}
     self.__connected = False
     self.daemon = True
 def __fill_requests_from_TB(self):
     requests_from_tb = {
         "attributeUpdates": self.__attribute_updates,
         "serverSideRpc": self.__rpc_requests,
     }
     for request_section in requests_from_tb:
         for request_config_object in self.__config.get(
                 request_section, []):
             uplink_converter = TBUtility.check_and_import(
                 self._connector_type,
                 request_config_object.get(
                     "extension", self._default_converters["uplink"]))(
                         request_config_object)
             downlink_converter = TBUtility.check_and_import(
                 self._connector_type,
                 request_config_object.get(
                     "extension", self._default_converters["downlink"]))(
                         request_config_object)
             request_dict = {
                 **request_config_object,
                 "uplink_converter": uplink_converter,
                 "downlink_converter": downlink_converter,
             }
             requests_from_tb[request_section].append(request_dict)
Exemple #23
0
 def __search_nodes_and_subscribe(self, device_info):
     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:
                     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_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 = TBUtility.check_and_import(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
                     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)
                         self.__sub.subscribe_data_change(information_node)
                     log.debug("Added subscription to node: %s", str(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 __load_converters(self, device):
     datatypes = [
         "attributes", "telemetry", "attribute_updates", "server_side_rpc"
     ]
     for datatype in datatypes:
         for datatype_config in device.get(datatype, []):
             try:
                 for converter_type in self.default_converters:
                     converter_object = self.default_converters[
                         converter_type] if datatype_config.get(
                             "class"
                         ) is None else TBUtility.check_and_import(
                             self.__connector_type, device.get("class"))
                     datatype_config[converter_type] = converter_object(
                         device)
             except Exception as e:
                 log.exception(e)
Exemple #25
0
 def _load_connectors(self):
     self.connectors_configs = {}
     if self.__config.get("connectors"):
         for connector in self.__config['connectors']:
             try:
                 type = connector["type"]
                 type1 = self._default_connectors.get(connector["type"])
                 classt = connector.get("class")
                 classtype = self._default_connectors.get(
                     connector["type"], connector.get("class"))
                 connector_class = TBUtility.check_and_import(
                     connector["type"],
                     self._default_connectors.get(connector["type"],
                                                  connector.get("class")))
                 self._implemented_connectors[
                     connector["type"]] = connector_class
                 log.info(connector_class)
                 #加载connector配置文件
                 with open(self._config_dir + connector['configuration'],
                           'r',
                           encoding="UTF-8") as conf_file:
                     connector_conf = load(conf_file)
                     if not self.connectors_configs.get(connector['type']):
                         self.connectors_configs[connector['type']] = []
                     connector_conf["name"] = connector["name"]
                     self.connectors_configs[connector['type']].append({
                         "name":
                         connector["name"],
                         "config": {
                             connector['configuration']: connector_conf
                         }
                     })
             except Exception as e:
                 log.error("Error on loading connector:")
                 log.exception(e)
     else:
         log.error("Connectors - not found! Check your configuration!")
         self.__init_remote_configuration(force=True)
         log.info("Remote configuration is enabled forcibly!")
Exemple #26
0
 def load_converters(self):
     devices_config = self.__config.get('devices')
     try:
         if devices_config is not None:
             print("Devices config part loaded ... ")
             for device_config in devices_config:
                 if device_config.get('converter') is not None:
                     converter = TBUtility.check_and_import(
                         self.__connector_type, device_config['converter'])
                     self.devices[device_config['name']] = {
                         'converter': converter(device_config),
                         'device_config': device_config
                     }
                 else:
                     log.error(
                         'Converter configuration for the custom connector %s -- not found, please check your configuration file.',
                         self.get_name())
         else:
             log.error(
                 'Section "devices" in the configuration not found. A custom connector %s has being stopped.',
                 self.get_name())
             self.close()
     except Exception as e:
         log.exception(e)
    def _on_connect(self, client, userdata, flags, result_code, *extra_params):

        result_codes = {
            1: "incorrect protocol version",
            2: "invalid client identifier",
            3: "server unavailable",
            4: "bad username or password",
            5: "not authorised",
        }

        if result_code == 0:
            self._connected = True
            self.__log.info('%s connected to %s:%s - successfully.',
                            self.get_name(), self.__broker["host"],
                            self.__broker.get("port", "1883"))

            self.__log.debug(
                "Client %s, userdata %s, flags %s, extra_params %s",
                str(client), str(userdata), str(flags), extra_params)

            # Setup data upload requests handling ----------------------------------------------------------------------
            for mapping in self.__mapping:
                try:
                    # Load converter for this mapping entry ------------------------------------------------------------
                    # mappings are guaranteed to have topicFilter and converter fields. See __init__
                    default_converter_class_name = "JsonMqttUplinkConverter"
                    # Get converter class from "extension" parameter or default converter
                    converter_class_name = mapping["converter"].get(
                        "extension", default_converter_class_name)
                    # Find and load required class
                    module = TBUtility.check_and_import(
                        self._connector_type, converter_class_name)
                    if module:
                        self.__log.debug('Converter %s for topic %s - found!',
                                         converter_class_name,
                                         mapping["topicFilter"])
                        converter = module(mapping)
                    else:
                        self.__log.error("Cannot find converter for %s topic",
                                         mapping["topicFilter"])
                        continue

                    # Setup regexp topic acceptance list ---------------------------------------------------------------
                    regex_topic = TBUtility.topic_to_regex(
                        mapping["topicFilter"])

                    # There may be more than one converter per topic, so I'm using vectors
                    if not self.__mapping_sub_topics.get(regex_topic):
                        self.__mapping_sub_topics[regex_topic] = []

                    self.__mapping_sub_topics[regex_topic].append(converter)

                    # Subscribe to appropriate topic -------------------------------------------------------------------
                    self.__subscribe(mapping["topicFilter"],
                                     mapping.get("subscriptionQos", 0))

                    self.__log.info('Connector "%s" subscribe to %s',
                                    self.get_name(),
                                    TBUtility.regex_to_topic(regex_topic))

                except Exception as e:
                    self.__log.exception(e)

            # Setup connection requests handling -----------------------------------------------------------------------
            for request in [
                    entry for entry in self.__connect_requests
                    if entry is not None
            ]:
                # requests are guaranteed to have topicFilter field. See __init__
                self.__subscribe(request["topicFilter"],
                                 request.get("subscriptionQos", 0))
                topic_filter = TBUtility.topic_to_regex(
                    request.get("topicFilter"))
                self.__connect_requests_sub_topics[topic_filter] = request

            # Setup disconnection requests handling --------------------------------------------------------------------
            for request in [
                    entry for entry in self.__disconnect_requests
                    if entry is not None
            ]:
                # requests are guaranteed to have topicFilter field. See __init__
                self.__subscribe(request["topicFilter"],
                                 request.get("subscriptionQos", 0))
                topic_filter = TBUtility.topic_to_regex(
                    request.get("topicFilter"))
                self.__disconnect_requests_sub_topics[topic_filter] = request

            # Setup attributes requests handling -----------------------------------------------------------------------
            for request in [
                    entry for entry in self.__attribute_requests
                    if entry is not None
            ]:
                # requests are guaranteed to have topicFilter field. See __init__
                self.__subscribe(request["topicFilter"],
                                 request.get("subscriptionQos", 0))
                topic_filter = TBUtility.topic_to_regex(
                    request.get("topicFilter"))
                self.__attribute_requests_sub_topics[topic_filter] = request

        else:
            if result_code in result_codes:
                self.__log.error("%s connection FAIL with error %s %s!",
                                 self.get_name(), result_code,
                                 result_codes[result_code])
            else:
                self.__log.error("%s connection FAIL with unknown error!",
                                 self.get_name())
Exemple #28
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)