Home Assistant + IP Camera #
En este proyecto se instalará el servicio de Home Assistant para integrar una camara IP en nuestra red.
El acceso será única y exclusivamente a través de una VPN ya previamente configurada.
Estructura #
Red local con:
Ip pública asociada a dyndns: glmbxecurity.ddns.net
Home Assistant -> 192.168.1.4 + 10.0.0.6 (wg0)
Camara IP - > 192.168.1.5
VPS con:
Ip pública asodiada a dyndns: glmbxecurity.duckdns.org
Wireguard server: 194.164.167.198 + 10.0.0.1 (wg0)
Instalación y configuración #
Partimos de la base que el servidor wireguard está configurado, y el cliente wireguard de home assistant está conectado a la VPN. Para más detalles de su configuración, mirar mi proyecto de VPN.
Preparación Camara #
Dependiendo de la cámara se hará de una u otra forma, habrá que mirar en el manual, la idea es habilitar RTSP y/o ONVIF
RTSP #
Sirve para visualizar la cámara únicamente
ONVIF #
Sirve tanto para visualizar como para controlar, movimientos de cámara y funciones extra
En nuestro proyecto habilitaremos las 2 en una camara TP-LINK que se suele utilizar con la App “Tapo”
Una vez habilitado, se necesitará anotar las credenciales que se han configurado al habilitar RTSP / ONVIF
Instalación Home Assistant #
La manera más sencilla es a través de docker, con:
docker pull homeassistant/home-assistant
Inicio Home Assistant con el sistema #
Crear un fichero docker-compose.yml
version: "3.9"
services:
homeassistant:
container_name: homeassistant
image: homeassistant/home-assistant
privileged: true
restart: unless-stopped
network_mode: host
volumes:
- /home/usuario/homeassistant:/config
environment:
- TZ=Europe/Madrid
Iniciar contenedor con:
docker-compose up -d
Probar a reiniciar a ver si el contenedor aparece iniciado
Acceso y configuración #
Para acceder a la interfaz de administración, basta con ir a:
http://10.0.0.6:8123
Una vez dentro, crearemos nuestro “hogar” y una cuenta de usuario para acceder a home asssistant. Si tenemos un teléfono móvil podemos descargar la APP e iniciar sesión siempre que estemos conectados a la VPN.
Configuración camara #
En el apartado de configuración de Home Assistant > Integraciones, agregamos una integración y elegimos onvif
Introducimos:
Nombre: Nombre que le queramos dar
Host: Ip de la cámara (192.168.1.5)
Puerto: 2020
usuario: el configurado al habilitar onvif
contraseña: la que corresponde al usuario
Configurar grabaciones #
1. Directorio para almacenar grabaciones #
mkdir -p /root/homeassistant/www/recordings
chmod -R 755 /root/homeassistant/www/recordings
2. Montar volumen en docker #
Para poder ver los videos e imagenes grabados de la cámara desde la app, tiene que poder ser accesibles desde el docker, para ello montaremos la ruta creada anteriormente en el directorio /media del docker. Esto se hará editando el docker-compose.
Se agrega en volumes la siguiente línea:
- /root/homeassistant/www/recordings:/media
3. Configurar Alertas y grabaciones automáticas #
Localizar los ID de cámra y sensor en configuración > Dispositovos > Entidades:
- camera.id_camara
- binary_sensor.id_sensor
En mi caso:
- eddygalamba_mainstream
- eddygalamba_cell_motion_detection
Automatizaciones y escenas #
Una vez localizado estos datos, nos dirigimos a la configuracion del dispositivo y localizamos automatizaciones y escenas.
En automatizaciones > crear una nueva automatización > opción desde cero.
Después de mucha prueba y error, he dado con la configuración perfecta para mi cámara, no debería ser diferente para la tuya, pero podría cambiar algo.
Clic en los tres puntos y editar YAML (modificar entity.id, image, action, filename según corresponda)
alias: Alerta de movimiento en cámara
description: Notifica cuando se detecte movimiento y graba un clip de vídeo
triggers:
- entity_id: binary_sensor.eddygalamba_cell_motion_detection
from: "off"
to: "on"
trigger: state
conditions: []
actions:
- data:
title: Alerta de Movimiento
message: Se detectó movimiento en la cámara.
data:
image: http://10.0.0.6:8123/api/camera_proxy/camera.tu_camara
action: notify.mobile_app_motorola_edge_30_pro
- target:
entity_id: camera.eddygalamba_minorstream
data:
filename: >-
/config/www/recordings/movimiento_{{ now().strftime('%Y%m%d-%H%M%S')
}}.mp4
duration: 30
action: camera.record
mode: single
Guardar y reiniciar Home Assistant
Ahora la cámara debe mandar una alerta a la app del movil motorola, y además ponerse a grabar durante 30 segundos cuando detecte movimiento en el sensor de la cámara.
Luego en Medios > My media debes de ver las grabaciones
Troubleshooting #
Si tienes problemas de que no se ve, puedes comprobar que se está accediendo correctamente a los ficheros a través de una URL, y descartar que sea problemas de permisos.
Si el archivo se configura con la ruta /config/www/recordings/
, los vídeos se almacenarán en tu máquina anfitriona en:
/home/usuario/homeassistant/www/recordings/
Se puede probar a crear un fichero de prueba a ver si accediendo, se ve el fichero: http://10.0.0.6:8123/local/recordings/prueba.txt
4. Script (cron), limitar grabaciones 1GB #
Este script será una tarea cron que se ejecutará a nivel S.O para que el directorio de grabaciones no ocupe más de 1GB, en ese caso eliminará los ficheros más antiguos conforme se vaya “llenando la memoria”.
ejecutamos:
crontab -e
Escribimos abajo del todo:
*/5 * * * * /root/scripts/limit_card_records_1gb.sh
Esto ejecutará la tarea cada 5 minutos (se puede editar).
Luego creamos el script y le damos permisos de ejecución. El contenido del script:
#!/bin/bash
# Carpeta donde se guardan los videos
VIDEO_FOLDER="/root/homeassistant/www/recordings/"
# Límite de espacio en MB (1GB = 1024MB)
LIMIT_MB=1024
# Obtener el tamaño total de la carpeta en MB
current_size=$(du -sm "$VIDEO_FOLDER" | cut -f1)
# Eliminar archivos más antiguos si se supera el límite
while [ "$current_size" -gt "$LIMIT_MB" ]; do
# Encontrar el archivo más antiguo y eliminarlo
oldest_file=$(find "$VIDEO_FOLDER" -type f -printf '%T+ %p\n' | sort | head -n 1 | awk '{print $2}')
rm -f "$oldest_file"
echo "Eliminado: $oldest_file"
# Actualizar el tamaño de la carpeta
current_size=$(du -sm "$VIDEO_FOLDER" | cut -f1)
done
DashBoard Personalizado #
Este apartado dependerá del gusto personal y necesidades, pero se puede crear algo así:
En mi caso puse una preview de la cámara, 3 botones (grabar 30s, tomar imagen y activar/desactivar la alerta+grabación creadas anteriormente).
A continuación un gráfico para monitorizar el movimiento, y un seguimiento de los momentos en que el sensor detecta movimiento.
Para crear el dashboard nos vamos a Configuración > Paneles y creamos uno nuevo (al finalizar, lo podemos establecer como dashboard predeterminado para el dispositivo).
La configuración la hice poco a poco a ensayo y error, pero la configuración final quedaría así (Si quieres algo similar, simplemente puedes copiar y pegar, editando sensores, directorios, etc):
views:
- title: Cámara
sections:
- type: grid
cards:
- type: heading
heading_style: title
heading: Cámara Salon
icon: mdi:camera
- type: picture-entity
entity: camera.eddygalamba_minorstream
- show_name: true
show_icon: true
type: button
tap_action:
action: perform-action
perform_action: camera.record
target:
entity_id: camera.eddygalamba_minorstream
data:
lookback: 0
filename: >-
/config/www/recordings/grabacion_{{
now().strftime('%Y%m%d-%H%M%S') }}.mp4
duration: 30
entity: camera.eddygalamba_minorstream
name: Grabar 30s
grid_options:
columns: 3
rows: 2
- show_name: true
show_icon: true
type: button
tap_action:
action: perform-action
perform_action: camera.snapshot
target:
entity_id: camera.eddygalamba_minorstream
data:
filename: >-
/config/www/recordings/imagen_{{
now().strftime('%Y%m%d-%H%M%S') }}.jpg
entity: camera.eddygalamba_minorstream
name: Tomar foto
icon: mdi:camera
show_state: false
grid_options:
columns: 3
rows: 2
- show_name: true
show_icon: true
type: button
entity: automation.prueba
show_state: true
grid_options:
rows: 2
- type: grid
cards:
- type: heading
heading_style: title
heading: Movimientos
- type: history-graph
entities:
- entity: binary_sensor.eddygalamba_cell_motion_detection
logarithmic_scale: false
- type: logbook
target:
entity_id:
- binary_sensor.eddygalamba_cell_motion_detection
badges: []
background:
opacity: 33
alignment: center
size: cover
repeat: repeat
attachment: fixed
image: /api/image/serve/af189795b7e76a5c378c5360c5ea58cb/original
cards: []
type: sections
max_columns: 4
icon: mdi:camera