0

i try to send the image from a usb webcam to a telegram group if motion is detected. the motion works, but i cant get it to send it to my group. so im working on to send a text instead. (with the picture i can figure out, but first i need to get the text working)

code:

import RPi.GPIO as GPIO
import time
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)


async def mein_callback(channel):
    print('motion detected!')
    await client.send_message(chatid, 'motion detected')
    
try:
    GPIO.add_event_detect(SENSOR_PIN , GPIO.RISING, callback=mein_callback)
    while True:
        time.sleep(100)
except KeyboardInterrupt:
    print ("Beende...")
GPIO.cleanup() 

error:

sys:1: RuntimeWarning: coroutine 'mein_callback' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback

cr0co
  • 33
  • 3

1 Answers1

0

I don't know how the RPi library works, but I know Telethon is an async library, and from the looks of it, RPi is not.

You cannot use time.sleep() because that will block the entire asyncio event loop. You would need something like await asyncio.sleep(). It also seems you are never running client.start(), so the client won't be connected, so client.send_message would fail. I recommend you read through the asyncio documentation to understand this better. That said... the following should work, assuming RPi is not threaded:

import RPi.GPIO as GPIO
import asyncio
from telethon import TelegramClient
 
...

client = TelegramClient(phone, api_id, api_hash)

async def mein_callback(channel):
    print('motion detected!')
    await client.send_message(chatid, 'motion detected')

def schedule_mein_callback(channel):
    client.loop.create_task(mein_callback(channel))  # <- create a new task that will run in the future

async def main():
    async with client:  # <- start the client so `send_message` works
        GPIO.add_event_detect(SENSOR_PIN , GPIO.RISING, callback=schedule_mein_callback)  # <- not an async callback, GPIO can run it fine
        while True:
            await asyncio.sleep(100)  # <- no longer blocks, telethon can run fine

try:
    client.loop.run_until_complete(main())  # <- enter async-land
except KeyboardInterrupt:  # <- should generally be used before entering `async`
    print ("Beende...")
GPIO.cleanup() 
Lonami
  • 5,945
  • 2
  • 20
  • 38
  • i get another error now: ` client.loop.create_task(mein_callback(channel)) # <- create a new task that will run in the future File "/home/pi/.local/lib/python3.7/site-packages/telethon/client/telegrambaseclient.py", line 460, in loop return asyncio.get_event_loop() File "/usr/lib/python3.7/asyncio/events.py", line 644, in get_event_loop % threading.current_thread().name) RuntimeError: There is no current event loop in thread 'Dummy-1'. ` – cr0co Aug 19 '21 at 11:30
  • That means RPi is using threads and calling your callback from one of them. You will need to wrap the create task call in `call_soon_threadsafe`; see https://stackoverflow.com/q/57314061/4759433 – Lonami Aug 19 '21 at 20:27
  • oh ok im new to python, need to read that. – cr0co Aug 20 '21 at 18:54