← Volver al blog
Plugins #perimeter

Receta: detección de intrusos de perímetro con evidencia y alertas

Dibujá zonas sobre una cámara, armalas en un horario nocturno, y recibí un webhook firmado más evidencia de captura y clip en el instante en que una persona entra. Un pipeline de intrusión auto-alojado completo.

4 min de lectura
Read in English

Por qué detección de perímetro

Un sensor de movimiento no distingue una persona de un gato, y un servicio de cámara en la nube manda tu video a los servidores de otro. La Studio App Perimeter vigila tu propia cámara buscando personas dentro de zonas que vos definís, solo mientras está armada, y entrega evidencia a un webhook que vos controlás. Es la diferencia entre "algo se movió" y "una persona entró al muelle de carga a las 02:14, acá está la captura y un clip de diez segundos".

La arquitectura en palabras

Perimeter es una Studio App con un worker Python (detección de personas YOLOv8 sobre el HLS de la app). Definís zonas como rectángulos o polígonos normalizados, un horario de armado y una URL de callback. Cuando el punto del pie de una persona cae dentro de una zona armada, el worker escribe una captura JPEG y un clip corto opcional a disco, registra la alerta en un perimeter.db por app, hace POST de un evento perimeter.intrusion firmado a tu webhook, y lo empuja al panel en vivo del dashboard.

1. Instalar y apuntar a una cámara

export BASE="https://your-server.example.com/api/v1"
export TOKEN="sk_...."

curl -X POST $BASE/apps/security/plugins/perimeter/install -H "Authorization: Bearer $TOKEN"

curl -X PATCH $BASE/apps/security/plugins/perimeter -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
        "enabled": true,
        "config": {
          "room": "cam-dock",
          "zones": "[{\"id\":\"gate\",\"rect\":[0.6,0.4,0.35,0.55]}]",
          "callbackUrl": "https://alerts.example.com/hooks/perimeter",
          "callbackSecret": "un-secreto-compartido-largo"
        }
      }'

room y al menos una zona son obligatorios. Las zonas son JSON, normalizadas 0–1: un rect es [x, y, ancho, alto]; los polígonos toman points.

2. Definir el horario de armado

Las perillas clave (con sus defaults):

  • armModeschedule (default), o armed / disarmed para forzar manualmente.
  • armSchedule"22:00-06:00" por defecto; una ventana HH:MM-HH:MM en hora local que cruza la medianoche.
  • armWeekendstrue; arma todo el sábado y domingo además de la ventana diaria.
  • timezone — un nombre IANA; vacío usa la hora local del host.
  • confidence0.5; fps1; cooldown60 segundos por zona; clipSeconds10 (0 desactiva el clip); anchorfoot; modelnano (o small).

Así, un depósito armado cada noche y todo el fin de semana es simplemente armMode: schedule, armSchedule: "20:00-07:00", armWeekends: true, timezone: "America/Argentina/Buenos_Aires".

3. Verificar la cadena de aviso

Cada intrusión hace POST a tu callbackUrl:

{ "event": "perimeter.intrusion", "app": "security", "room": "cam-dock",
  "ts": 1751000000.42, "zone": "gate", "confidence": 0.88,
  "snapshot": "…/evidence/20260709-233015-482-gate.jpg", "clip": "…-gate.mp4" }

Cuando callbackSecret está seteado, el cuerpo se firma con X-StreamHub-Signature: sha256=<hex> (HMAC-SHA256) — verificalo igual que cualquier webhook de StreamHub. Desde ahí, repartí a email, Slack o una sirena como quieras.

4. Leer las alertas en el dashboard

La pestaña de Perimeter lee el canal en vivo autenticado, GET /apps/security/plugins/perimeter/live/state, que transmite el estado de armado actual, las cajas de personas en vivo y las alertas recientes (con miniaturas base64). Para reconocer alertas hasta un punto, hacé PATCH del campo de config ackThrough al timestamp de esa alerta — todo lo anterior o igual pasa a reconocido.

Qué deberías ver

Mientras está desarmado, nada dispara. Dentro de la ventana armada, caminar hacia la zona gate produce un webhook en cerca de un segundo, una entrada en la lista de alertas de la pestaña con una miniatura, y una captura (más un clip de ~10s) bajo apps/security/perimeter/evidence/.

Resolución de problemas

  • Ninguna alerta — verificá que estés dentro de la ventana armada (o poné armMode: armed para probar ahora), y que room más al menos una zona estén seteados.
  • Captura pero sin clip — el clip -c copy se corta del HLS local en disco. Un worker que lee HLS por HTTP (un nodo edge remoto) graba solo captura; corré co-localizado para clips.
  • Demasiadas alertas — subí confidence, achicá la zona, o aumentá cooldown.
  • CPU alta — esto es detección real: presupuestá cerca de 0.5–1 núcleo de CPU y ~1.5–2 GB de RAM por sala vigilada a 1–2 fps. Bajá fps o usá una GPU (cuda: true) para más.

Cierre

Todo el pipeline — modelo, evidencia, base de datos, alertas — corre en tu hardware, y el video nunca sale de ahí. Si necesitás armado multi-cámara, una consola de alertas para guardias, o integración con un NVR o SOC existente, nuestro equipo los construye sobre la Studio App Perimeter open source.