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.
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):
armMode—schedule(default), oarmed/disarmedpara forzar manualmente.armSchedule—"22:00-06:00"por defecto; una ventanaHH:MM-HH:MMen hora local que cruza la medianoche.armWeekends—true; 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.confidence—0.5;fps—1;cooldown—60segundos por zona;clipSeconds—10(0 desactiva el clip);anchor—foot;model—nano(osmall).
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: armedpara probar ahora), y queroommás al menos una zona estén seteados. - Captura pero sin clip — el clip
-c copyse 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á
fpso 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.