def on_error(self, ws, error):
     # If this connection is a test, send the event
     if self.being_tested:
         notify_test_event(self.data_collector_id, 'ERROR', str(error))
         self.log.error(f"Error testing DataCollector ID {self.data_collector_id}: {str(error)}")
         self.stop_testing = True
         return
     else:
         self.log.error(f"Error ws: {str(error)}")
 def on_connect(self, client, userdata, flags, rc):
     # If this connection is a test, activate the flag and emit the event
     if self.being_tested:
         notify_test_event(client.data_collector_id, 'SUCCESS', 'Connection successful')
         self.stop_testing = True
         return
     else:
         client.subscribe(client.topics)
         self.connected = "CONNECTED"
     self.log.info("Connected to: {} with result code: {}".format(client.host, rc))
    def on_open(self, ws):  # similar to on_connect
        # If this connection is a test, activate the flag and emit the event
        if self.being_tested:
            notify_test_event(self.data_collector_id, 'SUCCESS', 'Connection successful')
            self.stop_testing = True
            return

        ws.send('["gateway:' + ws.gateway + '"]')
        ws.send('["token:' + ws.access_token + '"]')
        self.connected = "CONNECTED"
        ws.is_closed = False
        self.log.info(f"Connected to GW: {ws.gateway}" )
    def test(self):
        self.log.info(f'Testing connection')
        self.being_tested = True
        self.stop_testing = False

        # Try to connect the collector as in regular scenario
        self.connect()
        timeout = datetime.now() + timedelta(seconds=30)

        while not self.stop_testing and datetime.now() < timeout:
            sleep(1)
        self.disconnect()

        if not self.stop_testing:  # Means that the collector didn't have any update within the timeout
            message = 'Timeout error of {0} seconds exceeded.'.format(timeout)
            notify_test_event(self.data_collector_id, 'ERROR', message)

        self.disconnect()
    def connect(self):
        super(TTNCollector, self).connect()
        self.session = self.login(self.user, self.password)
        if self.session:
            self.connected = "CONNECTED"
            self.manually_disconnected = None
            data_access = self.fetch_access_token(self.session)
            access_token = data_access.get('access_token')
            expires = data_access.get('expires')

            self.ws = websocket.WebSocketApp(
                ws_url,
                on_message=lambda ws, msg: self.on_message(ws, msg),
                on_error=lambda ws, msg: self.on_error(ws, msg),
                on_close=lambda ws: self.on_close(ws))
            self.log.debug(f'WebSocket app initialized')
            self.ws.access_token = access_token
            self.ws.gateway = self.gateway_id
            self.ws.organization_id = self.organization_id
            self.ws.data_collector_id = self.data_collector_id
            self.ws.on_open = lambda ws: self.on_open(ws)
            self.ws.user_data = self
            self.ws.is_closed = False

            self.ws.packet_writter_message = self.packet_writter_message
            self.ws.location = self.location

            self.ws_thread = threading.Thread(target=self.ws.run_forever,
                                              kwargs={'ping_interval': 20})
            self.ws_thread.daemon = True
            self.ws_thread.start()

            self.refresh_token_thread = threading.Thread(
                target=self.schedule_refresh_token,
                args=(self.ws, self.session, expires))
            self.refresh_token_thread.daemon = True
            self.refresh_token_thread.start()
        else:
            if self.being_tested:
                notify_test_event(self.data_collector_id, 'ERROR',
                                  'Login failed')
                self.stop_testing = True
            else:
                save_login_error(self.data_collector_id)
示例#6
0
    def run_stream(self):
        init_connection = True

        headers = [
            'Accept: text/event-stream',
            'Authorization: Bearer ' + self.api_key
        ]
        post_data = {
            'identifiers': [{
                'gateway_ids': {
                    'gateway_id': self.gateway_name
                }
            }]
        }

        if self.region == 'eu1':
            stream_url = stream_eu1_url
        elif self.region == 'nam1':
            stream_url = stream_nam1_url
        elif self.region == 'au1':
            stream_url = stream_au1_url

        while True:
            if init_connection:
                curl = pycurl.Curl()
                curl.setopt(pycurl.HTTPHEADER, headers)
                curl.setopt(pycurl.URL, stream_url)
                curl.setopt(pycurl.WRITEFUNCTION, self.on_receive)
                curl.setopt(pycurl.POSTFIELDS, json.dumps(post_data))
                curl.setopt(pycurl.TIMEOUT, STREAM_TIMEOUT)

                multi_curl = pycurl.CurlMulti()
                multi_curl.add_handle(curl)

                init_connection = False

            multi_curl.perform()
            status_code = curl.getinfo(pycurl.RESPONSE_CODE)

            if status_code == 0:
                sleep(1)
            elif status_code == 200:
                if self.being_tested:
                    notify_test_event(self.data_collector_id, 'SUCCESS',
                                      'Connection successful')
                    self.stop_testing = True

                self.connected = 'CONNECTED'
                self.manually_disconnected = None

                while True:
                    if self.manually_disconnected:
                        curl.close()
                        multi_curl.close()
                        del multi_curl, curl
                        return

                    multi_curl.perform()
                    error = curl.errstr()

                    if error == '':
                        pass
                    elif 'Operation timed out' in error:
                        # Restart the connection every STREAM_TIMEOUT secs
                        curl.close()
                        multi_curl.close()
                        init_connection = True
                        break
                    else:
                        self.connected = 'DISCONNECTED'
                        curl.close()
                        multi_curl.close()
                        del multi_curl, curl
                        self.log.error(
                            f'Error reading data in TTNCollector ID {self.data_collector_id}: {error}'
                        )
                        return

                    sleep(1)
            else:
                self.connected = 'DISCONNECTED'
                curl.close()
                multi_curl.close()
                del multi_curl, curl
                if self.being_tested:
                    notify_test_event(self.data_collector_id, 'ERROR',
                                      'Connection failed')
                    self.stop_testing = True
                else:
                    save_login_error(self.data_collector_id)
                return