树莓派Zero W接PIR传感器使用Telethon发Telegram消息报错求解
错误原因
RPi.GPIO的事件回调是同步调用机制,不支持直接传入async异步协程函数,回调被触发时不会自动await你的异步函数,所以会抛出协程未被等待的运行时警告,同时你原代码没有启动Telegram客户端,就算回调正常也无法完成消息发送。
修复方案
用异步事件循环调度GPIO回调触发的发消息任务,完整修复后代码如下:
import RPi.GPIO as GPIO import asyncio from telethon import TelegramClient SENSOR_PIN = 17 GPIO.setmode(GPIO.BCM) GPIO.setup(SENSOR_PIN, GPIO.IN) # Telegram settings api_id='xxxxx' api_hash='xxxxx' phone='xxxx' # Kamera Gruppe chatid = -xxxxx client = TelegramClient(phone, api_id, api_hash) # 获取全局异步事件循环 loop = asyncio.get_event_loop() # 独立的异步发消息函数 async def send_alert(): print('motion detected!') await client.send_message(chatid, 'motion detected') # GPIO用同步回调,把异步任务提交给事件循环执行 def mein_callback(channel): loop.create_task(send_alert()) async def main(): # 启动Telegram客户端,完成登录校验 await client.start() GPIO.add_event_detect(SENSOR_PIN , GPIO.RISING, callback=mein_callback) # 用异步 sleep 替代同步time.sleep,避免阻塞事件循环 while True: await asyncio.sleep(100) if __name__ == "__main__": try: loop.run_until_complete(main()) except KeyboardInterrupt: print ("Beende...") finally: GPIO.cleanup() # 退出时断开Telegram连接 loop.run_until_complete(client.disconnect())
核心修改说明
- 引入
asyncio管理异步事件循环,所有Telethon的异步操作都依赖事件循环调度 - 拆分异步逻辑:GPIO触发时调用同步回调,同步回调只负责把发消息任务提交给事件队列,规避协程未被等待的问题
- 新增Telegram客户端显式启动逻辑,完成账号登录校验
- 替换同步阻塞的
time.sleep为异步asyncio.sleep,避免阻塞异步任务执行 - 新增退出时的Telegram连接断开逻辑,避免连接残留
内容的提问来源于stack exchange,提问作者cr0co
相关产品推荐
相关产品推荐

