Receta: seguridad laboral con detección de EPP y monitoreo de presencia
Marcá cascos y chalecos faltantes en una zona de trabajo durante el horario laboral, y detectá un puesto vacío o presencia fuera de hora. Dos apps de seguridad — con una nota honesta sobre cuál es experimental.
Por qué monitorear la seguridad
Dos preguntas de seguridad se repiten en una obra: ¿todos usan su equipo de protección, y está la persona correcta en su puesto (y nadie cuando no debería)? StreamHub responde ambas desde cámaras que ya tenés — detección de EPP para cascos y chalecos, y monitoreo de presencia para puestos vacíos y actividad fuera de hora. Una advertencia por adelantado, dicha con honestidad: la detección de EPP es experimental y de carácter orientativo, no un sistema de seguridad certificado.
La arquitectura en palabras
Ambas son Studio Apps con workers Python. safety-ppe corre un modelo YOLOv8 de EPP de la comunidad (vía ONNX) sobre el stream, asocia el equipo con las personas en zonas durante el horario laboral configurado, y dispara ppe.violation con una captura cuando a alguien le falta un elemento requerido. presence corre detección de personas en zonas rectangulares y dispara presence.absent cuando una zona queda vacía demasiado tiempo, presence.returned cuando alguien vuelve, y presence.after_hours cuando una zona está ocupada fuera del horario.
1. Detección de EPP (experimental)
export BASE="https://your-server.example.com/api/v1"
export TOKEN="sk_...."
curl -X POST $BASE/apps/site/plugins/safety-ppe/install -H "Authorization: Bearer $TOKEN"
curl -X PATCH $BASE/apps/site/plugins/safety-ppe -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"config": {
"room": "dock",
"requireHelmet": true,
"requireVest": true,
"zones": "[{\"name\":\"dock\",\"rect\":[0.1,0.2,0.5,0.7]}]",
"workHours": "08:00-18:00",
"workDays": "mon-fri",
"callbackUrl": "https://safety.example.com/hooks/ppe"
}
}'
Defaults clave: requireHelmet / requireVest true; zones vacío significa una zona a cuadro completo; workHours / workDays vacíos significan siempre activo; sustainFrames 3 (dispara tras más de 3 detecciones consecutivas); cooldownSeconds 120; confidence 0.35; association 0.5; fps 1 (YOLOv8m es ~1s por cuadro por núcleo de CPU — mantenelo en 1 en CPU). El payload de ppe.violation es { event, app, room, ts, zone, missing, confidence, snapshot_path }, donde missing es helmet, vest o helmet,vest, firmado cuando callbackSecret está seteado.
2. Monitoreo de presencia
curl -X POST $BASE/apps/site/plugins/presence/install -H "Authorization: Bearer $TOKEN"
curl -X PATCH $BASE/apps/site/plugins/presence -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"config": {
"room": "front-desk",
"zones": "[{\"id\":\"desk-1\",\"name\":\"Recepcion\",\"x\":0.1,\"y\":0.2,\"w\":0.3,\"h\":0.4}]",
"schedule": "08:00-18:00",
"scheduleDays": "mon-fri",
"thresholdMin": 5,
"afterHours": true,
"timezone": "America/Argentina/Buenos_Aires"
}
}'
Las zonas de presence son rectángulos (x/y/w/h, normalizados), no polígonos. thresholdMin 5 significa que una zona vacía por más de cinco minutos dispara presence.absent; afterHours true dispara presence.after_hours ante presencia fuera del horario. Los eventos van por los callbacks firmados de la app (más un callbackUrl crudo opcional), y el historial cae en apps/site/presence/presence.db.
3. Consumir los eventos
Ambas apps exponen su estado en vivo en la pestaña del dashboard (GET /apps/site/plugins/presence/data), y ambas hacen POST a tu webhook. Enrutá ppe.violation a un canal de supervisor, presence.absent a un jefe de turno, presence.after_hours a seguridad.
Qué deberías ver
Alguien que entra al muelle sin casco, en horario laboral, produce un ppe.violation con una captura tras unos cuadros sostenidos. Una recepción dejada vacía más de cinco minutos dispara presence.absent; la persona que vuelve dispara presence.returned; cualquiera en la recepción a las 3 de la mañana dispara presence.after_hours.
Resolución de problemas
- Falsos positivos/negativos de EPP — esperado. El modelo es de entrenamiento comunitario (mAP50 ≈ 0.78), sesgado hacia imágenes de construcción al aire libre, y más débil en las clases de "sin equipo" y en cascos chicos y lejanos. Tratá los eventos como señales orientativas; no construyas un control de cumplimiento solo sobre ellos.
- Picos de CPU con EPP — YOLOv8m cuesta ~1s de un núcleo por cuadro; mantené
fpsen 1 o menos en CPU, o sumá una GPU. - Presence nunca dispara ausente — el temporizador de vacío ancla en la primera muestra del worker, así que una zona ya vacía dispara
thresholdMindespués; confirmá que el rectángulo de la zona realmente cubra el puesto.
Cierre
Esto corre enteramente en tu hardware, y la app de EPP deliberadamente mantiene su evidencia local. Si necesitás un despliegue de seguridad robusto — modelos validados, flujos de aprobación, integración con un sistema de acceso al predio — es un servicio de consultoría donde fijamos las expectativas correctas y construimos hacia ellas, en vez de vender un modelo experimental como si estuviera certificado.