Esempio n. 1
0
 def __safe_apply_connection_configuration(self):
     apply_start = time() * 1000
     self.__old_tb_client = self.__gateway.tb_client
     try:
         self.__old_tb_client.unsubscribe('*')
         self.__old_tb_client.stop()
         self.__old_tb_client.disconnect()
         self.__gateway.tb_client = TBClient(
             self.__new_general_configuration_file["thingsboard"],
             self.__old_tb_client.get_config_folder_path())
         self.__gateway.tb_client.connect()
         connection_state = False
         while time(
         ) * 1000 - apply_start < self.__apply_timeout * 1000 and not connection_state:
             connection_state = self.__gateway.tb_client.is_connected()
             sleep(.1)
         if not connection_state:
             self.__revert_configuration()
             LOG.info(
                 "The gateway cannot connect to the ThingsBoard server with a new configuration."
             )
             return False
         else:
             self.__old_tb_client.stop()
             self.__gateway.subscribe_to_required_topics()
             return True
     except Exception as e:
         LOG.exception(e)
         self.__revert_configuration()
         return False
Esempio n. 2
0
 def __revert_configuration(self):
     try:
         LOG.info("Remote general configuration will be restored.")
         self.__new_general_configuration_file = self.__old_general_configuration_file
         self.__gateway.tb_client.disconnect()
         self.__gateway.tb_client.stop()
         self.__gateway.tb_client = TBClient(
             self.__old_general_configuration_file["thingsboard"])
         self.__gateway.tb_client.connect()
         self.__gateway.subscribe_to_required_topics()
         LOG.debug("%s connection has been restored",
                   str(self.__gateway.tb_client.client._client))
     except Exception as e:
         LOG.exception("Exception on reverting configuration occurred:")
         LOG.exception(e)
