Automatización IoT

Redes de sensores de ocupación de oficinas con MQTT: PIR, mmWave y CO2

Cómo elegir entre detección PIR, mmWave y CO2, diseñar topics MQTT para salas y puestos de trabajo y convertir los datos de ocupación en informes de uso y ahorros en climatización.

Techo de una sala de reuniones con un pequeño sensor de ocupación de oficinas enviando datos de presencia a un panel en la nube
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

Una red de sensores de ocupación de oficinas te dice qué salas y puestos se usan realmente, y cuándo. En este caso de uso compararás la detección PIR, mmWave y basada en CO2, publicarás la ocupación por MQTT con un diseño de topics limpio y usarás los datos para informes de uso del espacio y para un control de la climatización basado en la demanda sobre un broker de ConnectMQ.

Por qué medir la ocupación

El trabajo híbrido ha hecho impredecible el uso de las oficinas. Las salas de reuniones reservadas en el calendario se quedan vacías, mientras que las pequeñas salas de concentración siempre están llenas. Las plantas se calientan y se enfrían según el horario completo incluso los días en que solo acude una parte del personal, tanto en un corporativo de Ciudad de México como en unas oficinas de Barcelona. Los datos de ocupación responden a preguntas prácticas: qué salas están sobredimensionadas, si se puede cerrar una planta los viernes y si se puede reducir la ventilación en las zonas vacías.

Los sistemas de reserva y los datos de las tarjetas de acceso dan parte de la imagen, pero registran intenciones y entradas, no la presencia real en una sala. Los sensores cubren ese vacío, y MQTT es una forma natural de recoger sus datos en muchos edificios.

Elegir la tecnología de detección adecuada

Cada tecnología tiene un modo de fallo característico, y los mejores despliegues combinan dos.

Tecnología Cómo funciona Ventajas Inconvenientes Ideal para
PIR Detecta fuentes de calor en movimiento Barato, bajo consumo, maduro No detecta a las personas que están quietas, así que las salas parecen vacías durante el trabajo concentrado Pasillos, aseos, control de iluminación
Radar mmWave Detecta movimientos diminutos, incluida la respiración Detecta a personas inmóviles, funciona a través de cubiertas finas Puede ver a través de las paredes y captar a los vecinos si no se ajusta; necesita red eléctrica o una batería grande Salas de reuniones, salas de concentración, puestos
CO2 El aumento de la concentración de CO2 indica personas respirando Ofrece un recuento aproximado y la calidad del aire a la vez Lento (minutos), depende del caudal de ventilación Control de la ventilación, salas grandes
Sensores de puesto PIR o térmico bajo la mesa Uso a nivel de puesto Muchos dispositivos que mantener Analítica de puestos compartidos
Matriz térmica / contadores de personas Imagen térmica de baja resolución o recuento en puertas Cuenta personas sin imágenes Mayor coste, colocación cuidadosa Grandes espacios abiertos, entradas

Una combinación habitual y robusta para salas de reuniones es mmWave para la presencia más CO2 para la confirmación y la ventilación. Un PIR por sí solo tiende a dar una sala por vacía durante las videollamadas largas, porque la gente apenas se mueve.

La privacidad, lo primero

Los datos de ocupación tratan sobre personas. Usa sensores que no capten imágenes, publica presencia o recuentos en lugar de identidades y nunca pongas nombres ni ID de tarjetas en los topics. Agrega los datos de los puestos antes de compartirlos ampliamente, y revisa la normativa local y los acuerdos con el comité de empresa antes del despliegue.

Diseño de topics y payloads MQTT

Modela los topics según la jerarquía física para que los comodines respondan a preguntas reales:

acme/ist01/hq/f03/meeting-301/occupancy        presence state (retained)
acme/ist01/hq/f03/meeting-301/co2              CO2 ppm
acme/ist01/hq/f03/desk-3-14/occupancy          desk presence (retained)

Un mensaje de presencia debe incluir el estado, la fuente y cuándo cambió por última vez:

{
  "ts": "2026-10-16T09:41:07Z",
  "occupied": true,
  "source": "mmwave",
  "since": "2026-10-16T09:12:30Z",
  "count_estimate": null
}

