Ejemplo n.º 1
0
            def _attempt_connect(**kwargs):
                ignore = kwargs.pop('ignore', [])
                try:
                    # Attempt to connect to automatically selected port.
                    dropbot = db.SerialProxy(port=port,
                                             ignore=ignore,
                                             **kwargs)
                    raise asyncio.Return(dropbot)
                except db.proxy.NoPower as exception:
                    # No 12V power supply detected on DropBot.
                    _L().debug('No 12V power supply detected.')
                    responses = signals.signal('no-power').send('keep_alive')

                    for t in asyncio.as_completed(
                        [loop.create_task(r[1]) for r in responses]):
                        response = yield asyncio.From(t)
                        if response == 'ignore':
                            ignore.append(db.proxy.NoPower)
                            break
                    else:
                        raise exception
                except bnr.proxy.DeviceVersionMismatch as exception:
                    # Firmware version does not match driver version.
                    _L().debug(
                        'Driver version (`%s`) does not match firmware '
                        'version (`%s`)', db.__version__,
                        exception.device_version)
                    responses = signals.signal('version-mismatch')\
                        .send('keep_alive', driver_version=db.__version__,
                            firmware_version=exception.device_version)

                    update = False

                    for t in asyncio.as_completed(
                        [loop.create_task(r[1]) for r in responses]):
                        response = yield asyncio.From(t)
                        if response == 'ignore':
                            ignore.append(bnr.proxy.DeviceVersionMismatch)
                            break
                        elif response == 'update':
                            update = True
                            break
                    else:
                        raise

                    if update:
                        # Flash firmware and retry connection.
                        _L().info('Flash firmware and retry connection.')
                        yield asyncio.From(co_flash_firmware())

                dropbot = yield asyncio.From(
                    _attempt_connect(ignore=ignore, **kwargs))
                raise asyncio.Return(dropbot)
Ejemplo n.º 2
0
    def set_waveform(key, value):
        exception = None
        result = signals.signal('set-%s' % key).send(value)
        if result:
            try:
                receivers, co_callbacks = zip(*result)
                if receivers:
                    results = yield asyncio.From(asyncio.gather(*co_callbacks))
            except asyncio.CancelledError:
                raise
            except Exception as exception:
                pass
            else:
                if receivers:
                    raise asyncio.Return(zip(receivers, results))

        if exception is not None:
            message = ('Error setting **%s**: `%s`' % (key, exception))
        else:
            message = ('No waveform generators available to set **%s**.' % key)

        yield asyncio.From(
            _warning(signals.signal('warning'),
                     message,
                     title='Warning: failed to set %s' % key,
                     key='waveform-%s' % key))
