tutorial python

Cámara de seguridad con bot de telegram – parte 2

Para nuestro tutoriales vamos a hacer un ejemplo muy sencillo: hacer una cámara de seguridad que envía foto a nuestro chat de telegram.

Para saber cómo crear un bot o cómo entender la api de telegram recomiendo leer el post anterior.

Preparación en nuestra raspberry pi

Vamos a instalar en nuestra raspberry lo siguiente:

nos conectamos al terminal de nuestra raspberry de la siguiente manera ssh pi@192.168.100.63 <— esta ip varia dependiendo tu red

Colocamos nuestra contraseña y creamos una carpeta:
mkdir Documents/camtelegram

nos posicionamos en la carpeta, ahora vamos a instalar unas cosas que necesitaremos:

pip install requests
sudo apt install fswebcam
sudo apt install ffmpeg

Conociendo nuestra raspberry pi

vamos a tener en mente esta imagen, que lo pueden encontrar googleando pin raspberry pi 3

Qué es GPIO? - Control de GPIO con Python en Raspberry Pi
raspberry pi para cámara de seguridad

vamos a guiarnos de los que dicen gpio y vamos a colocar un sensor ultrasónico como este

HC-SR04

Vamos a colocar de la siguiente manera pin39 es gnd, pin2 es salida de corriente 5v, gpio 25 entrada , gpio 7 spi (serial)

conexión con ultrasónico

En resumen, el ultrasonido envía un sonido desde un cono y espera una respuesta, apartir del tiempo podemos calcular la distancia.

Trigger envía el sonido y echo recibe el sonido

Escribiendo Código en python

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)   
GPIO_TRIGGER = 25
GPIO_ECHO = 7
stop = 0
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
GPIO.setup(GPIO_ECHO,GPIO.IN)
GPIO.output(GPIO_TRIGGER,False)    #Ponemos el pin 25 como LOW

GPIO.output(GPIO_TRIGGER,True)
        time.sleep(0.00001) 
        GPIO.output(GPIO_TRIGGER,False)
        start = time.time()
        while GPIO.input(GPIO_ECHO)==0:
            start = time.time()
        while GPIO.input(GPIO_ECHO)==1:
            stop = time.time()
        elapsed = stop-start
        distance = (elapsed * 34300)/2
        print (str(distance)+ ' - ' + str(time.strftime('%H:%M:%S')))

con este código mandamos una señal y lo recibimos y así podemos calcular la distancia con una fórmula matemática muy simple.

Verificar si hay internet

import time
import urllib.request as request
import os, ssl

if (not os.environ.get('PYTHONHTTPSVERIFY', '') and
   getattr(ssl, '_create_unverified_context', None)): 
   ssl._create_default_https_context = ssl._create_unverified_context

class InternetOk():
    def Internet(self):
        siInternet = False
        while not siInternet:    
            try :
                web = "https://www.python.org/"
                data = request.urlopen(web)
                siInternet = True
                break
            except:
                siInternet = False
                time.sleep(30)
        return  siInternet
inter = InternetOk()
print (inter.Internet())

Con este código lo que hacemos es checar si tenemos internet, si no hay internet el código se clicla la llamada hasta que tengamos un ok.

Funciones para enviar a telegram (explicación)

def mensaje(texto):
    smsn = "https://api.telegram.org/bot"+botkey+"/sendMessage?chat_id="+ str(chat_id) + "&text=" + texto
    requests.post(smsn)

