Cámaras y SeguridadTécnico

Cámara Pi Zero que graba clips de movimiento en tu NAS

Una cámara pequeña y barata que guarda un clip de video, incluyendo los segundos antes del movimiento, directo a una carpeta de red.

NivelTécnico
Tiempo1.5 h
Costo est.~$67
Pasos5

Picamera2 puede guardar en memoria los últimos segundos de video con un búfer circular. Cuando la vista de baja resolución cambia lo suficiente, el script guarda ese búfer y lo que sigue en tu NAS, así casi no se usa la tarjeta SD.

⚠ SEGURIDAD
Graba solo áreas que sean tuyas o que tengas permiso de grabar, y dile a la gente que vive contigo dónde están las cámaras.

Pasos de la misión

  1. Conecta la cámara

    Usa el cable de 22 a 15 pines: el extremo angosto va al Pi Zero 2 W, con los contactos hacia la placa. Prueba con rpicam-hello.

  2. Monta la carpeta del NAS

    Crea una carpeta en tu NAS y agrega una entrada CIFS o NFS en /etc/fstab con las opciones nofail y _netdev, montada en /mnt/nas.

  3. Corre el script

    Guarda el script de abajo y córrelo con python3. Mueve la mano frente a la cámara y verifica que aparezca un archivo en el NAS.

  4. Ajusta la sensibilidad

    Sube THRESHOLD si los árboles o cambios de luz la disparan; bájalo si pasa gente sin que se active.

  5. Arranca al encender

    Crea un servicio de systemd con Restart=always para que siga funcionando tras reinicios y fallas del NAS.

Código

import time, datetime
import numpy as np
from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import CircularOutput

SAVE, THRESHOLD = '/mnt/nas/porch', 7
W, H = 320, 240
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={'size': (1280, 720)}, lores={'size': (W, H), 'format': 'YUV420'}))
encoder = H264Encoder(2000000, repeat=True)
encoder.output = CircularOutput(buffersize=150)   # about 5 s at 30 fps
picam2.start()
picam2.start_encoder(encoder)

prev, recording, last_motion = None, False, 0
while True:
    cur = picam2.capture_buffer('lores')[:W * H].reshape(H, W).astype(np.int16)
    if prev is not None:
        if np.square(cur - prev).mean() > THRESHOLD:
            last_motion = time.time()
            if not recording:
                name = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
                encoder.output.fileoutput = f'{SAVE}/{name}.h264'
                encoder.output.start(); recording = True
                print('motion ->', name)
        elif recording and time.time() - last_motion > 10:
            encoder.output.stop(); recording = False
    prev = cur

Code comments are in English, like most libraries and docs — a good habit for makers.

Preguntas

¿Cómo reproduzco los archivos .h264?

VLC los reproduce directamente. Para tener archivos MP4 normales, corre ffmpeg -i clip.h264 -c copy clip.mp4 en el NAS o en tu PC.

¿Puedo usar motionEye en su lugar?

Sí, si prefieres una interfaz web. Verifica que la versión actual de motionEye soporte tu cámara y sistema; este script es más liviano y usa la librería oficial Picamera2.