Esempio n. 3
0
 def __safe_apply_connection_configuration(self):
     apply_start = time() * 1000
     self.__old_tb_client = self.__gateway.tb_client
     try:
         self.__old_tb_client.pause()
     except Exception as e:
         log.exception(e)
         self.__revert_configuration()
         return False
     try:
         tb_client = TBClient(
             self.__new_general_configuration_file["thingsboard"])
         tb_client.connect()
     except Exception as e:
         log.exception(e)
         self.__revert_configuration()
         return False
     self.__gateway.tb_client = tb_client
     try:
         connection_state = False
         while time(
         ) * 1000 - apply_start < self.__apply_timeout * 1000 and not connection_state:
             connection_state = self.__gateway.tb_client.is_connected()
             sleep(.1)
         if not connection_state:
             self.__revert_configuration()
             log.info(
                 "The gateway cannot connect to the ThingsBoard server with a new configuration."
             )
             return False
         else:
             self.__old_tb_client.unsubscribe("*")
             self.__old_tb_client.stop()
             self.__gateway.tb_client.client.gw_set_server_side_rpc_request_handler(
                 self.__gateway._rpc_request_handler)
             self.__gateway.tb_client.client.set_server_side_rpc_request_handler(
                 self.__gateway._rpc_request_handler)
             self.__gateway.tb_client.client.subscribe_to_all_attributes(
                 self.__gateway._attribute_update_callback)
             self.__gateway.tb_client.client.gw_subscribe_to_all_attributes(
                 self.__gateway._attribute_update_callback)
             return True
     except Exception as e:
         log.exception(e)
         self.__revert_configuration()
         return False
    def __init__(self, config_file=None):
        self.stopped = False
        self.__lock = RLock()
        if config_file is None:
            config_file = path.dirname(path.dirname(
                path.abspath(__file__))) + '/config/tb_gateway.yaml'.replace(
                    '/', path.sep)
        with open(config_file) as general_config:
            self.__config = safe_load(general_config)
        self._config_dir = path.dirname(path.abspath(config_file)) + path.sep
        logging_error = None
        try:
            logging.config.fileConfig(self._config_dir + "logs.conf",
                                      disable_existing_loggers=False)
        except Exception as e:
            logging_error = e
        global log
        log = logging.getLogger('service')
        log.info("Gateway starting...")
        self.__updater = TBUpdater()
        self.__updates_check_period_ms = 300000
        self.__updates_check_time = 0
        self.version = self.__updater.get_version()
        log.info("ThingsBoard IoT gateway version: %s",
                 self.version["current_version"])
        self.available_connectors = {}
        self.__connector_incoming_messages = {}
        self.__connected_devices = {}
        self.__saved_devices = {}
        self.__events = []
        self.name = ''.join(choice(ascii_lowercase) for _ in range(64))
        self.__rpc_register_queue = Queue(-1)
        self.__rpc_requests_in_progress = {}
        self.__connected_devices_file = "connected_devices.json"
        self.tb_client = TBClient(self.__config["thingsboard"],
                                  self._config_dir)
        self.tb_client.connect()
        self.subscribe_to_required_topics()
        self.__subscribed_to_rpc_topics = True
        if logging_error is not None:
            self.tb_client.client.send_telemetry({
                "ts": time() * 1000,
                "values": {
                    "LOGS":
                    "Logging loading exception, logs.conf is wrong: %s" %
                    (str(logging_error), )
                }
            })
            TBLoggerHandler.set_default_handler()
        self.counter = 0
        self.__rpc_reply_sent = False
        global main_handler
        self.main_handler = main_handler
        self.remote_handler = TBLoggerHandler(self)
        self.main_handler.setTarget(self.remote_handler)
        self._default_connectors = DEFAULT_CONNECTORS
        self._implemented_connectors = {}
        self._event_storage_types = {
            "memory": MemoryEventStorage,
            "file": FileEventStorage,
        }
        self.__gateway_rpc_methods = {
            "ping": self.__rpc_ping,
            "stats": self.__form_statistics,
            "devices": self.__rpc_devices,
            "update": self.__rpc_update,
            "version": self.__rpc_version,
        }
        self.__remote_shell = None
        if self.__config["thingsboard"].get("remoteShell"):
            log.warning(
                "Remote shell is enabled. Please be carefully with this feature."
            )
            self.__remote_shell = RemoteShell(
                platform=self.__updater.get_platform(),
                release=self.__updater.get_release())
        self.__rpc_remote_shell_command_in_progress = None
        self.__sheduled_rpc_calls = []
        self.__rpc_sheduled_methods_functions = {
            "restart": {
                "function": execv,
                "arguments":
                (executable, [executable.split(pathsep)[-1]] + argv)
            },
            "reboot": {
                "function": system,
                "arguments": ("reboot 0", )
            },
        }
        self._event_storage = self._event_storage_types[
            self.__config["storage"]["type"]](self.__config["storage"])
        self.connectors_configs = {}
        self.__remote_configurator = None
        self.__request_config_after_connect = False
        self.__init_remote_configuration()
        self._load_connectors()
        self._connect_with_connectors()
        self.__load_persistent_devices()
        self._published_events = Queue(-1)
        self._send_thread = Thread(target=self.__read_data_from_storage,
                                   daemon=True,
                                   name="Send data to Thingsboard Thread")
        self._send_thread.start()
        log.info("Gateway started.")

        try:
            gateway_statistic_send = 0
            connectors_configuration_check_time = 0
            while not self.stopped:
                cur_time = time() * 1000
                if not self.tb_client.is_connected(
                ) and self.__subscribed_to_rpc_topics:
                    self.__subscribed_to_rpc_topics = False
                if self.tb_client.is_connected(
                ) and not self.__subscribed_to_rpc_topics:
                    for device in self.__saved_devices:
                        self.add_device(
                            device, {
                                "connector":
                                self.__saved_devices[device]["connector"]
                            },
                            device_type=self.__saved_devices[device]
                            ["device_type"])
                    self.subscribe_to_required_topics()
                    self.__subscribed_to_rpc_topics = True
                if self.__sheduled_rpc_calls:
                    for rpc_call_index in range(len(
                            self.__sheduled_rpc_calls)):
                        rpc_call = self.__sheduled_rpc_calls[rpc_call_index]
                        if cur_time > rpc_call[0]:
                            rpc_call = self.__sheduled_rpc_calls.pop(
                                rpc_call_index)
                            result = None
                            try:
                                result = rpc_call[1]["function"](
                                    *rpc_call[1]["arguments"])
                            except Exception as e:
                                log.exception(e)
                            if result == 256:
                                log.warning(
                                    "Error on RPC command: 256. Permission denied."
                                )
                if (self.__rpc_requests_in_progress
                        or not self.__rpc_register_queue.empty()
                    ) and self.tb_client.is_connected():
                    new_rpc_request_in_progress = {}
                    if self.__rpc_requests_in_progress:
                        for rpc_in_progress, data in self.__rpc_requests_in_progress.items(
                        ):
                            if cur_time >= data[1]:
                                data[2](rpc_in_progress)
                                self.cancel_rpc_request(rpc_in_progress)
                                self.__rpc_requests_in_progress[
                                    rpc_in_progress] = "del"
                        new_rpc_request_in_progress = {
                            key: value
                            for key, value in
                            self.__rpc_requests_in_progress.items()
                            if value != 'del'
                        }
                    if not self.__rpc_register_queue.empty():
                        rpc_request_from_queue = self.__rpc_register_queue.get(
                            False)
                        topic = rpc_request_from_queue["topic"]
                        data = rpc_request_from_queue["data"]
                        new_rpc_request_in_progress[topic] = data
                    self.__rpc_requests_in_progress = new_rpc_request_in_progress
                else:
                    try:
                        sleep(.1)
                    except Exception as e:
                        log.exception(e)
                        break
                if not self.__request_config_after_connect and self.tb_client.is_connected(
                ) and not self.tb_client.client.get_subscriptions_in_progress(
                ):
                    self.__request_config_after_connect = True
                    self.__check_shared_attributes()

                if cur_time - gateway_statistic_send > self.__config[
                        "thingsboard"].get(
                            "statsSendPeriodInSeconds",
                            3600) * 1000 and self.tb_client.is_connected():
                    summary_messages = self.__form_statistics()
                    # with self.__lock:
                    self.tb_client.client.send_telemetry(summary_messages)
                    gateway_statistic_send = time() * 1000
                    # self.__check_shared_attributes()

                if cur_time - connectors_configuration_check_time > self.__config[
                        "thingsboard"].get(
                            "checkConnectorsConfigurationInSeconds",
                            60) * 1000:
                    self.check_connector_configuration_updates()
                    connectors_configuration_check_time = time() * 1000

                if cur_time - self.__updates_check_time >= self.__updates_check_period_ms:
                    self.__updates_check_time = time() * 1000
                    self.version = self.__updater.get_version()

        except KeyboardInterrupt:
            self.__stop_gateway()
        except Exception as e:
            log.exception(e)
            self.__stop_gateway()
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
Esempio n. 5
0
    def __init__(self, config_file=None):
        self.__lock = RLock()
        if config_file is None:
            config_file = path.dirname(path.dirname(
                path.abspath(__file__))) + '/config/tb_gateway.yaml'.replace(
                    '/', path.sep)
        with open(config_file) as general_config:
            config = safe_load(general_config)
        self._config_dir = path.dirname(path.abspath(config_file)) + path.sep
        logging.config.fileConfig(self._config_dir + "logs.conf")
        global log
        log = logging.getLogger('service')
        log.info("Gateway starting...")
        self.version = get_distribution('thingsboard_gateway').version
        log.info("ThingsBoard IoT gateway version: %s", self.version)
        self.available_connectors = {}
        self.__connector_incoming_messages = {}
        self.__connected_devices = {}
        self.__saved_devices = {}
        self.__events = []
        self.name = ''.join(choice(ascii_lowercase) for _ in range(64))
        self.__rpc_requests_in_progress = {}
        self.__connected_devices_file = "connected_devices.json"
        self.tb_client = TBClient(config["thingsboard"])
        self.tb_client.connect()
        self.subscribe_to_required_topics()
        self.counter = 0
        self.__rpc_reply_sent = False
        global main_handler
        self.main_handler = main_handler
        self.remote_handler = TBLoggerHandler(self)
        self.main_handler.setTarget(self.remote_handler)
        self._default_connectors = {
            "mqtt": "MqttConnector",
            "modbus": "ModbusConnector",
            "opcua": "OpcUaConnector",
            "ble": "BLEConnector",
            "request": "RequestConnector",
            "can": "CanConnector"
        }
        self._implemented_connectors = {}
        self._event_storage_types = {
            "memory": MemoryEventStorage,
            "file": FileEventStorage,
        }
        self.__gateway_rpc_methods = {
            "ping": self.__rpc_ping,
            "stats": self.__form_statistics,
            "devices": self.__rpc_devices,
        }
        self.__sheduled_rpc_calls = []
        self.__self_rpc_sheduled_methods_functions = {
            "restart": {
                "function": execv,
                "arguments":
                (executable, [executable.split(pathsep)[-1]] + argv)
            },
            "reboot": {
                "function": system,
                "arguments": ("reboot 0", )
            },
        }
        self._event_storage = self._event_storage_types[
            config["storage"]["type"]](config["storage"])
        self.connectors_configs = {}
        self._load_connectors(config)
        self._connect_with_connectors()
        self.__remote_configurator = None
        self.__request_config_after_connect = False
        if config["thingsboard"].get("remoteConfiguration"):
            try:
                self.__remote_configurator = RemoteConfigurator(self, config)
            except Exception as e:
                log.exception(e)
        if self.__remote_configurator is not None:
            self.__remote_configurator.send_current_configuration()
        self.__load_persistent_devices()
        self._published_events = Queue(-1)
        self._send_thread = Thread(target=self.__read_data_from_storage,
                                   daemon=True,
                                   name="Send data to Thingsboard Thread")
        self._send_thread.start()
        log.info("Gateway started.")

        try:
            gateway_statistic_send = 0
            while True:
                cur_time = time() * 1000
                if self.__sheduled_rpc_calls:
                    for rpc_call_index in range(len(
                            self.__sheduled_rpc_calls)):
                        rpc_call = self.__sheduled_rpc_calls[rpc_call_index]
                        if cur_time > rpc_call[0]:
                            rpc_call = self.__sheduled_rpc_calls.pop(
                                rpc_call_index)
                            result = None
                            try:
                                result = rpc_call[1]["function"](
                                    *rpc_call[1]["arguments"])
                            except Exception as e:
                                log.exception(e)
                            if result == 256:
                                log.warning(
                                    "Error on RPC command: 256. Permission denied."
                                )
                if self.__rpc_requests_in_progress and self.tb_client.is_connected(
                ):
                    for rpc_in_progress, data in self.__rpc_requests_in_progress.items(
                    ):
                        if cur_time >= data[1]:
                            data[2](rpc_in_progress)
                            self.cancel_rpc_request(rpc_in_progress)
                            self.__rpc_requests_in_progress[
                                rpc_in_progress] = "del"
                    new_rpc_request_in_progress = {
                        key: value
                        for key, value in
                        self.__rpc_requests_in_progress.items()
                        if value != 'del'
                    }
                    self.__rpc_requests_in_progress = new_rpc_request_in_progress
                else:
                    try:
                        sleep(.1)
                    except Exception as e:
                        log.exception(e)
                        break
                if not self.__request_config_after_connect and self.tb_client.is_connected(
                ) and not self.tb_client.client.get_subscriptions_in_progress(
                ):
                    self.__request_config_after_connect = True
                    self.__check_shared_attributes()

                if cur_time - gateway_statistic_send > 5000.0 and self.tb_client.is_connected(
                ):
                    summary_messages = self.__form_statistics()
                    # with self.__lock:
                    self.tb_client.client.send_telemetry(summary_messages)
                    gateway_statistic_send = time() * 1000
                    # self.__check_shared_attributes()
        except KeyboardInterrupt:
            log.info("Stopping...")
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
        except Exception as e:
            log.exception(e)
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
Esempio n. 6
0
    def __init__(self, config_file=None):
        if config_file is None:
            config_file = path.dirname(path.dirname(
                path.abspath(__file__))) + '/config/tb_gateway.yaml'.replace(
                    '/', path.sep)
        with open(config_file) as general_config:
            config = safe_load(general_config)
        self._config_dir = path.dirname(path.abspath(config_file)) + path.sep
        logging.config.fileConfig(self._config_dir + "logs.conf")
        global log
        log = logging.getLogger('service')
        self.available_connectors = {}
        self.__connector_incoming_messages = {}
        self.__connected_devices = {}
        self.__saved_devices = {}
        self.__events = []
        self.name = ''.join(choice(ascii_lowercase) for _ in range(64))
        self.__rpc_requests_in_progress = {}
        self.__connected_devices_file = "connected_devices.json"
        self.tb_client = TBClient(config["thingsboard"])
        self.tb_client.connect()
        self.subscribe_to_required_topics()
        global main_handler
        self.main_handler = main_handler
        self.remote_handler = TBLoggerHandler(self)
        self.main_handler.setTarget(self.remote_handler)
        self._default_connectors = {
            "mqtt": "MqttConnector",
            "modbus": "ModbusConnector",
            "opcua": "OpcUaConnector",
            "ble": "BLEConnector",
        }
        self._implemented_connectors = {}
        self._event_storage_types = {
            "memory": MemoryEventStorage,
            "file": FileEventStorage,
        }
        self._event_storage = self._event_storage_types[
            config["storage"]["type"]](config["storage"])
        self.connectors_configs = {}
        self._load_connectors(config)
        self._connect_with_connectors()
        self.__remote_configurator = None
        self.__request_config_after_connect = False
        if config["thingsboard"].get("remoteConfiguration"):
            try:
                self.__remote_configurator = RemoteConfigurator(self, config)
            except Exception as e:
                log.exception(e)
        if self.__remote_configurator is not None:
            self.__remote_configurator.send_current_configuration()
        self.__load_persistent_devices()
        self.__published_events = Queue(0)
        self.__send_thread = Thread(target=self.__read_data_from_storage,
                                    daemon=True,
                                    name="Send data to Thingsboard Thread")
        self.__send_thread.start()

        try:
            gateway_statistic_send = 0
            while True:
                cur_time = time.time() * 1000
                if self.__rpc_requests_in_progress and self.tb_client.is_connected(
                ):
                    for rpc_in_progress, data in self.__rpc_requests_in_progress.items(
                    ):
                        if cur_time >= data[1]:
                            data[2](rpc_in_progress)
                            self.cancel_rpc_request(rpc_in_progress)
                            self.__rpc_requests_in_progress[
                                rpc_in_progress] = "del"
                    new_rpc_request_in_progress = {
                        key: value
                        for key, value in
                        self.__rpc_requests_in_progress.items()
                        if value != 'del'
                    }
                    self.__rpc_requests_in_progress = new_rpc_request_in_progress

                else:
                    try:
                        time.sleep(1)
                    except Exception as e:
                        log.exception(e)
                        break
                if not self.__request_config_after_connect and \
                        self.tb_client.is_connected() and not self.tb_client.client.get_subscriptions_in_progress():
                    self.__request_config_after_connect = True
                    self.__check_shared_attributes()

                if cur_time - gateway_statistic_send > 60000.0 and self.tb_client.is_connected(
                ):
                    summary_messages = self.__form_statistics()
                    self.tb_client.client.send_telemetry(summary_messages)
                    gateway_statistic_send = time.time() * 1000
                    # self.__check_shared_attributes()
        except KeyboardInterrupt:
            log.info("Stopping...")
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
        except Exception as e:
            log.exception(e)
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
Esempio n. 7
0
    def __init__(self, config_file=None):
        if config_file is None:
            config_file = path.dirname(path.dirname(
                path.abspath(__file__))) + '/config/tb_gateway.yaml'
        with open(config_file) as general_config:
            config = safe_load(general_config)
        self._config_dir = path.dirname(path.abspath(config_file)) + '/'
        logging.config.fileConfig(self._config_dir + "logs.conf")
        global log
        log = logging.getLogger('service')
        self.available_connectors = {}
        self.__connector_incoming_messages = {}
        self.__connected_devices = {}
        self.__saved_devices = {}
        self.__events = []
        self.name = ''.join(choice(ascii_lowercase) for _ in range(64))
        self.__rpc_requests_in_progress = {}
        self.__connected_devices_file = "connected_devices.json"
        self.tb_client = TBClient(config["thingsboard"])
        self.tb_client.connect()
        self.tb_client.client.gw_set_server_side_rpc_request_handler(
            self._rpc_request_handler)
        self.tb_client.client.set_server_side_rpc_request_handler(
            self._rpc_request_handler)
        self.tb_client.client.subscribe_to_all_attributes(
            self._attribute_update_callback)
        self.tb_client.client.gw_subscribe_to_all_attributes(
            self._attribute_update_callback)
        global main_handler
        self.main_handler = main_handler
        self.remote_handler = TBLoggerHandler(self)
        self.main_handler.setTarget(self.remote_handler)
        self._default_connectors = {
            "mqtt": "MqttConnector",
            "modbus": "ModbusConnector",
            "opcua": "OpcUaConnector",
            "ble": "BLEConnector",
        }
        self._implemented_connectors = {}
        self._event_storage_types = {
            "memory": MemoryEventStorage,
            "file": FileEventStorage,
        }
        self._event_storage = self._event_storage_types[
            config["storage"]["type"]](config["storage"])
        self._connectors_configs = {}
        self._load_connectors(config)
        self._connect_with_connectors()
        self.__remote_configurator = None
        self.__request_config_after_connect = False
        if config["thingsboard"].get("remoteConfiguration"):
            try:
                self.__remote_configurator = RemoteConfigurator(self, config)
            except Exception as e:
                log.exception(e)
        if self.__remote_configurator is not None:
            self.__remote_configurator.send_current_configuration()
        self.__load_persistent_devices()
        self.__published_events = Queue(0)
        self.__send_thread = Thread(target=self.__read_data_from_storage,
                                    daemon=True,
                                    name="Send data to Thingsboard Thread")
        self.__send_thread.start()

        try:
            gateway_statistic_send = 0
            while True:
                cur_time = time.time()
                if self.__rpc_requests_in_progress and self.tb_client.is_connected(
                ):
                    for rpc_in_progress in self.__rpc_requests_in_progress:
                        if cur_time >= self.__rpc_requests_in_progress[
                                rpc_in_progress][1]:
                            self.__rpc_requests_in_progress[rpc_in_progress][
                                2](rpc_in_progress)
                            self.cancel_rpc_request(rpc_in_progress)
                    time.sleep(0.1)
                else:
                    try:
                        time.sleep(1)
                    except Exception as e:
                        log.exception(e)
                        break
                if  not self.__request_config_after_connect and \
                        self.tb_client.is_connected() and not self.tb_client.client.get_subscriptions_in_progress():
                    self.__request_config_after_connect = True
                    self.__check_shared_attributes()

                if cur_time - gateway_statistic_send > 60.0 and self.tb_client.is_connected(
                ):
                    summary_messages = {"eventsProduced": 0, "eventsSent": 0}
                    telemetry = {}
                    for connector in self.available_connectors:
                        if self.available_connectors[connector].is_connected():
                            connector_camel_case = connector[0].lower(
                            ) + connector[1:].replace(' ', '')
                            telemetry[(connector_camel_case + ' EventsProduced').replace(' ', '')] = \
                                self.available_connectors[connector].statistics['MessagesReceived']
                            telemetry[(connector_camel_case + ' EventsSent').replace(' ', '')] = \
                                self.available_connectors[connector].statistics['MessagesSent']
                            self.tb_client.client.send_telemetry(telemetry)
                            summary_messages['eventsProduced'] += telemetry[
                                str(connector_camel_case +
                                    ' EventsProduced').replace(' ', '')]
                            summary_messages['eventsSent'] += telemetry[str(
                                connector_camel_case + ' EventsSent').replace(
                                    ' ', '')]
                    self.tb_client.client.send_telemetry(summary_messages)
                    gateway_statistic_send = time.time()
                    # self.__check_shared_attributes()
        except KeyboardInterrupt as e:
            log.info("Stopping...")
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
        except Exception as e:
            log.exception(e)
            self.__close_connectors()
            log.info("The gateway has been stopped.")
            self.tb_client.stop()
