Fon Simó

Videovigilancia en Raspberry Pi

En este artículo comparto cómo he montado un sistema de videovigilancia en Raspberry Pi, utilizando motion, Insync y algunos script. Además del sistema que monté en software, también monté una cajita con un switch (para activar y desactivar la videovigilancia) y una serie de LEDs para ver el estado del sistema, aunque eso lo publicaré en otro artículo. 🙂

Adrian van Leen for openphoto.net

Sistema de videovigilancia en Raspberry

¿Qué buscaba cuando me decidí a montar mi sistema de videovigilancia? Para que fuera útil y funcional tenía que:

¿Qué necesitas?

Empezamos

Primero, necesitamos el paquete motion, el encargado de detectar movimiento y grabar lo que detecta. Motion ya viene con Raspbian, así que sólo nos hará falta instalar motion con apt-get. Además, necesitamos el paquete mpack, que será el encargado de enviarnos por correo electrónico las imágenes
sudo apt-get install motion mpack

Desactivar modo daemon

Me interesa arrancar y detener motion cuando me voy de casa y que utilice los ficheros y carpetas del usuario pi, con permisos de usuario y no de sistema. Para ello desactivamos el modo daemon (siempre detectando movimiento), editando /etc/motion/motion.conf y poner la opción daemon en off

/etc/motion/motion.conf
############################################################
# Daemon
############################################################

# Start in daemon (background) mode and release terminal (default: off)
daemon off

Lo segundo es crear un directorio donde pondremos todos los scripts para ejecutar la detección de movimiento. En mi sistema, he creado todos los scripts en /home/pi/motion.

Modificando motion.conf

Esta es la parte más importante del sistema de videovigilancia en Raspberry Pi. Lograr que motion esté correctamente configurado, se conecte a la cámara, detecte movimiento, y además que ejecute los comandos adecuados.

El fichero motion.conf es el fichero de configuración de motion, y es donde se configuran las cámaras y los script necesarios cuando hay movimiento.

Primero hemos de copiar el fichero general de motion (/etc/motion/motion.conf) a nuestro directorio de usuario.
sudo cp /etc/motion/motion.conf ~/motion
sudo chown pi ~/motion/motion.conf

Definiendo la fuente de las imágenes.

Dependiendo si conectas el módulo de cámara de Raspberry, una cámara USB o, como en mi caso, una cámara IP, tienes que decirle a motion cómo tiene que conectarse a la cámara, de dónde sacar las imágenes para el sistema de videovigilancia en Raspberry.

En el caso de usar el módulo de cámara de la Raspberry, tienes que primero asegurarte que se activa el módulo
sudo modprobe bcm2835-v4l2
Y el fichero motion.con ya debería funcionar con la línea (que viene activada por defecto):
videodevice /dev/video0
En mi caso, que he utilizado una cámara IP (una TP-LINK TL-SC2020N, que ya está descatalogada , ahora estoy usando esta otra: D-Link DCS-932L) se define el origen del vídeo usando los comandos netcam. Hay dos maneras de utilizarlo, usando el protocolo rstp o el protocolo http.

Para usar rstp (en este ejemplo, la cámara usa la IP 192.168.2.130 y el puerto 554, y según el manual del fabricante, con esta URL se accede al feed de la cámara):
netcam_url rtsp://usuario:contraseña@192.168.2.130:554/video.mjpg
Y el protocolo http, el que se usa con la TP-LINK NC220, es el siguiente (misma IP del ejemplo anterior)
netcam_url http://192.168.2.130/video.mjpg?mute
netcam_userpass usuario:contraseña

Para la D-Link DCS-932L, utilizo esta configuración:

netcam_url http://usuario:contraseña@192.168.2.130/video.cgi?resolution=VGA
netcam_keepalive on

Ejemplos de ficheros motion.conf

Las líneas que yo modifiqué en mi caso, y las que son más relevantes son las siguientes (el fichero completo motion.con que yo utilizo, lo puedes descargar aquí)

Actualización: actualizo el fichero para Raspbian Jessie. Algunos parámetros cambian de Wheezy. En las líneas que cambian lo aclaro.
# Queremos que motion se ejecute en segundo plano, que libere el terminal

# o script que lo ejecuta daemon on
# La definición de nuestra cámara
width 640
height 480

# El feed de la cámara IP

netcam_url http://192.168.2.130/video.mjpg?mute
netcam_userpass usuario:contraseña

