Receta: conectar una ESP32-CAM y datos IoT
Transmití cuadros MJPEG desde una cámara de dos dólares por una sola WebSocket, mandá lecturas de sensores por la misma conexión, ingerí MQTT de tu flota, y convertí cualquiera de esos en un trigger de flujo.
Por qué ingesta IoT
Una ESP32-CAM cuesta un par de dólares y no tiene codificador H.264, así que la vía RTMP habitual necesita un salto de transcode. La ingesta por WebSocket de StreamHub toma los cuadros MJPEG crudos de la cámara directamente — y deja que el mismo dispositivo mande datos de sensores por el mismo socket. Sumá MQTT-in para el resto de tu flota, y cada lectura se vuelve un evento sobre el que podés automatizar.
La arquitectura en palabras
El dispositivo abre una WebSocket a /ingest/ws, autenticada con una clave wsk_, y manda cuadros JPEG completos como mensajes binarios. Los espectadores tiran esos cuadros como MJPEG sin relay y sin transcode. Por el mismo socket el dispositivo puede mandar cuadros de texto data, y un suscriptor MQTT-in aparte tira mensajes de tu broker; ambos convergen en un único evento iot.data que se reparte a webhooks y a Streamflow.
1. Aprovisionar una cámara WebSocket
export BASE="https://your-server.example.com/api/v1"
export TOKEN="sk_...."
curl -s -X POST $BASE/apps/iot/ws-ingest -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"room":"cam1","identity":"porton-norte"}'
La respuesta devuelve un id (wsi_…), una streamKey (wsk_…), y las wsUrl, mjpegUrl y playerUrl.
2. Apuntar el dispositivo al socket
La ESP32 conecta y transmite cuadros JPEG:
wss://your-server.example.com/ingest/ws?app=iot&room=cam1&key=wsk_...
Cada mensaje binario es un JPEG completo (FF D8 … FF D9). Al conectar, el servidor manda un cuadro ready con los límites que va a aplicar (maxFps 15, maxFrameBytes, y los topes de cuadros de datos).
3. Mandar datos de sensores por la misma conexión
El dispositivo manda un cuadro de texto para publicar una lectura:
{ "type": "data", "topic": "door", "data": { "open": true, "battery": 87 } }
Eso se vuelve un evento iot.data { topic, deviceId, data, source: "ws" }. Límites de cuadros de datos (de features.ws_ingest): max_data_bytes 16384, max_data_per_sec 5 — un cuadro de datos sobredimensionado se descarta (solo un JPEG sobredimensionado cierra el socket).
4. Ingerir MQTT del resto de la flota
Agregá una lista subscribe a la config mqtt de la app para que los mensajes del broker se vuelvan el mismo evento:
mqtt:
enabled: true
url: "mqtt://broker.example.com:1883"
subscribe:
- topic: devices/#
Cada mensaje entrante despacha iot.data { topic, data, source: "mqtt" } (JSON si es válido, si no la cadena cruda), con tope de 64 suscripciones y 64 KB por mensaje.
5. Mirar la cámara y disparar un flujo
Mirá el MJPEG en vivo sin token cuando la reproducción pública está activa:
https://your-server.example.com/live/iot/cam1/mjpeg
https://your-server.example.com/live/iot/cam1/frame.jpg
Después, en Streamflow, una caja trigger.mqtt que dispara ante el tema door (coincidido desde el cuadro de datos WS o desde MQTT-in) puede capturar una foto y avisarte en el instante en que se abre el portón.
Qué deberías ver
Los cuadros de la cámara aparecen en la URL MJPEG a segundos de que el dispositivo conecta; cada lectura de sensor y cada mensaje del broker aparece como un evento iot.data en tu log de webhooks; y un flujo de Streamflow atado al tema corre en el momento justo.
Resolución de problemas
- El socket cierra al instante — verificá que la clave, la app y la sala coincidan con la cámara aprovisionada; un desajuste cierra con
4401, una función deshabilitada o cuota excedida con4403. - Cuadros rechazados — un JPEG por encima de
max_frame_kb(256 KB por defecto) cierra con4413; bajá la resolución/calidad de la cámara. - Sin audio, sin grabación — la ingesta WS v1 es solo video y datos: sin audio (la cámara no tiene micrófono), sin grabación MP4/HLS, sin bitrate adaptativo. Para medio completo, usá la vía de relay ffmpeg a RTMP.
- ¿Datos de salida? — recibir datos de vuelta en el dispositivo por el socket todavía no está implementado; esta etapa es solo datos de entrada.
Cierre
Cámaras y sensores baratos, transmitidos y automatizados en tu propio servidor — esa es la historia IoT sin una nube de dispositivos. Si querés firmware, un flujo de aprovisionamiento de flota, o los flujos cableados de punta a punta, nuestro equipo los construye alrededor de la ingesta open source como servicio de consultoría.