Обнаружение границ GPIO -> уведомление веб-клиента - PullRequest
0 голосов
/ 23 октября 2019

Так что я считаю, что суть моей проблемы заключается в том, что обнаружение событий Python GPIO является многопоточным, как и в Socket.IO Emit. Я пытаюсь вызвать Emit, когда срабатывает обнаружение событий GPIO. И я получаю сообщения об ошибках, не ожидая socket.io.emit, когда я пытаюсь бросить await перед ним, я получаю неверный синтаксис. веб-клиент, когда прерывание происходит на IO. Например, мигает светодиод, я хочу отправить это клиенту. Использование socket.io передает сообщение клиентской части, а GPIO прерывает через обнаружение событий, выполняет другую часть (без привязки к приложению). Мне просто нужно отправить эти обнаружения событий из GPIO в socket.io, который излучает каким-то образом.

Также я использую веб-сервер Sanic.

В любом случае вот код:


sio = socketio.AsyncServer(async_mode='sanic')

app = Sanic()
sio.attach(app)

GPIO.setmode(GPIO.BOARD)

GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)


#this gets called when the gpio.add_event_detect event is hit upon the gpio pin #going high (led lighting up). This works fine except sio.emit needs to be #awaited, but if I throw an await in front of it I get bad syntax, I put async #in front of the function def and then I get errors saying I never awaited the #function my_callback_one when it gets called from the GPIO.add_event_detect #event firing. I'm not sure what to do or if this is possible.

def my_callback_one(channel):
    sio.emit('my_response', {'data': 'test'})
    print('========button press LED lighting detected========')

GPIO.add_event_detect(18, GPIO.RISING, callback=my_callback_one)


#Starts the web application
if __name__ == "__main__":

    app.run(host='0.0.0.0', port= 8090, workers=4)


В нормальных условиях я мог бы делать потоки с веб-сервера в многопоточном режиме, например, так:

async def background_task():

     count = 0
     while count < 10:
         await sio.sleep(.05)
         print("message sent to client")
         count += 1
         await sio.emit('my_response', {'data': count})
    pass

@app.listener('before_server_start')
def before_server_start(sanic, loop):
    sio.start_background_task(background_task)

Это прекрасно работает, но как только я пытаюсь сделать это sio.emit из обратного вызова gpio (другой поток), у меня возникают проблемы с ожиданием sio.emit. Я попытался сделать мой asyc def my_callback_one (channel) определенным, но это не помогло. (async def my_callback_one (channel))

Я знаю, что это проблема с многопоточностью, но я просто не уверен, что с ней делать.

...