En este tutorial vamos a convertir cualquier Raspberry Pi con una webcam USB estándar en un sistema de videovigilancia profesional con detección de personas por Inteligencia Artificial y avisos instantáneos con foto en Telegram.
A diferencia de los sistemas tradicionales como MotionEye (que saltan por cualquier cambio de luz o movimiento de hojas), este montaje utiliza Frigate NVR para analizar la imagen mediante redes neuronales en tiempo real, garantizando cero falsas alarmas.
🛠️ Requisitos previos
- Raspberry Pi (Recomendado Raspberry Pi 4 de 4GB/8GB o Raspberry Pi 5).
- Sistema Operativo: Raspberry Pi OS / Debian 64 bits con Docker y Docker Compose instalados.
- Cámara: Cualquier webcam USB estándar compatible con la norma UVC (Logitech, Trust, modelos genéricos sin marca, etc.).
- Una cuenta de Telegram.
📸 Paso 1: Identificar la webcam USB en Linux
Conecta tu webcam a cualquier puerto USB de la Raspberry Pi. En Linux, las cámaras USB crean varios nodos de vídeo. Para comprobarlos, ejecuta:
ls -l /dev/video*
Normalmente verás /dev/video0 y /dev/video1. El nodo principal de captura de vídeo suele ser /dev/video0.
Para consultar las resoluciones y formatos nativos compatibles con tu cámara:
v4l2-ctl --list-formats-ext
📁 Paso 2: Crear la estructura de carpetas y Mosquitto
Crearemos una carpeta organizada para alojar todos los ficheros de configuración del proyecto:
mkdir -p ~/camara-ia/mosquitto/config ~/camara-ia/mosquitto/data ~/camara-ia/mosquitto/log ~/camara-ia/frigate/config ~/camara-ia/notifier
cd ~/camara-ia
Configurar el Broker MQTT (Mosquitto)
Frigate utiliza MQTT para comunicar los eventos de detección en tiempo real. Creamos el archivo de configuración para Mosquitto:
echo -e "listener 1883\nallow_anonymous true" | sudo tee ./mosquitto/config/mosquitto.conf
🤖 Paso 3: Configurar Frigate NVR (config.yml)
Crea el archivo ~/camara-ia/frigate/config/config.yml y pega la configuración base adaptada a webcams USB genéricas:
# 1. Configuración de conexión MQTT
mqtt:
enabled: true
host: mosquitto
port: 1883
# 2. Motor de inferencia por CPU
detectors:
cpu1:
type: cpu
# 3. Configuración de la Cámara USB
cameras:
webcam_usb:
enabled: true
ffmpeg:
inputs:
- path: /dev/video0
roles:
- detect
- record
input_args:
- -f
- v4l2
- -input_format
- mjpeg # Cambiar a yuyv422 si tu webcam no admite mjpeg
- -video_size
- 1280x720 # Resolución recomendada para rendimiento óptimo
- -framerate
- "15"
detect:
enabled: true
width: 1280
height: 720
fps: 5 # 5 FPS es el estándar perfecto para detección por IA
objects:
track:
- person # Objeto a rastrear
# 4. Grabación y retención de eventos
record:
enabled: true
retain:
days: 3
events:
retain:
default: 7
📲 Paso 4: Configurar el Bot Notificador de Telegram
Para recibir la foto de la persona detectada en el móvil al instante, crearemos un servicio ligero en Python.
1. Obtener las credenciales de Telegram
- Abre Telegram, busca al usuario
@BotFathery envía el comando/newbot. Sigue los pasos y guarda el API TOKEN generado. - Abre el chat de tu nuevo bot y pulsa Iniciar.
- Busca al bot
@userinfobot, envíale cualquier mensaje y anota el número que aparece enId:.
2. Crear el script de Python (script.py)
Crea el archivo ~/camara-ia/notifier/script.py:
import json
import os
import time
import requests
import paho.mqtt.client as mqtt
MQTT_HOST = os.getenv("MQTT_HOST", "mosquitto")
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
FRIGATE_URL = os.getenv("FRIGATE_URL", "http://frigate:5000")
def on_connect(client, userdata, flags, rc, properties=None):
if rc == 0:
print("[NOTIFIER] -> Conectado con éxito al Broker MQTT.")
client.subscribe("frigate/events")
print("[NOTIFIER] -> Suscrito al canal 'frigate/events'. Esperando detecciones...")
else:
print(f"[NOTIFIER] -> Error de conexión a MQTT. Código: {rc}")
def on_message(client, userdata, msg):
try:
payload = json.loads(msg.payload.decode())
event_type = payload.get("type")
# 'new' avisa al entrar en escena, 'end' cuando finaliza el evento
if event_type in ["new", "end"]:
after = payload.get("after", {})
label = after.get("label", "")
camera = after.get("camera", "")
event_id = after.get("id", "")
if label == "person":
print(f"[NOTIFIER] -> ¡Persona detectada ({event_type})! Enviando alerta...")
snapshot_url = f"{FRIGATE_URL}/api/events/{event_id}/snapshot.jpg"
caption = f"⚠️ Detección: {label.upper()}\nCámara: {camera}"
# Descargar snapshot de Frigate y enviar por Telegram
res = requests.get(snapshot_url, timeout=5)
if res.status_code == 200:
tg_res = requests.post(
f"https://api.telegram.org/bot{TOKEN}/sendPhoto",
data={"chat_id": CHAT_ID, "caption": caption},
files={"photo": ("snapshot.jpg", res.content)},
timeout=10
)
if tg_res.status_code == 200:
print("[NOTIFIER] -> Foto enviada correctamente a Telegram.")
else:
print(f"[NOTIFIER] -> Error Telegram API: {tg_res.text}")
else:
print(f"[NOTIFIER] -> No se pudo obtener snapshot (Status {res.status_code})")
except Exception as e:
print("[NOTIFIER] -> Error procesando evento:", e)
# Compatibilidad con Paho MQTT v2
try:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
except AttributeError:
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
print(f"[NOTIFIER] -> Conectando a {MQTT_HOST}:1883...")
# Bucle de reintento automático
connected = False
while not connected:
try:
client.connect(MQTT_HOST, 1883, 60)
connected = True
except Exception as err:
print(f"[NOTIFIER] -> Esperando a Mosquitto... ({err})")
time.sleep(3)
client.loop_forever()
3. Crear el Dockerfile del notificador
Crea el archivo ~/camara-ia/notifier/Dockerfile:
FROM python:3.11-slim
RUN pip install paho-mqtt requests
COPY script.py /script.py
CMD ["python", "-u", "/script.py"]
🚀 Paso 5: Despliegue con Docker Compose
Crea el archivo ~/camara-ia/docker-compose.yml para orquestar todos los servicios:
services:
# Servidor MQTT
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:latest
restart: unless-stopped
ports:
– «1883:1883»
volumes:
– ./mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf
– ./mosquitto/data:/mosquitto/data
– ./mosquitto/log:/mosquitto/log
# Frigate NVR
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: «256mb»
devices:
– /dev/video0:/dev/video0
– /dev/video1:/dev/video1
volumes:
– /etc/localtime:/etc/localtime:ro
– ./frigate/config:/config
– /media/frigate:/media/frigate
– type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
– «8971:8971» # Panel Web con contraseña
– «127.0.0.1:5000:5000» # Acceso interno sin contraseña
– «8554:8554» # Streams RTSP
– «8555:8555/tcp»
– «8555:8555/udp»
environment:
FRIGATE_RTSP_PASSWORD: «CambiaEstaPasswordSegura»
depends_on:
– mosquitto
# Notificador de Telegram
frigate-notifier:
container_name: frigate-notifier
build: ./notifier
restart: unless-stopped
environment:
– MQTT_HOST=mosquitto
– FRIGATE_URL=http://frigate:5000
– TELEGRAM_BOT_TOKEN=TU_TOKEN_AQUI # <– Pega tu Token
– TELEGRAM_CHAT_ID=TU_CHAT_ID_AQUI # <– Pega tu Chat ID
depends_on:
– frigate
– mosquitto
🚦 Paso 6: Puesta en marcha y verificación
- Arranca todos los contenedores y compila el notificador localmente:Bash
docker compose up -d --build - Comprueba los registros del bot de Telegram para verificar que está esperando eventos:Bash
docker logs -f frigate-notifier(Debes ver[NOTIFIER] -> Conectado con éxito al Broker MQTT). - Accede al panel web seguro de Frigate desde tu navegador:
https://IP_DE_TU_RASPBERRY_PI:8971(La primera vez te pedirá definir usuario y contraseña de administrador).
¡Listo! Pasa por delante de tu webcam y en 2-3 segundos recibirás un aviso en Telegram con la imagen de la persona detectada.

Deja una respuesta