def start_client(mysql_db_server_ip, mysql_user, mysql_password, mysql_db_name, REDIS_HOST, REDIS_PORT, REDIS_db): url = SERVER_URL refresh_token = SERVER_REFRESH_TOKEN dh = DeviceHive(ClientHandler, 'IoTServer', mysql_db_server_ip, mysql_user, mysql_password, mysql_db_name, REDIS_HOST, REDIS_PORT, REDIS_db) dh.connect(url, refresh_token=refresh_token)
def run(self, handle_connect, handle_command_insert=None, handle_command_update=None, handle_notification=None, timeout=5): handler_kwargs = {'handle_connect': handle_connect, 'handle_command_insert': handle_command_insert, 'handle_command_update': handle_command_update, 'handle_notification': handle_notification} device_hive = DeviceHive(TestHandler, **handler_kwargs) device_hive.connect(self._transport_url, refresh_token=self._refresh_token) device_hive.join(timeout) exception_info = device_hive.exception_info() if not exception_info: return six.reraise(*exception_info)
def run(self, handle_connect, handle_command_insert=None, handle_command_update=None, handle_notification=None, handle_timeout=60): handler_kwargs = { 'handle_connect': handle_connect, 'handle_command_insert': handle_command_insert, 'handle_command_update': handle_command_update, 'handle_notification': handle_notification } device_hive = DeviceHive(TestHandler, **handler_kwargs) timeout_timer = threading.Timer(handle_timeout, self._on_handle_timeout, args=(device_hive, )) timeout_timer.setDaemon(True) timeout_timer.start() device_hive.connect(self._transport_url, **self._credentials) timeout_timer.cancel() if self._is_handle_timeout: raise TimeoutError('Waited too long for handle.')
def run(self, handle_connect, handle_command_insert=None, handle_command_update=None, handle_notification=None, handle_timeout=60): handler_kwargs = {'handle_connect': handle_connect, 'handle_command_insert': handle_command_insert, 'handle_command_update': handle_command_update, 'handle_notification': handle_notification} device_hive = DeviceHive(TestHandler, **handler_kwargs) device_hive.connect(self._transport_url, transport_keep_alive=False, **self._credentials) start_time = time.time() while time.time() - handle_timeout < start_time: exception_info = device_hive.transport.exception_info if exception_info: six.reraise(*exception_info) if not device_hive.handler.api.connected: return time.sleep(self._timeout_sleep_time) raise TimeoutError('Waited too long for handle.')
str(temperature)) self._scheduler.enter(float(READINGS_INTERVAL), 60, self._timer_loop, ()) def handle_connect(self): logger.info('connecting to server...' + SERVER_URL) self._device = self.api.put_device(self._device_id) # self._device.subscribe_insert_commands() logger.info('Connected!') self._timer_loop() t = threading.Thread(target=self._scheduler.run) t.setDaemon(True) t.start() def handle_command_insert(self, command): if command.command == 'led/on': GPIO.output(LED_PIN, 1) command.status = "Ok" elif command.command == 'led/off': GPIO.output(LED_PIN, 0) command.status = "Ok" else: command.status = "Unknown command" command.save() dh = DeviceHive(SampleHandler) dh.connect(SERVER_URL, refresh_token=SERVER_REFRESH_TOKEN)
'devicehive.api_request': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False }, } } logging.config.dictConfig(LOGGING) class EchoHandler(Handler): def __init__(self, api, device_id='example-echo-device'): super(EchoHandler, self).__init__(api) self._device_id = device_id self._device = None def handle_connect(self): self._device = self.api.put_device(self._device_id) self._device.subscribe_insert_commands() def handle_command_insert(self, command): self._device.send_notification(command.command, parameters=command.parameters) url = 'http://playground.devicehive.com/api/rest' refresh_token = 'PUT_YOUR_REFRESH_TOKEN_HERE' dh = DeviceHive(EchoHandler) dh.connect(url, refresh_token=refresh_token)
def _run_instance(subscribe_notifications): dh = DeviceHive(DHHandler, subscribe_notifications) dh.connect(SERVER_URL, refresh_token=REFRESH_TOKEN)
class Daemon(Server): _dh_thread = None _process_thread = None _web_thread = None _process_buf = None _ask_data_event = None _captor = None _sample_rate = 16000 _processor_sleep_time = 0.01 dh_cfg = None deviceHive = None dh_status = None events_queue = None base_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'web') def __init__(self, *args, **kwargs): kwargs.setdefault('routes', routes) min_time = kwargs.pop('min_capture_time', 5) max_time = kwargs.pop('max_capture_time', 5) self._save_path = kwargs.pop('max_capture_time', None) super(Daemon, self).__init__(*args, **kwargs) self.events_queue = deque(maxlen=10) self.dh_cfg = Config('config.json', update_callback=self._restart_dh) self.dh_status = DHStatus() self._web_thread = threading.Thread( target=self._web_loop, daemon=True, name='web') self._ask_data_event = threading.Event() self._process_thread = threading.Thread( target=self._process_loop, daemon=True, name='processor') self._captor = Captor( min_time, max_time, self._ask_data_event, self._process) def send_dh(self, data): if not self._is_dh_connected(): logger.warning('Devicehive is not connected') return self.deviceHive.handler.send(data) def start(self): self._start_web() self.dh_cfg.load() # this will start DH thread automatically self._start_capture() self._start_process() def _start_web(self): logger.info('Start server http://{}:{}'.format(*self.server_address)) self._web_thread.start() def _start_dh(self): if self._is_dh_connected(): logging.info('Devicehive already started') return logger.info('Start devicehive') self._dh_thread = threading.Thread( target=self._dh_loop, daemon=True, name='device_hive') self._dh_thread.start() def _stop_dh(self): if not self._is_dh_connected(): logging.info('Devicehive already stopped') return # TODO: Now it's only one proper way to call disconnect, we need # implement better way to do it self.deviceHive.transport.handler.handler.api.disconnect() def _restart_dh(self): if self._is_dh_connected(): self._stop_dh() self._start_dh() def _is_dh_connected(self): return self.dh_status.connected def _start_capture(self): logger.info('Start captor') self._captor.start() def _start_process(self): logger.info('Start processor loop') self._process_thread.start() def _web_loop(self): self.serve_forever() def _dh_loop(self): self.dh_status.set_connecting() self.deviceHive = DeviceHive( DeviceHiveHandler, self.dh_cfg.data['deviceid']) error = '' try: self.dh_status.set_connected() url = self.dh_cfg.data['url'] refresh_token = self.dh_cfg.data['token'] self.deviceHive.connect(url, refresh_token=refresh_token) except TransportError as e: logger.exception(e) error = str(e) finally: self.dh_status.set_disconnected(error) logger.info('Stop devicehive') def _process(self, data): self._process_buf = np.frombuffer(data, dtype=np.int16) def _process_loop(self): with WavProcessor() as proc: self._ask_data_event.set() while True: if self._process_buf is None: # Waiting for data to process time.sleep(self._processor_sleep_time) continue self._ask_data_event.clear() if self._save_path: f_path = os.path.join( self._save_path, 'record_{:.0f}.wav'.format(time.time()) ) wavfile.write(f_path, self._sample_rate, self._process_buf) logger.info('"{}" saved'.format(f_path)) logger.info('Start processing') predictions = proc.get_predictions( self._sample_rate, self._process_buf) formatted = format_predictions(predictions) logger.info( 'Predictions: {}'.format(formatted)) self.events_queue.append((datetime.datetime.now(), formatted)) self.send_dh(predictions) logger.info('Stop processing') self._process_buf = None self._ask_data_event.set()
class Worker(threading.Thread): def __init__(self, supervisor, url, message_type, message_name, message_payload, base_device_name, thread_index, access_token=None, refresh_token=None, delay=1., cleanup=False): threading.Thread.__init__(self, name='Worker_%s' % thread_index) self._supervisor = supervisor self._url = url self._message_type = message_type self._message_name = message_name self._message_template = Template(message_payload) self._device_name = base_device_name + str(thread_index) self._access_token = access_token self._refresh_token = refresh_token self._delay = delay self._cleanup = cleanup self._dh = None self._device = None self._payload_method = None self._last_message_time = 0. def _init(self): self._dh = DeviceHive(WorkerHandler) self._dh.connect(self._url, access_token=self._access_token, refresh_token=self._refresh_token, transport_keep_alive=False) while not self._dh.handler.connected and self._supervisor.is_running: time.sleep(.001) self._device = self._dh.handler.api.put_device(self._device_name) method_name = 'send_%s' % self._message_type self._payload_method = getattr(self._device, method_name) self._last_message_time = time.time() def _get_payload(self): return json.loads(self._message_template.render(**PAYLOAD)) def _send_message(self): start = time.time() last_sent = start - self._last_message_time if last_sent > 15.0: logger.warning('Previous message was sent %s seconds ago.', last_sent) self._payload_method(self._message_name, self._get_payload()) now = time.time() message_time = now - start if message_time > 10.0: logger.warning('Message send request took %s seconds.', message_time) self._last_message_time = now def run(self): self._init() try: while self._supervisor.is_running: self._send_message() self._supervisor.counter.increment() time.sleep(self._delay) finally: if self._cleanup: self._device.remove() self._dh.handler.api.disconnect()
class Server(object): """ Encapsulates DeviceHive connection and web server. Can be easily extended to add more services to run. """ dh_cfg = None dh_status = None deviceHive = None webServer = None _dh_thread = None _web_thread = None _dh_handler_class = None _dh_handler_args = None _dh_handler_kwargs = None _is_blocking = None __is_running = None def __init__(self, dh_handler_class, routes=(), static_dirs=(), is_blocking=True, server_address=('0.0.0.0', 8000), initial_config=None, *dh_handler_args, **dh_handler_kwargs): """ Initialize web server and devicehive client. :param dh_handler_class: Handler class for devicehive client. :param routes: Additional routes for web server. :param static_dirs: Additional static dirs for web server. :param is_blocking: If True blocking loop wil be started on startup. :param server_address: Server address to serve web ui. :param initial_config: Dict with Devicehive config. :param dh_handler_args: Additional args to be passed to handler. :param dh_handler_kwargs: Additional kwargs to be passed to handler. """ self._dh_handler_class = dh_handler_class self._dh_handler_args = dh_handler_args self._dh_handler_kwargs = dh_handler_kwargs self._is_blocking = is_blocking self._initial_config = initial_config self.dh_status = Status() self.dh_cfg = Config(update_callback=self._restart_dh) self.webServer = WebServer(server=self, routes=routes, static_dirs=static_dirs, server_address=server_address, RequestHandlerClass=RoutedHandler) self._web_thread = threading.Thread( target=self._web_loop, name='web') self._web_thread.setDaemon(True) @property def is_running(self): return self.__is_running def start(self): self.__is_running = True self._start_web() # this will start DH thread automatically if self._initial_config: self.dh_cfg.save(self._initial_config) else: self.dh_cfg.load() self._on_startup() if self._is_blocking: self._blocking_loop() def stop(self): self.__is_running = False self.webServer.shutdown() self._stop_dh() self._on_shutdown() def _on_startup(self): """ Can be overridden by nested classes to start additional processes """ pass def _on_shutdown(self): """ Can be overridden by nested classes to stop additional processes """ pass def _blocking_loop(self): try: while self.__is_running: time.sleep(.001) except KeyboardInterrupt: logger.info( 'Warm shutdown request by Ctrl-C. Press again to use force.') try: self.stop() except KeyboardInterrupt: logger.info('May the force be with you!') raise def _web_loop(self): self.webServer.serve_forever() def _dh_loop(self): self.deviceHive = DeviceHive(self._dh_handler_class, device_id=self.dh_cfg.data['device_id'], connect_cb=self._dh_connect, *self._dh_handler_args, **self._dh_handler_kwargs) error = '' try: self.dh_status.set_connecting() url = self.dh_cfg.data['url'] access_token = self.dh_cfg.data['a_token'] refresh_token = self.dh_cfg.data['r_token'] self.deviceHive.connect(url, access_token=access_token, refresh_token=refresh_token) except TransportError as e: logger.exception(e) error = str(e) finally: self.dh_status.set_disconnected(error) logger.info('Stop devicehive') def _dh_connect(self): self.dh_status.set_connected() def _start_web(self): logger.info('Start web server on http://{}:{}'.format( *self.webServer.server_address)) self._web_thread.start() def _start_dh(self): if self.dh_status.connected: logging.info('Devicehive already started') return logger.info('Start devicehive') self._dh_thread = threading.Thread( target=self._dh_loop, name='device_hive') self._dh_thread.setDaemon(True) self._dh_thread.start() def _stop_dh(self): if not self.dh_status.connected: logging.info('Devicehive already stopped') return self.deviceHive.handler.api.disconnect() logging.info('Stoping devicehive...') self._dh_thread.join() def _restart_dh(self): if self.dh_status.connected: self._stop_dh() self._start_dh()
class Daemon(Server): _dh_thread = None _process_thread = None _web_thread = None _process_buf = None _ask_data_event = None _captor = None _sample_rate = 16000 _processor_sleep_time = 0.01 dh_cfg = None deviceHive = None dh_status = None events_queue = None base_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'web') def __init__(self, *args, **kwargs): kwargs.setdefault('routes', routes) min_time = kwargs.pop('min_capture_time', 5) max_time = kwargs.pop('max_capture_time', 5) self._save_path = kwargs.pop('max_capture_time', None) super(Daemon, self).__init__(*args, **kwargs) self.events_queue = deque(maxlen=10) self.dh_cfg = Config('config.json', update_callback=self._restart_dh) self.dh_status = DHStatus() self._web_thread = threading.Thread(target=self._web_loop, daemon=True, name='web') self._ask_data_event = threading.Event() self._process_thread = threading.Thread(target=self._process_loop, daemon=True, name='processor') self._captor = Captor(min_time, max_time, self._ask_data_event, self._process) def send_dh(self, data): if not self._is_dh_connected(): logger.warning('Devicehive is not connected') return self.deviceHive.handler.send(data) def start(self): self._start_web() self.dh_cfg.load() # this will start DH thread automatically self._start_capture() self._start_process() def _start_web(self): logger.info('Start server http://{}:{}'.format(*self.server_address)) self._web_thread.start() def _start_dh(self): if self._is_dh_connected(): logging.info('Devicehive already started') return logger.info('Start devicehive') self._dh_thread = threading.Thread(target=self._dh_loop, daemon=True, name='device_hive') self._dh_thread.start() def _stop_dh(self): if not self._is_dh_connected(): logging.info('Devicehive already stopped') return # TODO: Now it's only one proper way to call disconnect, we need # implement better way to do it self.deviceHive.transport.handler.handler.api.disconnect() def _restart_dh(self): if self._is_dh_connected(): self._stop_dh() self._start_dh() def _is_dh_connected(self): return self.dh_status.connected def _start_capture(self): logger.info('Start captor') self._captor.start() def _start_process(self): logger.info('Start processor loop') self._process_thread.start() def _web_loop(self): self.serve_forever() def _dh_loop(self): self.dh_status.set_connecting() self.deviceHive = DeviceHive(DeviceHiveHandler, self.dh_cfg.data['deviceid']) error = '' try: self.dh_status.set_connected() url = self.dh_cfg.data['url'] refresh_token = self.dh_cfg.data['token'] self.deviceHive.connect(url, refresh_token=refresh_token) except TransportError as e: logger.exception(e) error = str(e) finally: self.dh_status.set_disconnected(error) logger.info('Stop devicehive') def _process(self, data): self._process_buf = np.frombuffer(data, dtype=np.int16) def _process_loop(self): with WavProcessor() as proc: self._ask_data_event.set() while True: if self._process_buf is None: # Waiting for data to process time.sleep(self._processor_sleep_time) continue self._ask_data_event.clear() if self._save_path: f_path = os.path.join( self._save_path, 'record_{:.0f}.wav'.format(time.time())) wavfile.write(f_path, self._sample_rate, self._process_buf) logger.info('"{}" saved'.format(f_path)) logger.info('Start processing') predictions = proc.get_predictions(self._sample_rate, self._process_buf) formatted = format_predictions(predictions) logger.info('Predictions: {}'.format(formatted)) self.events_queue.append((datetime.datetime.now(), formatted)) self.send_dh(predictions) logger.info('Stop processing') self._process_buf = None self._ask_data_event.set()