Asyncio ожидает изменения состояния без события

#python #python-asyncio

#python #python-asyncio

Вопрос:

У меня есть программа для одновременного чтения данных с нескольких устройств Bluetooth. Мне нужно дождаться 200 пакетов от каждого датчика. Первоначально я тестировал только с одним устройством, в течение этого времени я использовал asyncio.event для ожидания 200 пакетов, а затем продолжил.

 async with BleakClient(sensor_address, loop = loop, timeout = timeout) as bluetooth:
    x = await bluetooth.is_connected()
    logging.info(f'connected: {x}')

    await bluetooth.start_notify(self.SENSOR_CHARACTERISTIC_UUID, self._notification_handler)
    await event.wait()
    await bluetooth.stop_notify(self.SENSOR_CHARACTERISTIC_UUID)
  

и в моей функции _notification_handler:

 def _notification_handler(self, event, sender, data: bin):
    if self.packets_received < self.num_packets:
        self.packets_received  = 1
        self.decode_data(data)
    else:
        event.set()
  

однако, поскольку я сейчас использую несколько датчиков, я не могу дождаться установки события, поскольку это приведет к прекращению сбора данных всеми датчиками, если первый завершится независимо от состояния других.

Я думал о том, чтобы просто создать цикл под start_notify для ожидания всех пакетов и просто спать пару секунд, прежде чем проверять снова, но мне это кажется очень неуклюжим.

 await client.start_notify(SENSOR_CHARACTERISTIC_UUID, notification_handler)

while packets_received < self.num_packets:
    await asyncio.sleep(10.0)    

await client.stop_notify(SENSOR_CHARACTERISTIC_UUID)
  

Есть ли лучший способ приблизиться к этому? (Функция notification_handler была изменена с учетом приведенных выше изменений).

Комментарии:

1. Я не понимаю, почему вы больше не можете ждать события. Как ожидание события «вызовет прекращение сбора данных всеми датчиками»? Не произойдет ли то же самое в цикле ожидания на основе ожидания?

2. Нет, я создаю одну задачу для каждого датчика, но я считаю, что событие привязано к циклу, и задачи используют один и тот же цикл событий. режим ожидания не повлияет на все задачи, только на ту, из которой он вызывается.

3. Разве у вас не может быть одного события на датчик?

4. возможно ли это с учетом текущего кода? Как бы я назначил одно событие для каждого датчика?

5. Я не знаком с деталями библиотеки и кода, но я ожидаю, что вы можете создать asyncio.Event() для каждого датчика и передать его в качестве аргумента сопрограмме, которая имеет дело с датчиком. Глядя на ваш код, что-то вроде await bluetooth.start_notify(<id>, lambda ...: self._notification_handler(..., event)) .