Ejemplo n.º 3
0
def list_controllers(self, timeout):
    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug("List of controllers received with status={}".format(
            packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            controllers = packet.get(name='controllers',
                                     format_function=lambda raw_ctrls: [
                                         Controller.from_flatbuffers(raw_ctrl)
                                         for raw_ctrl in raw_ctrls
                                     ])

            future.set_result(controllers)
        else:
            future.set_exception(
                BaBLEException(packet, "Failed to list controllers"))

    future = asyncio.Future()
    request_packet = Packet.build(GetControllersList)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Waiting for list of controllers...")
    try:
        controllers = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(controllers)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        raise RuntimeError("List controllers timed out")
Ejemplo n.º 4
0
def schema_input(schema,
                 message='**Please fill in the following fields:**',
                 description=None):
    '''
    Asynchronous GTK input dialog based on JSON schema.

    Parameters
    ----------
    schema : dict
        JSON schema.
    message : str, optional
        Message presented in dialog.
    description : str, optional
        Title of input dialog.

    Returns
    -------
    dict or None
        Mapping from field name to entered value if ``OK`` button was
        pressed. Otherwise, ``None``.
    '''
    # Wrap dialog function call in partial since `gtk_threadsafe` does
    # not support passing keyword arguments.
    dialog_func = ft.partial(schema_dialog,
                             schema,
                             title=description,
                             type=gtk.MESSAGE_OTHER,
                             message_format=markdown2pango(message),
                             buttons=gtk.BUTTONS_OK_CANCEL)
    # Queue dialog to be launched in GTK thread and wait for response.
    response = yield asyncio.From(sync(gtk_threadsafe)(dialog_func)())
    if response is None:
        raise RuntimeError('Cancelled in response to message `%s`.' % message)
    raise asyncio.Return(response)
Ejemplo n.º 5
0
def read_frame(signals):
    '''
    :py:mod:`trollius` `asyncio` wrapper to return a single frame produced by a
    ``frame-ready`` event signalled by
    :func:`dropbot_chip_qc.video.chip_video_process()`.

    Parameters
    ----------
    signals : blinker.Namespace
        DMF chip webcam monitor signals (see
        :func:`dropbot_chip_qc.video.chip_video_process()`).
    '''
    loop = asyncio.get_event_loop()

    frame_ready = asyncio.Event()
    response = {}

    def on_frame_ready(sender, **message):
        response.update(message)
        loop.call_soon_threadsafe(frame_ready.set)

    signals.signal('frame-ready').connect(on_frame_ready)

    yield asyncio.From(frame_ready.wait())
    raise asyncio.Return(response)
Ejemplo n.º 6
0
def transfer_windows(signals,
                     channel_plan,
                     completed_transfers,
                     co_transfer,
                     n=2):
    def on_transfer_complete(sender, **message):
        transfer_i = message['completed_transfers'][-1]
        print('\r%-100s' %
              ('completed transfer `%s` to `%s`' %
               (transfer_i['channels'][:-1], transfer_i['channels'][1:])),
              end='')

    signals.signal('transfer-complete').connect(on_transfer_complete)

    channel_plan_i = list(channel_plan)

    while len(channel_plan_i) > 1:
        try:
            channel_plan_i, completed_transfers = yield asyncio\
                .From(_next_transfer(channel_plan=channel_plan_i,
                                     completed_transfers=completed_transfers,
                                     co_transfer=co_transfer, n=n))
        except Exception as exception:
            raise TransferFailed(channel_plan_i, completed_transfers,
                                 exception)
        else:
            signals.signal('transfer-complete')\
                .send(caller_name(0),
                      channel_plan=channel_plan_i,
                      completed_transfers=completed_transfers)
    channel_plan_i = []
    result = dict(channel_plan=channel_plan_i,
                  completed_transfers=completed_transfers)
    signals.signal('test-complete').send(caller_name(0), **result)
    raise asyncio.Return(result)
Ejemplo n.º 7
0
def call(ES_URL, queries):
    results = []
    results_append = results.append
    futures = _do_calls(ES_URL, queries)
    for future in futures:
        result = yield trollius.From(future)
        results_append(result)
    raise trollius.Return(results)
Ejemplo n.º 8
0
def _next_transfer(channel_plan, completed_transfers, co_transfer, n=2):
    transfer_channels = channel_plan[:n]
    result = yield asyncio.From(co_transfer(transfer_channels))
    raise asyncio.Return(
        channel_plan[1:], completed_transfers + [{
            'channels': transfer_channels,
            'result': result
        }])
Ejemplo n.º 9
0
def actuate_channels(self, channels, allow_disabled=True):
    '''
    Parameters
    ----------
    channels : list
        List of channel numbers to actuate.
    allow_disabled : bool, optional
        If ``False``, verify actuated channels match specified channels
        _exactly_.  Otherwise, ensure that all actuated channels belong to the
        specified set of channels, _even if_ not _all_ specified channels are
        actuated.  This supports attempting to actuate channels that are
        disabled.

    Returns
    -------
    list
        List of actuated channels.  If :data:`allow_disabled` is ``True``, the
        returned list of channels may differ from the specified list of
        channels.

    Raises
    ------
    RuntimeError
        If list actuated channels does not match the requested channels
        (missing disabled channels are ignored if ``allowed_disabled`` is
        `True`).
    '''
    loop = asyncio.get_event_loop()

    channels_updated = asyncio.Event()

    def _on_channels_updated(message):
        channels_updated.actuated = message.get('actuated')
        loop.call_soon_threadsafe(channels_updated.set)

    # Enable `channels-updated` DropBot signal.
    self.enable_event(db.proxy.EVENT_CHANNELS_UPDATED)

    # Request to be notified when the set of actuated channels changes.
    signal = self.signals.signal('channels-updated')
    signal.connect(_on_channels_updated)

    # Request actuation of the specified channels.
    self.set_state_of_channels(pd.Series(1, index=channels), append=False)

    yield asyncio.From(channels_updated.wait())
    if not allow_disabled and (set(channels_updated.actuated) !=
                               set(channels)):
        raise RuntimeError('Actuated channels `%s` do not match '
                           'expected channels `%s`' %
                           (channels_updated.actuated, channels))
    elif set(channels_updated.actuated) - set(channels):
        # Disabled channels are allowed.
        raise RuntimeError('Actuated channels `%s` are not included in'
                           ' expected channels `%s`' %
                           (channels_updated.actuated, channels))
    raise asyncio.Return(channels_updated.actuated)
Ejemplo n.º 10
0
def probe_characteristics(self, controller_id, connection_handle, start_handle,
                          end_handle, on_characteristics_probed, timeout):

    if isinstance(on_characteristics_probed, (tuple, list)):
        on_characteristics_probed_cb = on_characteristics_probed[0]
        on_characteristics_probed_params = on_characteristics_probed[1:]
    else:
        on_characteristics_probed_cb = on_characteristics_probed
        on_characteristics_probed_params = []

    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug(
            "Probe characteristics response received with status={}".format(
                packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            characteristics = packet.get_dict([
                'controller_id', 'connection_handle',
                ('characteristics', lambda chars:
                 [Characteristic.from_flatbuffers(char) for char in chars])
            ])
            on_characteristics_probed_cb(True, characteristics, None,
                                         *on_characteristics_probed_params)
            future.set_result(characteristics)
        else:
            error = BaBLEException(packet,
                                   "Failed to probe characteristics",
                                   connection_handle=connection_handle)
            on_characteristics_probed_cb(False, None, error,
                                         *on_characteristics_probed_params)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(ProbeCharacteristics,
                                  controller_id=controller_id,
                                  connection_handle=connection_handle,
                                  start_handle=start_handle,
                                  end_handle=end_handle)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Waiting for characteristics...")
    try:
        characteristics = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(characteristics)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        raise RuntimeError("Probe characteristics timed out")
Ejemplo n.º 11
0
def read(self, controller_id, connection_handle, attribute_handle, on_read,
         timeout):

    if isinstance(on_read, (tuple, list)):
        on_read_cb = on_read[0]
        on_read_params = on_read[1:]
    else:
        on_read_cb = on_read
        on_read_params = []

    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug("Read response received with status={}".format(
            packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            data = packet.get_dict([
                'controller_id', 'connection_handle', 'attribute_handle',
                ('value', bytes)
            ])

            on_read_cb(True, data, None, *on_read_params)

            future.set_result(data)
        else:
            error = BaBLEException(packet,
                                   "Failed to read value",
                                   connection_handle=connection_handle,
                                   attribute_handle=attribute_handle)
            on_read_cb(False, None, error, *on_read_params)

            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(ReadCentral,
                                  controller_id=controller_id,
                                  connection_handle=connection_handle,
                                  attribute_handle=attribute_handle)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Reading...")
    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        on_read_cb(False, None, "Read timed out", *on_read_params)
        raise RuntimeError("Read timed out")
Ejemplo n.º 12
0
def transfer_liquid(aproxy, channels, **kwargs):
    '''
    Transfer liquid from tail n-1 channels to head n-1 channels.

        xxxx... -> ...xxxx

    where ``x`` denotes liquid and ``.`` denotes an empty electrode.

    This is accomplished through two separate actuations::

     1. Actuate all but the **last** channel in ``channels``.
     2. Actuate all but the **first** channel in ``channels``.

    Actuation **(1)** is applied until a steady-state capacitance is reached.
    At this point, the measured capacitance is recorded as a target threshold.
    Actuation **(2)** is then applied until the target threshold capacitance
    from actuation **(1)** is reached.
    '''
    messages_ = []

    try:
        tail_channels_i = list(channels[:-1])
        route_i = list(
            it.chain(*(c if isinstance(c, collections.Sequence) else [c]
                       for c in tail_channels_i)))
        print('\r%-50s' % ('Wait for steady state: %s' % list(route_i)),
              end='')
        messages = yield asyncio\
            .From(actuate(aproxy, route_i, ft.partial(test_steady_state_,
                                                      **kwargs)))
        messages_.append({'channels': tuple(route_i), 'messages': messages})
        target_capacitance_i = ((float(len(channels) - 1) / len(channels)) *
                                messages[-1]['new_value'])

        head_channels_i = list(channels[1:])
        print('\r%-50s' % ('Wait for target capacitance of: %sF' %
                           si.si_format(target_capacitance_i)),
              end='')
        route_i = list(
            it.chain(*(c if isinstance(c, collections.Sequence) else [c]
                       for c in head_channels_i)))

        def test_threshold(messages):
            df = pd.DataFrame(messages[-5:])
            return df.new_value.median() >= target_capacitance_i

        messages = yield asyncio\
            .From(actuate(aproxy, route_i, test_threshold))
        messages_.append({'channels': tuple(route_i), 'messages': messages})
    except (asyncio.CancelledError, asyncio.TimeoutError):
        raise TransferTimeout(channels)

    raise asyncio.Return(messages_)
Ejemplo n.º 13
0
def execute(plugin_kwargs, signals):
    '''
    XXX Coroutine XXX

    Parameters
    ----------
    plugin_kwargs : dict
        Plugin settings as JSON serializable dictionary.
    signals : blinker.Namespace
        Signals namespace.
    '''
    if NAME not in plugin_kwargs:
        raise asyncio.Return([])
    else:
        kwargs = plugin_kwargs[NAME]

    # Wait for plugins to connect to signals as necessary.
    event = asyncio.Event()
    signals.signal('signals-connected').connect(lambda *args: event.set(),
                                                weak=False)
    yield asyncio.From(event.wait())

    voltage = kwargs['Voltage (V)']
    frequency = kwargs['Frequency (Hz)']
    duration_s = kwargs['Duration (s)']
    static_states = kwargs.get('electrode_states', pd.Series())
    dynamic = kwargs.get('dynamic', True)
    result = yield asyncio.From(
        execute_actuations(signals,
                           static_states,
                           voltage,
                           frequency,
                           duration_s,
                           dynamic=dynamic))

    logger = _L()  # use logger with function context
    logger.info('%d/%d actuations completed', len(result), len(result))
    logger.debug('completed actuations: `%s`', result)
    raise asyncio.Return(result)
Ejemplo n.º 14
0
def load(proxy,
         channels,
         threshold=50e-12,
         load_duration=.25,
         detach_duration=2.):
    '''Load reservoir to specified threshold capacitance.

    Steps::

     1. Load: actuate first electrode until threshold capacitance is met.
     2. Detach: turn off first electrode and actuate the remaining electrodes
        until threshold capacitance is met.

    Parameters
    ----------
    channels : list
        List of channel numbers to actuate.
    threshold : float, optional
        Minimum median capacitance in Farads (from most recent ``N`` samples)
        before considering load complete (default: 50 pF).
    load_duration : float, optional
        Seconds before first electrode capacitance is considered stable
        (default: 0.25).
    detach_duration : float, optional
        Seconds before detaching electrodes capacitance is considered stable
        (default: 0.5).

    Returns
    -------
    list
        See `wait_on_capacitance()` for return type.
    '''
    # Load starting reservoir.
    logging.debug('Wait for channel `%s` to be loaded', channels[:1])
    yield asyncio.From(
        actuate(
            proxy, channels[:-1],
            ft.partial(test_steady_state,
                       min_duration=load_duration,
                       threshold=1.1 * threshold)))

    detach_channels = channels[1:]
    logging.debug(
        'Wait for liquid to detach from edge electrode `%s` to '
        '`%s`...', channels[:1], detach_channels)
    messages = yield asyncio\
        .From(actuate(proxy, detach_channels,
                      ft.partial(test_steady_state,
                                 min_duration=detach_duration,
                                 threshold=threshold)))
    raise asyncio.Return(messages)
Ejemplo n.º 15
0
def actuate(proxy, channels, callback):
    '''Actuate channels and wait for callback to return `True`.

    Parameters
    ----------
    channels : list
        List of channel numbers to actuate.
    callback
        Callback function accepting a list of ``capacitance-updated`` messages
        as only argument.
    '''
    # Actuate channels.
    yield asyncio.From(actuate_channels(proxy, channels))
    # Wait for callback.
    result = yield asyncio.From(wait_on_capacitance(proxy, callback))
    raise asyncio.Return(result)
Ejemplo n.º 16
0
 def execute_test(*args, **kwargs):
     yield asyncio.From(set_capacitance_update_interval())
     try:
         result = yield asyncio\
             .From(qc.ui.plan.transfer_windows(*args, **kwargs))
     except qc.ui.plan.TransferFailed as exception:
         # Save intermediate result.
         result = dict(
             channel_plan=exception.channel_plan,
             completed_transfers=exception.completed_transfers)
         signals.signal('test-interrupt').send(caller_name(0), **result)
     self.completed_results.append(result)
     yield asyncio.From(
         aproxy.set_state_of_channels(pd.Series(), append=False))
     # result = dict(channel_plan=channel_plan_i,
     # completed_transfers=completed_transfers_i)
     raise asyncio.Return(result)
Ejemplo n.º 17
0
def cancel_connection(self, controller_id, on_connection_cancelled, timeout):

    if isinstance(on_connection_cancelled, (tuple, list)):
        on_connection_cancelled_cb = on_connection_cancelled[0]
        on_connection_cancelled_params = on_connection_cancelled[1:]
    else:
        on_connection_cancelled_cb = on_connection_cancelled
        on_connection_cancelled_params = []

    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug(
            "Cancel connection response received with status={}".format(
                packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            on_connection_cancelled_cb(True, None, None,
                                       *on_connection_cancelled_params)
            future.set_result(True)
        else:
            error = BaBLEException(packet, "Failed to cancel connection")
            on_connection_cancelled_cb(False, None, error,
                                       *on_connection_cancelled_params)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(CancelConnection,
                                  controller_id=controller_id)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Waiting for connection to cancel...")
    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        on_connection_cancelled_cb(False, None, "Cancel connection timed out",
                                   *on_connection_cancelled_params)
        raise RuntimeError("Cancel connection timed out")
Ejemplo n.º 18
0
def set_gatt_table(self, controller_id, services, characteristics, on_set,
                   timeout):

    if isinstance(on_set, (tuple, list)):
        on_set_cb = on_set[0]
        on_set_params = on_set[1:]
    else:
        on_set_cb = on_set
        on_set_params = []

    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug("GATT table set with status={}".format(
            packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            data = packet.get_dict(['controller_id'])

            on_set_cb(True, data, None, *on_set_params)
            future.set_result(data)
        else:
            error = BaBLEException(packet, "Failed to set GATT table")
            on_set_cb(False, None, error, *on_set_params)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(SetGATTTable,
                                  controller_id=controller_id,
                                  services=services,
                                  characteristics=characteristics)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Waiting for setting GATT table response...")
    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        raise RuntimeError("Set GATT table timed out")
Ejemplo n.º 19
0
def wait_for_result(client, verb, prefix, name, *args, **kwargs):
    '''
    Example
    -------

    >>> client = Client(client_id='DropBot MQTT bridge')
    >>> ...
    >>> # bind MQTT client to DropBot monitor blinker signals namespace...
    >>> ...
    >>> prefix = '/dropbot/' + str(dropbot.uuid)
    >>> call = ft.partial(wait_for_result, client, 'call', prefix)
    >>> property = ft.partial(wait_for_result, client, 'property', prefix)
    >>> ...
    >>> loop = asyncio.get_event_loop()
    >>> loop.run_until_complete(property('voltage', 80))
    '''
    loop = asyncio.get_event_loop()
    result = asyncio.Event()

    def on_received(client, userdata, message):
        try:
            payload = message.payload or 'null'
            result.data = jt.loads(payload)
        except Exception:
            result.data = json.loads(payload)
            try:
                module_name = '.'.join(result.data['__instance_type__'][:-1])
                class_name = result.data['__instance_type__'][-1]
                module = __import__(module_name)
                cls = getattr(module, class_name)
                result.data = cls(**result.data['attributes'])
            except Exception:
                pass
        loop.call_soon_threadsafe(result.set)

    client.message_callback_add('%s/result/%s' % (prefix, name), on_received)

    try:
        payload = jt.dumps({'args': args, 'kwargs': kwargs})
        client.publish('%s/%s/%s' % (prefix, verb, name), payload=payload,
                       qos=1)
        yield asyncio.From(result.wait())
    finally:
        client.message_callback_remove(sub='%s/result/%s' % (prefix, name))
    raise asyncio.Return(result.data)
Ejemplo n.º 20
0
def stop_scan(self, controller_id, on_scan_stopped, timeout):

    if isinstance(on_scan_stopped, (tuple, list)):
        on_scan_stopped_cb = on_scan_stopped[0]
        on_scan_stopped_params = on_scan_stopped[1:]
    else:
        on_scan_stopped_cb = on_scan_stopped
        on_scan_stopped_params = []

    @asyncio.coroutine
    def on_response_received(packet, future):
        self.logger.debug("Stop scan response received with status={}".format(
            packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            self.remove_callback(
                PacketUuid(payload_type=Payload.DeviceFound,
                           controller_id=controller_id))
            on_scan_stopped_cb(True, packet.get_dict(['controller_id']), None,
                               *on_scan_stopped_params)
            future.set_result(True)
        else:
            error = BaBLEException(packet, "Failed to stop scan")
            on_scan_stopped_cb(False, None, error, *on_scan_stopped_params)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(StopScan, controller_id=controller_id)

    self.register_callback(request_packet.packet_uuid,
                           callback=on_response_received,
                           params={'future': future})

    self.send_packet(request_packet)

    self.logger.debug("Waiting for scan to stop...")
    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        on_scan_stopped_cb(False, None, "Stop scan timed out",
                           *on_scan_stopped_params)
        raise RuntimeError("Stop scan timed out")
Ejemplo n.º 21
0
 def get_ws_token(self, qlist):
     loop = trollius.get_event_loop()
     async_req = loop.run_in_executor(
         None,
         functools.partial(self.sina.session.get,
                           URL_WSKT_TOKEN,
                           params=PARAM_WSKT_TOKEN(ip=self.ip,
                                                   qlist=qlist,
                                                   hq=self.hq),
                           headers=HEADERS_WSKT_TOKEN(),
                           timeout=5))
     req = yield trollius.From(async_req)
     # self.logger.info(req.text)
     response = re.findall(r'(\{.*\})', req.text)[0]
     response = json.loads(
         response.replace(',', ',"').replace('{', '{"').replace(':', '":'))
     # gc.collect()
     raise trollius.Return(response)
Ejemplo n.º 22
0
    def on_no_power(*args, **kwargs):
        while True:
            response = raw_input('No 12V power supply detected.  '
                                 '[I]gnore/[s]kip: ')
            if not response:
                # Default response is `ignore` and try to connect anyway.
                response = 'ignore'

            for action in ('ignore', 'skip'):
                if action.startswith(response.lower()):
                    response = action
                    break
            else:
                print('Invalid response: `%s`' % response)
                response = None

            if response is not None:
                break
        raise asyncio.Return(response)
Ejemplo n.º 23
0
def notify(self, controller_id, connection_handle, attribute_handle, value,
           timeout):

    # TODO: use characteristic instead of attribute_handle

    @asyncio.coroutine
    def on_ack_received(packet, future):
        self.logger.debug(
            "EmitNotification ack received with status={}".format(
                packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            future.set_result(True)
        else:
            error = BaBLEException(packet,
                                   "Failed to send EmitNotification packet",
                                   connection_handle=connection_handle,
                                   attribute_handle=attribute_handle)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(EmitNotification,
                                  controller_id=controller_id,
                                  connection_handle=connection_handle,
                                  attribute_handle=attribute_handle,
                                  value=bytes(value))

    self.register_callback(request_packet.packet_uuid,
                           callback=on_ack_received,
                           params={'future': future})

    self.send_packet(request_packet)

    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        self.logger.debug("Notification sent")
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        raise RuntimeError("Notification timed out")
Ejemplo n.º 24
0
def wait_on_capacitance(proxy, callback):
    '''Return once callback returns `True`.

    Parameters
    ----------
    callback
        Callback function accepting a list of ``capacitance-updated`` messages
        as only argument.

    Returns
    -------
    list
        List of DropBot ``capacitance-updated`` messages containing the
        following keys::

         - ``event``: ``"capacitance-updated"``
         - ``new_value``: capacitance value in Farads
         - ``time_us``: DropBot microsecond 32-bit counter
         - ``n_samples``: number of samples used for RMS measurement
         - ``V_a``: measured actuation voltage during capacitance reading
    '''
    move_done = asyncio.Event()
    loop = asyncio.get_event_loop()

    messages = []

    def _on_capacitance(message):
        # message.keys == ['event', 'new_value', 'time_us', 'n_samples', 'V_a']
        # Added by `co_target_capacitance()`: 'actuation_uuid1', 'actuated_channels'
        try:
            messages.append(message)
            if callback(messages):
                loop.call_soon_threadsafe(move_done.set)
        except Exception:
            logging.debug('capacitance event error.', exc_info=True)
            return

    proxy.signals.signal('capacitance-updated').connect(_on_capacitance)
    yield asyncio.From(move_done.wait())
    raise asyncio.Return(messages)
Ejemplo n.º 25
0
    def _dynamic_states():
        # Merge received actuation states from requests with
        # explicit states stored by this plugin.
        requests = []

        responses = signals.signal('get-electrode-states-request').send()

        for receiver_i, co_callback_i in responses:
            request_i = yield asyncio.From(co_callback_i)
            if request_i is not None:
                requests.append(request_i)
                logger = _L()
                if logger.getEffectiveLevel() >= logging.DEBUG:
                    message = ('receiver: %s, actuation_request=%s' %
                               (receiver_i, request_i))
                    map(logger.debug, message.splitlines())

        if requests:
            combined_states = pd.concat([r[r > 0] for r in requests])
        else:
            combined_states = pd.Series()
        raise asyncio.Return(combined_states)
Ejemplo n.º 26
0
def write_without_response(self, controller_id, connection_handle,
                           attribute_handle, value, timeout):
    @asyncio.coroutine
    def on_ack_received(packet, future):
        self.logger.debug(
            "WriteWithoutResponse ack received with status={}".format(
                packet.status))
        self.remove_callback(packet.packet_uuid)

        if packet.status_code == StatusCode.Success:
            future.set_result(True)
        else:
            error = BaBLEException(
                packet,
                "Failed to send WriteWithoutResponse packet",
                connection_handle=connection_handle,
                attribute_handle=attribute_handle)
            future.set_exception(error)

    future = asyncio.Future()
    request_packet = Packet.build(WriteWithoutResponseCentral,
                                  controller_id=controller_id,
                                  connection_handle=connection_handle,
                                  attribute_handle=attribute_handle,
                                  value=bytes(value))

    self.register_callback(request_packet.packet_uuid,
                           callback=on_ack_received,
                           params={'future': future})

    self.send_packet(request_packet)

    try:
        result = yield From(asyncio.wait_for(future, timeout=timeout))
        self.logger.debug("Write without response command sent")
        raise asyncio.Return(result)
    except asyncio.TimeoutError:
        self.remove_callback(request_packet.packet_uuid)
        raise RuntimeError("WriteWithoutResponse timed out")
Ejemplo n.º 27
0
def _warning(signal, message, **kwargs):
    '''
    XXX Coroutine XXX

    Send warning signal and gather response from receivers.

    If no receivers are available or any receiver raises an exception, raise
    the specified warning message as a `RuntimeError`.

    Raises
    ------
    RuntimeError
        If no receivers are available or any receiver raises an exception.
    '''
    responses = signal.send(message, **kwargs)

    try:
        receivers, co_callbacks = zip(*responses)
        results = yield asyncio.From(asyncio.gather(*co_callbacks))
    except Exception:
        raise RuntimeError(message)
    else:
        raise asyncio.Return(zip(receivers, results))
Ejemplo n.º 28
0
    def on_version_mismatch(*args, **kwargs):
        _L().info('args=`%s`, kwargs=`%s`', args, kwargs)
        message = ('Driver version `%(driver_version)s` does not match '
                   'firmware `%(firmware_version)s` version.' % kwargs)
        while True:
            response = raw_input(message + ' [I]gnore/[u]pdate/[s]kip: ')
            if not response:
                # Default response is `ignore` and try to connect anyway.
                response = 'ignore'

            for action in ('ignore', 'update', 'skip'):
                if action.startswith(response.lower()):
                    response = action
                    break
            else:
                print('Invalid response: `%s`' % response)
                response = None

            if response is not None:
                break
        if response == 'skip':
            raise IOError(message)
        raise asyncio.Return(response)
Ejemplo n.º 29
0
def execute_step(plugin_kwargs):
    '''
    .. versionadded:: 2.32

    XXX Coroutine XXX

    Execute a single protocol step.

    Parameters
    ----------
    plugin_kwargs : dict
        Plugin keyword arguments, indexed by plugin name.

    Returns
    -------
    list
        Return values from plugin ``on_step_run()`` coroutines.
    '''
    # Take snapshot of arguments for current step.
    plugin_kwargs = copy.deepcopy(plugin_kwargs)

    signals = blinker.Namespace()

    @asyncio.coroutine
    def notify_signals_connected():
        yield asyncio.From(asyncio.sleep(0))
        signals.signal('signals-connected').send(None)

    loop = asyncio.get_event_loop()
    # Get list of coroutine futures by emitting `on_step_run()`.
    plugin_step_tasks = emit_signal("on_step_run",
                                    args=[plugin_kwargs, signals])
    future = asyncio.wait(plugin_step_tasks.values())

    loop.create_task(notify_signals_connected())
    result = yield asyncio.From(future)
    raise asyncio.Return(result)
Ejemplo n.º 30
0
    def get_quote_coroutine(self, symbols, dataframe):
        loop = trollius.get_event_loop()
        if isinstance(symbols, list) or isinstance(symbols, set) or isinstance(
                symbols, tuple):
            symbolList = list(symbols)
        elif isinstance(symbols, str):
            symbolList = symbols.split(',')
        symbols = util.symbols_to_string(symbols)
        url = URL_QUOTATION(symbols)

        retry = True
        while retry:
            try:
                async_req = loop.run_in_executor(
                    None,
                    functools.partial(self.session.get,
                                      URL_QUOTATION(symbols),
                                      timeout=0.1))
                quote = yield trollius.From(async_req)
                retry = False
            except:
                pass
        quote = quote.text
        quote = re.findall(r'\"(.*)\"', quote)

        for i in range(0, len(quote)):
            quote[i] = quote[i].split(',')

        if dataframe:
            quote = DataFrame(quote, columns=SINA_QUOTE_COLUMNS)
            quote["symbol"] = symbolList
            quote["time"] = datetime.strptime(
                quote.iloc[0]["date"] + " " + quote.iloc[0]["time"],
                '%Y-%m-%d %H:%M:%S')
        else:
            quote = [[x] + y for x, y in zip(symbolList, quote)]
        raise trollius.Return(quote)