Esempio n. 8
0
    def __init__(self, config_file=None):
        if config_file is None:
            config_file = path.dirname(path.dirname(
                path.abspath(__file__))) + '/config/tb_gateway.yaml'
        with open(config_file) as config:
            config = safe_load(config)
            self.__config_dir = path.dirname(path.abspath(config_file)) + '/'
            logging.config.fileConfig(self.__config_dir + "logs.conf")
            global log
            log = logging.getLogger('service')
            self.available_connectors = {}
            self.__connector_incoming_messages = {}
            self.__connected_devices = {}
            self.__saved_devices = {}
            self.__events = []
            self.__rpc_requests_in_progress = {}
            self.__connected_devices_file = "connected_devices.json"
            self.tb_client = TBClient(config["thingsboard"])
            self.main_handler = logging.handlers.MemoryHandler(1000)
            self.remote_handler = TBLoggerHandler(self)
            self.main_handler.setTarget(self.remote_handler)
            self.__default_connectors = {
                "mqtt": "MqttConnector",
                "modbus": "ModbusConnector",
                "opcua": "OpcUaConnector",
                "ble": "BLEConnector",
            }
            self.__implemented_connectors = {}
            self.__event_storage_types = {
                "memory": MemoryEventStorage,
                "file": FileEventStorage,
            }
            self.__load_connectors(config)
            self.__connect_with_connectors()
            self.__load_persistent_devices()
            self.__published_events = Queue(0)
            self.__send_thread = Thread(target=self.__read_data_from_storage,
                                        daemon=True,
                                        name="Send data to Thingsboard Thread")
            self.__event_storage = self.__event_storage_types[
                config["storage"]["type"]](config["storage"])
            self.tb_client.connect()
            self.tb_client.client.gw_set_server_side_rpc_request_handler(
                self.__rpc_request_handler)
            self.tb_client.client.set_server_side_rpc_request_handler(
                self.__rpc_request_handler)
            self.tb_client.client.subscribe_to_all_attributes(
                self.__attribute_update_callback)
            self.tb_client.client.gw_subscribe_to_all_attributes(
                self.__attribute_update_callback)
            self.__send_thread.start()

            try:
                gateway_statistic_send = 0
                while True:
                    cur_time = time.time()
                    if self.__rpc_requests_in_progress and self.tb_client.is_connected(
                    ):
                        for rpc_in_progress in self.__rpc_requests_in_progress:
                            if cur_time >= self.__rpc_requests_in_progress[
                                    rpc_in_progress][1]:
                                self.__rpc_requests_in_progress[
                                    rpc_in_progress][2](rpc_in_progress)
                                self.cancel_rpc_request(rpc_in_progress)
                        time.sleep(0.1)
                    else:
                        time.sleep(1)

                    if cur_time - gateway_statistic_send > 60.0 and self.tb_client.is_connected(
                    ):
                        summary_messages = {
                            "eventsProduced": 0,
                            "eventsSent": 0
                        }
                        telemetry = {}
                        for connector in self.available_connectors:
                            if self.available_connectors[
                                    connector].is_connected():
                                connector_camel_case = connector[0].lower(
                                ) + connector[1:].replace(' ', '')
                                telemetry[(connector_camel_case + ' EventsProduced').replace(' ', '')] = \
                                self.available_connectors[connector].statistics['MessagesReceived']
                                telemetry[(connector_camel_case + ' EventsSent').replace(' ', '')] = \
                                self.available_connectors[connector].statistics['MessagesSent']
                                self.tb_client.client.send_telemetry(telemetry)
                                summary_messages[
                                    'eventsProduced'] += telemetry[str(
                                        connector_camel_case +
                                        ' EventsProduced').replace(' ', '')]
                                summary_messages['eventsSent'] += telemetry[
                                    str(connector_camel_case +
                                        ' EventsSent').replace(' ', '')]
                        self.tb_client.client.send_telemetry(summary_messages)
                        gateway_statistic_send = time.time()
            except Exception as e:
                log.exception(e)
                for device in self.__connected_devices:
                    log.debug("Close connection for device %s", device)
                    try:
                        current_connector = self.__connected_devices[
                            device].get("connector")
                        if current_connector is not None:
                            current_connector.close()
                            log.debug("Connector %s closed connection.",
                                      current_connector.get_name())
                    except Exception as e:
                        log.error(e)