# El threshold son la cantidad de píxeles que tienen que cambiar en una imagen para que
# motion lo detecte como movimiento. Yo tuve que ir ajustando este valor para evitar falsos
# positivos y que detecte movimiento real cuando lo hay.
threshold 7500

# Ignorar cambios bruscos de luz. Estos cambios, en mi caso, me disparaban muchas falsas alarmas
lightswitch 95

# El numero mínimo de frames que han de cambiar para considerarse movimiento. Por defecto es 1,
# recibía muchos emails con sólo dos imágenes (falsas alarmas)
minimum_motion_frames 5

# El gap es la cantidad de segundos que han de pasar (sin movimiento) para que acabe un evento.
# Un evento es una serie de imágenes (y un vídeo) en un corto período de tiempo, esto es, si no
# hay más movimiento en los próximos 3 minutos (180 segundos), cerramos el vídeo y finaliza el
# evento que disparó la alarma. Si ponemos este valor en 0, motion empezará a grabar el vídeo
# cuando detecte movimiento y no se detendrá más, haya o no haya más movimiento

# En Wheezy es gap
event_gap 180

# La calidad de los JPG que se grabarán
quality 100

# Quiero grabar los vídeos usando mpeg4

# Era ffmpeg_cap_new en Wheezy
ffmpeg_output_movies on
ffmpeg_video_codec mpeg4

# Nombres de ficheros

# ¿Dónde se guardan las imágenes y los vídeos?
# Se guardan en el directorio donde tengo configurado InSync, para sincronizarlo con Google
# Drive
target_dir /home/pi/USUARIO@GMAIL.COM/VideoVigilancia

# Esta configuración creará un directorio por día, y dentro los ficheros de movimiento separados
# por evento (%v) y hora. Por ejemplo 20151231/cam1-01-235005-00.jpg
# En Wheezy era jpeg_filename picture_filename %Y%m%d/cam1-%v-%H%M%S-%q
# Se mantiene en Jessie
movie_filename %Y%m%d/cam1-%v-%H%M%S

############################################################
# Live Webcam Server
############################################################

# Si quieres ver lo que motion está monitorizando, puedes activar el puerto 8081
# y luego acceder via http://ip_de_la_rpi:8081/
#En Wheezy era webcam_port stream_port 8081

# Por defecto sólo puedes acceder al feed de vídeo actual desde localhost, si quieres monitorizarlo
# desde otro sitio, se ha de poner en off (yo lo tengo en off, y accedo vía VPN)

# En Wheezy era webcam_localhost
stream_localhost off

############################################################
# HTTP Based Control
############################################################

# Si quieres controlar motion (cambiar la configuración, empezar o detener un evento, etc)
# puedes acceder a http://ip_de_la_rpi:8080/ y controlar motion
# En Jessie todos los comandos se cambian de control_ a webcontrol_ (Jessie)

webcontrol_port 8080
webcontrol_localhost off

# Usuario y contraseña para controlar motion a distancia
webcontrol_authentication usuario:contraseña

# Qué script ejecutar cuando hay movimiento?
on_event_start ~/motion/haymovimiento %Y%m%d %H:%M

# ¿Qué script ejecutar cuando acaba el movimiento?
on_event_end ~/motion/sincro

# Para un sistema real de videovigilancia en Raspberry podemos tener más cámaras
# Si tenemos más de una cámara, hay que crear estos ficheros, con la configuración específica
# para cada una de las cámaras. Si tienes 3 cámaras, tendrás 2 ficheros thread y el motion.con

thread /home/pi/motion/camara1.conf
thread /home/pi/motion/camara2.conf
thread /home/pi/motion/camara3.conf
thread /home/pi/motion/camara4.conf
Una vez configurado motion, pasamos a crear o modificar los scripts centrales del sistema.

Pantallazo de la web de administración de motion

Scripts para arrancar y detener motion

Creé dos scripts para activar y desactivar la videovigilancia en Raspberry: mevoy y yatoy 🙂

mevoy (activar videovigilancia)

La idea de este script es encender el LED rojo (indicando que la videovigilancia está activada), esperar 5 minutos (a que salgamos de casa), crear un fichero a modo de flag (para saber que motion se está ejecutando) y ejecutar motion con el fichero que hemos modificado antes

