async def run(self): try: await service_status.wait_autoconnecting(self.app) service_status.set_connected(self.app, self._address) self.update_ticks() await self.welcome() while True: await asyncio.sleep(3600) except Exception as ex: # pragma: no cover LOGGER.error(strex(ex)) raise ex finally: service_status.set_disconnected(self.app)
async def test_system_status(app, client): await service_status.wait_synchronized(app) resp = await response(client.get('/system/status')) fw_info = { 'firmware_version': ANY, 'proto_version': ANY, 'firmware_date': ANY, 'proto_date': ANY, 'device_id': ANY, } assert resp == { 'device_address': 'simulation:1234', 'connection_kind': 'wifi', 'service_info': { **fw_info, 'name': 'test_app', }, 'device_info': { **fw_info, 'system_version': ANY, 'platform': ANY, 'reset_reason': ANY, }, 'handshake_info': { 'is_compatible_firmware': True, 'is_latest_firmware': True, 'is_valid_device_id': True, }, 'is_autoconnecting': True, 'is_connected': True, 'is_acknowledged': True, 'is_synchronized': True, 'is_updating': False, } service_status.set_disconnected(app) await asyncio.sleep(0.01) resp = await response(client.get('/system/status')) assert resp['is_synchronized'] is False assert resp['is_connected'] is False assert resp['device_info'] is None
async def shutdown(self, app: web.Application): service_status.set_disconnected(app)
async def run(self): """Implements RepeaterFeature.run""" try: if self._retry_count >= CONNECT_RETRY_COUNT: raise ConnectionAbortedError() if self._retry_count == 1: LOGGER.info('Retrying connection...') if self._retry_count > 0: await asyncio.sleep(self.retry_interval) await service_status.wait_autoconnecting(self.app) result = await connect_funcs.connect(self.app) self._proc = result.process self._address = result.address self._reader = result.reader self._writer = result.writer self._parser = cbox_parser.ControlboxParser() service_status.set_connected(self.app, self._address) self._retry_count = 0 self.reset_retry_interval() LOGGER.info(f'{self} connected') while self.connected: # read() does not raise an exception when connection is closed # connected status must be checked explicitly later recv = await self._reader.read(100) # read() returns empty if EOF received if not recv: # pragma: no cover raise ConnectionError('EOF received') # Send to parser self._parser.push(recv.decode()) # Drain parsed messages for msg in self._parser.event_messages(): await self._on_event(msg) for msg in self._parser.data_messages(): await self._on_data(msg) raise ConnectionError('Connection closed') except ConnectionAbortedError: LOGGER.error('Connection aborted. Exiting now.') self.increase_retry_interval() raise web.GracefulExit() except connect_funcs.DiscoveryAbortedError as ex: LOGGER.error('Device discovery failed.') if ex.reboot_required: self._retry_count += 1 raise ex except Exception: self._retry_count += 1 raise finally: with suppress(Exception): self._writer.close() LOGGER.info(f'{self} closed stream writer') with suppress(Exception): self._proc.terminate() LOGGER.info(f'{self} terminated subprocess') service_status.set_disconnected(self.app) self._proc = None self._reader = None self._writer = None self._parser = None
async def disconnect(app): service_status.set_disconnected(app) await service_status.wait_disconnected(app) await asyncio.sleep(0.01)