async def created(app, client, object_args):
    status.get_status(app).connected.set()
    retv = await client.post('/objects', json={
        API_SID_KEY: object_args[OBJECT_SID_KEY],
        GROUP_LIST_KEY: object_args[GROUP_LIST_KEY],
        API_TYPE_KEY: object_args[OBJECT_TYPE_KEY],
        API_DATA_KEY: object_args[OBJECT_DATA_KEY],
    })
    assert retv.status < 400
Esempio n. 2
0
async def test_system_status(app, client):
    resp = await response(client.get('/system/status'))
    assert resp == {
        'connected': True,
        'synchronized': True,
    }
    status.get_status(app).connected.clear()
    status.get_status(app).disconnected.set()
    await asyncio.sleep(0.01)
    resp = await response(client.get('/system/status'))
    assert resp == {
        'connected': False,
        'synchronized': False,
    }
Esempio n. 3
0
def states(app):
    state = status.get_status(app)
    return [
        state.disconnected.is_set(),
        state.connected.is_set(),
        state.synchronized.is_set(),
    ]
Esempio n. 4
0
    async def _maintain_connection(self, connect_func: Callable[[], Awaitable[ConnectionResult_]]):
        last_ok = True
        while True:
            try:
                spark_status = status.get_status(self.app)
                self._address, self._transport, self._protocol = await connect_func()

                await self._protocol.connected
                LOGGER.info(f'Connected {self}')
                spark_status.disconnected.clear()
                spark_status.connected.set()
                last_ok = True

                await self._protocol.disconnected
                LOGGER.info(f'Disconnected {self}')
                spark_status.connected.clear()
                spark_status.disconnected.set()

            except CancelledError:
                with suppress(Exception):
                    await self._transport.close()
                break

            except Exception as ex:
                if last_ok:
                    LOGGER.info(f'Connection failed: {type(ex).__name__}({ex})')
                    last_ok = False
                await asyncio.sleep(RETRY_INTERVAL_S)

            finally:
                # Keep last known address
                self._transport = None
                self._protocol = None
Esempio n. 5
0
    async def _broadcast(self):
        LOGGER.info(f'Starting {self}')

        try:
            api = ObjectApi(self.app)
            spark_status: status.SparkStatus = status.get_status(self.app)

        except Exception as ex:
            LOGGER.error(strex(ex), exc_info=True)
            raise ex

        while True:
            try:
                await spark_status.synchronized.wait()
                await asyncio.sleep(PUBLISH_INTERVAL_S)

                if not self._queues:
                    self._current = None
                    continue

                self._current = await api.all()
                coros = [q.put(self._current) for q in self._queues]
                await asyncio.wait_for(
                    asyncio.gather(*coros, return_exceptions=True),
                    PUBLISH_INTERVAL_S)

            except asyncio.CancelledError:
                break

            except Exception as ex:
                self._current = None
                warnings.warn(f'{self} encountered an error: {strex(ex)}')
Esempio n. 6
0
async def _broadcast(app: web.Application,
                     sid: str,
                     exchange: str,
                     routing: str,
                     interval: int
                     ):
    publisher = events.get_publisher(app)
    spark_status = status.get_status(app)
    ctrl = device.get_controller(app)
    last_broadcast_ok = True

    while True:
        try:
            await spark_status.connected.wait()
            await asyncio.sleep(interval)
            obj = await ctrl.read_object({OBJECT_SID_KEY: sid})

            await publisher.publish(
                exchange=exchange,
                routing=routing,
                message=obj[OBJECT_DATA_KEY]
            )

            if not last_broadcast_ok:
                LOGGER.info(f'Remote publisher [{routing}] resumed Ok')
                last_broadcast_ok = True

        except CancelledError:
            break

        except Exception as ex:
            if last_broadcast_ok:
                warnings.warn(f'Remote publisher [{routing}] encountered an error: {strex(ex)}')
                last_broadcast_ok = False
Esempio n. 7
0
    async def _seed(self):
        spark_status = status.get_status(self.app)

        while True:
            await spark_status.connected.wait()
            await self._seed_datastore()
            await self._seed_time()
            spark_status.synchronized.set()

            await spark_status.disconnected.wait()
            spark_status.synchronized.clear()
Esempio n. 8
0
    async def _broadcast(self):
        try:
            name = self.app['config']['name']
            interval = self.app['config']['broadcast_interval']
            exchange = self.app['config']['broadcast_exchange']

            if interval <= 0 or self.app['config']['volatile']:
                LOGGER.info(f'{self} disabled by user')
                return

            LOGGER.info(f'Starting {self}')

            api = ObjectApi(self.app)
            spark_status = status.get_status(self.app)
            publisher = events.get_publisher(self.app)
            last_broadcast_ok = True

        except Exception as ex:
            LOGGER.error(f'{type(ex).__name__}: {str(ex)}', exc_info=True)
            raise ex

        while True:
            try:
                await spark_status.synchronized.wait()
                await asyncio.sleep(interval)
                current_objects = {
                    obj[API_SID_KEY]: obj[API_DATA_KEY]
                    for obj in await api.all_logged()
                    if not obj[API_SID_KEY].startswith(GENERATED_ID_PREFIX)
                }

                # Don't broadcast when empty
                if not current_objects:
                    continue

                await publisher.publish(exchange=exchange,
                                        routing=name,
                                        message=current_objects)

                if not last_broadcast_ok:
                    LOGGER.info(f'{self} resumed Ok')
                    last_broadcast_ok = True

            except CancelledError:
                break

            except Exception as ex:
                if last_broadcast_ok:
                    warnings.warn(
                        f'{self} encountered an error: {type(ex).__name__}({ex})'
                    )
                    last_broadcast_ok = False
Esempio n. 9
0
async def check_status(request: web.Request) -> web.Response:
    """
    ---
    summary: Get service status
    tags:
    - Spark
    - System
    operationId: controller.spark.system.status
    produces:
    - application/json
    """
    _status = status.get_status(request.app)
    return web.json_response({
        'connected': _status.connected.is_set(),
        'synchronized': _status.synchronized.is_set(),
    })
Esempio n. 10
0
async def test_codec_config(app, client, cdc):
    state = status.get_status(app)

    updated = cdc.update_unit_config({'Temp': 'degF'})
    assert updated['Temp'] == 'degF'
    assert cdc.get_unit_config() == updated

    # disconnect
    state.connected.clear()
    state.disconnected.set()
    await asyncio.sleep(0.01)
    # connect
    state.disconnected.clear()
    state.connected.set()
    await asyncio.sleep(0.01)

    assert cdc.get_unit_config()['Temp'] == 'degC'
Esempio n. 11
0
async def spark_status(app):
    return status.get_status(app)
Esempio n. 12
0
async def disconnect(app):
    state = status.get_status(app)
    state.connected.clear()
    state.disconnected.set()
    await asyncio.sleep(0.01)
Esempio n. 13
0
 def __init__(self, app: web.Application, wait_sync=True):
     self._wait_sync = wait_sync
     self._status = status.get_status(app)
     self._ctrl: device.SparkController = device.get_controller(app)
     self._store: twinkeydict.TwinKeyDict = datastore.get_datastore(app)
Esempio n. 14
0
 async def startup(self, app: web.Application):
     await self._responder.startup(app)
     status.get_status(app).connected.set()
Esempio n. 15
0
async def connected(app, client):
    status.get_status(app).connected.set()
    status.get_status(app).synchronized.set()