Publica la ocupación como retenida para que un panel o un gemelo digital 3D del edificio que se conecte a mitad del día muestre el estado actual de inmediato. Publica en cada cambio más un latido cada pocos minutos, lo que mantiene el tráfico mínimo y te permite detectar un sensor caído. Con la jerarquía tipo carpeta, acme/ist01/hq/f03/+/occupancy devuelve todas las salas y puestos de la tercera planta, y la vista de dispositivos de ConnectMQ puede agrupar esos mismos topics por sede y área.

Un nodo de sensor mmWave sencillo

Los módulos mmWave populares de bajo coste, como la familia LD2410, exponen un pin de salida digital que se pone en alto cuando se detecta presencia. Un ESP32 puede filtrar los rebotes de ese pin y publicar los cambios. El sketch usa PubSubClient y el broker público para las pruebas.

#include <WiFi.h>
#include <PubSubClient.h>

const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* BROKER = "broker.connectmq.com";
const int   PORT = 1883;
const char* TOPIC = "connectmq/demo/occ-5t2w/f03/meeting-301/occupancy";
const int   PRESENCE_PIN = 27;           // pin OUT del LD2410
const unsigned long HOLD_MS = 60000;     // mantener "ocupado" 60 s tras la última detección
const unsigned long HEARTBEAT_MS = 300000;

WiFiClient net;
PubSubClient mqtt(net);
bool occupied = false;
unsigned long lastSeen = 0, lastPublish = 0;

void publishState() {
  char msg[96];
  snprintf(msg, sizeof(msg), "{\"occupied\":%s,\"source\":\"mmwave\",\"uptime_s\":%lu}",
           occupied ? "true" : "false", millis() / 1000);
  mqtt.publish(TOPIC, msg, true);        // retenido
  lastPublish = millis();
}

void connectMqtt() {
  while (!mqtt.connected()) {
    String id = "occ-" + String((uint32_t)ESP.getEfuseMac(), HEX);
    if (mqtt.connect(id.c_str())) {
      publishState();
    } else {
      delay(2000);
    }
  }
}

void setup() {
  pinMode(PRESENCE_PIN, INPUT);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(250);
  mqtt.setServer(BROKER, PORT);
}

void loop() {
  if (!mqtt.connected()) connectMqtt();
  mqtt.loop();

  if (digitalRead(PRESENCE_PIN) == HIGH) lastSeen = millis();
  bool now = (millis() - lastSeen) < HOLD_MS && lastSeen != 0;

  if (now != occupied) {
    occupied = now;
    publishState();
  } else if (millis() - lastPublish > HEARTBEAT_MS) {
    publishState();
  }
  delay(100);
}

El tiempo de retención es el parámetro de ajuste más importante. Si es demasiado corto, la sala parpadea entre ocupada y vacía; si es demasiado largo, la sala parece ocupada después de que la gente se haya ido. Entre sesenta segundos y unos pocos minutos funciona bien para las salas de reuniones. Ajusta el alcance de detección del radar con la herramienta del fabricante para que no vea el pasillo.

De la presencia en bruto al uso del espacio

Los mensajes de encendido/apagado en bruto se vuelven útiles una vez agregados. Un pequeño suscriptor puede calcular, por sala y por día, la proporción del horario laboral en que la sala estuvo ocupada. Una versión mínima en Python:

import json
import time
import uuid
from collections import defaultdict

import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/occ-5t2w"
occupied_since = {}
occupied_seconds = defaultdict(float)


def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(f"{PREFIX}/+/+/occupancy", qos=1)


def on_message(client, userdata, msg):
    room = "/".join(msg.topic.split("/")[-3:-1])
    data = json.loads(msg.payload)
    now = time.time()
    if data["occupied"] and room not in occupied_since:
        occupied_since[room] = now
    elif not data["occupied"] and room in occupied_since:
        occupied_seconds[room] += now - occupied_since.pop(room)
    hours = occupied_seconds[room] / 3600
    client.publish(f"{PREFIX}/{room}/utilization",
                   json.dumps({"occupied_hours_today": round(hours, 2)}), retain=True)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"occ-agg-{uuid.uuid4().hex[:6]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, 60)
client.loop_forever()

En producción, guarda las transiciones en una base de datos para poder informar de los picos semanales y comparar salas por tamaño.

Usar la ocupación para controlar la climatización