def video(name):
    mensaje('enviando video: '+ name)
    files = {'video': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendVideo?chat_id="+ str(chat_id)
    response = requests.post(tlgurl, files= files)
    bnd = 0

def foto(name):
    files = {'photo': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendPhoto?chat_id="+ str(chat_id)
    mensaje("Enviando Foto " + name)
    requests.post(tlgurl, files= files)

Como explicamos en nuestro post anterior, lo que necesitamos es consumir la api rest asi que lo que hacemos es enviar por parámetros en el caso del chat

tlgurl = «https://api.telegram.org/bot»+botkey+»/sendVideo?chat_id=»+ str(chat_id)
recordar porque pasa esto

lo que hacemos en el caso de foto y video, es usar un multipart enviando un archivo

files = {‘video’: open(name,’rb’)} –> multipart para videos en telegram
files = {‘photo’: open(name,’rb’)} –> multipart para fotos en telegram

si tomamos fotos hacemos la llamada a nuestra librería fswebcam usando subprocess.

subprocess es una libreria de python3 para hacer llamadas al sistema como si fuera una terminal (shell)

subprocess.call(‘fswebcam –no-banner movrecamara.jpg’, shell=True)

para grabar videos hacemos casi lo mismo pero usando nuestra librería de ffmpeg

subprocess.call(‘ffmpeg -t 15 -f v4l2 -framerate 25 -video_size 640×480 -i /dev/video0 movrecamara1.mp4’, shell=True)

Código completo para enviar foto en telegram

Si no tenemos sensor

Si no tenemos un sensor y queremos probar podemos enviar foto y video cada X tiempo

import RPi.GPIO as GPIO
import time
import requests
import subprocess
from internetok import InternetOk

botkey = "botkey"
chat_id = chatid
bnd = 0
nega = 0


inter = InternetOk()

def mensaje(texto):
    smsn = "https://api.telegram.org/bot"+botkey+"/sendMessage?chat_id="+ str(chat_id) + "&text=" + texto
    requests.post(smsn)

def video(name):
    mensaje('enviando video: '+ name)
    files = {'video': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendVideo?chat_id="+ str(chat_id)
    response = requests.post(tlgurl, files= files)
    bnd = 0

def foto(name):
    files = {'photo': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendPhoto?chat_id="+ str(chat_id)
    mensaje("Enviando Foto " + name)
    requests.post(tlgurl, files= files)

try:
    mensaje("acabo de despertar vamos a encender el ultrasonido del cuarto")
    while True:
        time.sleep(2)
        inter.Internet()
        mensaje("tomando foto")
        subprocess.call('fswebcam --no-banner movrecamara.jpg', shell=True)
        foto('movrecamara.jpg')
        time.sleep(30)
    
        mensaje("se sigue detectando movimiento en cuarto vamos a grabar")
        subprocess.call('rm -f movrecamara1.mp4', shell=True)
        subprocess.call('ffmpeg -t 15 -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 movrecamara1.mp4', shell=True)
        video('movrecamara1.mp4')
        time.sleep(120)

except:                #Si el usuario pulsa CONTROL+C... KeyboardInterrupt
    mensaje("Se detuvo la aplicacion de la recamara")                         #Avisamos del cierre al usuario
    GPIO.cleanup()
    bnd = 0
    subprocess.call("python3 /home/pi/Documents/ultras.py &",shell=True)

Si tenemos un sensor

import RPi.GPIO as GPIO
import time
import requests
import subprocess
from internetok import InternetOk

botkey = "botapi"
chat_id = usertelegram
bnd = 0
nega = 0

GPIO.setmode(GPIO.BCM)   
GPIO_TRIGGER = 25
GPIO_ECHO = 7
stop = 0
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
GPIO.setup(GPIO_ECHO,GPIO.IN)
GPIO.output(GPIO_TRIGGER,False)    #Ponemos el pin 25 como LOW
inter = InternetOk()

def mensaje(texto):
    smsn = "https://api.telegram.org/bot"+botkey+"/sendMessage?chat_id="+ str(chat_id) + "&text=" + texto
    requests.post(smsn)

def video(name):
    mensaje('enviando video: '+ name)
    files = {'video': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendVideo?chat_id="+ str(chat_id)
    response = requests.post(tlgurl, files= files)
    bnd = 0

def foto(name):
    files = {'photo': open(name,'rb')}
    tlgurl = "https://api.telegram.org/bot"+botkey+"/sendPhoto?chat_id="+ str(chat_id)
    mensaje("Enviando Foto " + name)
    requests.post(tlgurl, files= files)

try:
    mensaje("acabo de despertar vamos a encender el ultrasonido del cuarto")
    while True:
        time.sleep(2)
        inter.Internet()
        GPIO.output(GPIO_TRIGGER,True)
        time.sleep(0.00001) 
        GPIO.output(GPIO_TRIGGER,False)
        start = time.time()
        while GPIO.input(GPIO_ECHO)==0:
            start = time.time()
        while GPIO.input(GPIO_ECHO)==1:
            stop = time.time()
        elapsed = stop-start
        distance = (elapsed * 34300)/2
        print (str(distance)+ ' - ' + str(time.strftime('%H:%M:%S')))
        if distance < 0:
            if nega == 0 or nega > 60:
                mensaje("negativo "+str(distance))
                
                if nega > 61:
                    nega = 0
            nega += 1

        if distance > 30 and distance < 80:
            if bnd < 3:
                mensaje("Se detecto movimiento en cuarto")
                subprocess.call('fswebcam --no-banner movrecamara.jpg', shell=True) #tomamos fotos en segundo plano
                foto('movrecamara.jpg')
                bnd += 1
                time.sleep(1)
            else:
                bnd = 0
                mensaje("se sigue detectando movimiento en cuarto vamos a grabar")
                subprocess.call('rm -f movrecamara1.mp4', shell=True) #borramos info en segundo plano
                subprocess.call('ffmpeg -t 15 -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 movrecamara1.mp4', shell=True)
                video('movrecamara1.mp4')
except:                #Si el usuario pulsa CONTROL+C... KeyboardInterrupt
    mensaje("Se detuvo la aplicacion de la recamara")                         #Avisamos del cierre al usuario
    GPIO.cleanup()
    bnd = 0
    subprocess.call("python3 /home/pi/Documents/ultras.py &",shell=True)

Con esto podemos enviar por telegram fotos :

con esto podemos entender un poco más como funciona los bot en telegram y vamos a comenzar a hacer algo más complicado como un chat interactivo.

Un comentario

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.