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)
Exemple #2
0
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
Exemple #3
0
 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)