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