You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:54:03