Esta es mi versión actual:
#!/bin/sh
#Arranca Videovigilancia en Raspberry Pi
#PIN 27: LED rojo
#PIN 17: LED verde
#PIN 22: LED rojo cristal
#PIN 23: LED verde-testigo-always on

#Encendemos LED roja y apagamos LED verde
echo 1 > /sys/class/gpio/gpio27/value
echo 0 > /sys/class/gpio/gpio17/value

touch ~/motion/arming
sleep 5m
rm ~/motion/arming
touch ~/motion/running
motion -c ~/motion/motion.conf

yatoy (desactivar videovigilancia)

La función del script yatoy es apagar el LED rojo, encender el verde y además cerrar motion
#!/bin/sh
#Detenemos Videovigilancia en Raspberry

#PIN 27: LED rojo
#PIN 17: LED verde
#PIN 22: LED rojo cristal
#Encendemos LED verde y apagamos LED roja. Dejamos LED rojo cristal como está

echo 0 > /sys/class/gpio/gpio27/value
echo 1 > /sys/class/gpio/gpio17/value
rm ~/motion/running
killall motion

¡Hay movimiento! El script haymovimiento

El script más importante: qué hacemos cuando hay movimiento.
En mi caso quiero que, además de poner las imágenes y los vídeos en la carpeta que se sincroniza con Google Drive (de esto se encargan Insync y motion.conf), recibir un correo en tiempo real con lo que está pasando en casa.

El sistema funciona de la siguiente manera, cuando ha movimiento motion dispara este script, esperamos 10 segundos para que haya alguna imagen, y luego enviamos un correo por cada imagen del evento. El email sale con el asunto «Motion detecta movimiento hh:mm».

Recordar que este script se ejecuta en motion con 2 parámetros, día y hora (en los formatos AAAAmmdd y hh:mm
on_event_start ~/motion/haymovimiento %Y%m%d %H:%M

El comando find del script se entiende como: encuentra ficheros más nuevos que el momento donde se disparó la alarma (newermt $1 $2) y el resultado pásaselo al comando mpack (que es el que envía los mails).

Este es el script:
#!/bin/bash
# Videovigilancia en Raspberry: ¡hay movimiento!

#PIN 27: LED rojo
#PIN 17: LED verde
#PIN 22: LED rojo cristal

#Encendemos LED rojo cristal
echo 1 > /sys/class/gpio/gpio22/value

# %1 Dia
# %2 Hora

# Esperamos 10 segundos para enviar imágenes
sleep 10s
cd ~/usuario@GMAIL.COM/VideoVigilancia

# Este comando es el central del sistema:
find . -name '*.jpg' -newermt "$1 $2" -exec mpack -a -s "Motion detecta movimiento "$2 '{}' usuario@gmail.com \;

sincro: el script cuando se acaba el evento de motion

Este es el script que se ejecuta cuando motion termina un evento, esto es, cuando ya no se detecta movimiento. En mi caso sólo apago el LED de alarma, antes además forzaba la actualización en Google Drive (cuando usaba otro sistema anterior a Insync).
#!/bin/bash
#PIN 27: LED rojo
#PIN 17: LED verde
#PIN 22: LED rojo cristal
#PIN 23: LED verde-testigo-always on
#Apagamos LED rojo cristal

echo 0 > /sys/class/gpio/gpio22/value

Arrancar el sistema de videovigilancia al arranque

Si necesitas que, apenas enciendas la Raspberry Pi, se inicie el sistema de videovigilancia, aquí te dejo el script para poner en /etc/init.d. En mi caso lo he llamado
/etc/init.d/motionVV.sh
#!/bin/sh

### BEGIN INIT INFO
# Provides: MotionVV
# Required-Start: hostname $all
# Required-Stop:
# Should-Start:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Ejecuta motion en el arranque
### END INIT INFO

cd /home/pi/motion echo Arrancamos motion
sudo -u pi /home/pi/motion/mevoy
Para que este script se ejecute al inicio, debes asegurarte de poner
sudo update-rc.d motionVV.sh defaults

¡Listo!

Y esta es la manera de tener un sistema de videovigilancia en Raspberry Pi, nada más y nada menos. 🙂

La idea de este artículo es compartir mi implementación, por eso si has montado otro o quieres compartir tu experiencia con este u otro sistema ¡déjame un comentario! ¡Será bienvenido!

Sistema de videovigilancia en Raspberry Pi usando motion
Salir de la versión móvil