GPIO 边缘检测 - >通知 Web 客户端



所以我相信我问题的症结在于python GPIO事件检测是线程化的,Socket.IO Emit 的东西也是如此。我正在尝试在 GPIO 事件检测触发时调用 Emit。而且我收到不等待socket.io.emit的错误,当我尝试在它前面抛出一个等待时,我的语法很糟糕。

无论如何,我只是尝试在IO上发生中断时将消息发送到Web客户端。例如,发生 LED 闪烁,我想将其发送给客户端。使用 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)

在正常情况下,我可以以线程方式从 Web 服务器发出,如下所示:

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)

这工作正常,但是一旦我尝试从gpio回调(另一个线程)执行sio.emit,我就会遇到不等待sio.emit的问题。我试过定义我的def my_callback_one(通道)asyc,但这没有帮助。(异步定义my_callback_one(通道))

我知道这是一个线程问题,但我只是不确定该去哪里。

尝试在函数之前放置一个"@sio.event",告诉sanic这是一个套接字事件(async和await也很好)。下面是一个示例:

https://github.com/miguelgrinberg/python-socketio/blob/master/examples/server/sanic/app.py

最新更新