Los datos de ocupación se amortizan más rápido cuando gobiernan la ventilación y los ajustes de temperatura:

  1. Cuando una zona lleva vacía un tiempo determinado, un gateway puede ampliar su banda muerta de temperatura o reducir el caudal de aire.
  2. Cuando el CO2 supera tu objetivo, aumenta la ventilación con independencia del estado de presencia.
  3. Antes de la ocupación programada, preacondiciona el espacio como siempre; la ocupación solo recorta el horario, nunca lo sustituye.
  4. Mantén siempre seguro el control local: el controlador de climatización debe volver a su horario si dejan de llegar datos de ocupación.

La ruta de escritura de vuelta hacia el BMS es la misma que se describe en BACnet a MQTT, y la parte de climatización se trata en monitorización HVAC con sensores IoT. La medición de CO2 sirve también como señal de calidad del aire; consulta nuestro montaje de monitor de calidad del aire interior.

Validar la precisión de los sensores

Antes de que nadie elabore un informe con datos de ocupación, comprueba que los sensores dicen la verdad. Una semana de validación sencilla funciona bien. Elige unas cuantas salas y pide a un compañero que anote el uso real a horas fijas, o compara los datos de los sensores con las reservas del calendario y busca discrepancias. Los hallazgos típicos son sensores mmWave que dan una sala por ocupada porque ven movimiento en el pasillo, sensores PIR que dan salas por vacías durante llamadas largas y sensores de CO2 que van diez minutos o más por detrás de la llegada de la gente.

Corrige cada hallazgo en el origen: reduce el alcance de detección del radar, recoloca un PIR para que mire hacia la zona de asientos en lugar de hacia la puerta o usa el CO2 solo como señal de confirmación. Registra la configuración final por tipo de sala para que las nuevas instalaciones partan de una configuración probada. La validación también genera confianza entre las personas cuyas salas se miden, algo tan importante como la precisión técnica.

Lista de comprobación del despliegue

  1. Revisa las salas y decide la tecnología por tipo de sala.
  2. Monta los sensores mmWave orientados hacia el interior de la sala, lejos de puertas y ventanas.
  3. Da a cada sensor un client ID y unas credenciales únicos en un broker privado.
  4. Pon en marcha cada sala entrando y saliendo mientras observas el explorador de topics.
  5. Deja funcionar el sistema dos semanas antes de sacar conclusiones sobre el uso.

Hacer pruebas en el servidor MQTT público gratuito está bien con un prefijo de demostración, pero los datos de ocupación reales revelan cuándo hay gente en el edificio, así que corresponden a un broker privado con TLS. Un broker MQTT gestionado de ConnectMQ da a cada sensor sus propias credenciales, y unas cuantas decenas de sensores caben holgadamente en un piloto. Para más proyectos de edificios, consulta la guía de automatización IoT.

Ejecuta tus sensores de ocupación en ConnectMQ

Regístrate en app.connectmq.com y crea un broker Serverless gratuito, sin tarjeta de crédito. Conecta tus primeros sensores, observa en vivo cómo cambia la presencia en el explorador de topics y añade reglas de alerta por umbral para el CO2 en las salas más concurridas. ConnectMQ se ocupa del broker para que tú puedas centrarte en el espacio.

Preguntas frecuentes

¿Qué sensor de ocupación de oficinas es más preciso para las salas de reuniones?

El radar mmWave suele ser la mejor opción individual porque detecta a las personas sentadas e inmóviles. Combinarlo con CO2 aporta confirmación y permite controlar la ventilación.

¿Los sensores de ocupación capturan datos personales?

Los sensores PIR, mmWave y de CO2 no captan imágenes ni identidades, pero los patrones de ocupación siguen siendo sensibles. Publica solo presencia o recuentos y mantén los datos en un broker privado.

¿Cuánto debe durar el tiempo de retención?

Empieza con 60 segundos para las salas pequeñas y hasta unos pocos minutos para las grandes, y ajústalo tras observar datos reales durante una semana.

¿Pueden los datos de ocupación reducir el consumo energético de la climatización?

Sí, relajando la temperatura y la ventilación en las zonas vacías. Mantén el horario del controlador como respaldo para que el confort nunca dependa de la red de sensores.

Artículos relacionados

Guía para configurar Zigbee2MQTT: del coordinador al panel

Instala Zigbee2MQTT con Docker, configura el coordinador y la conexión MQTT, empareja y renombra dispositivos, contrólalos por MQTT y consulta sus estados en un panel, probando primero en un servidor MQTT público gratuito.

8 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.