Automatización IoT

Aparcamiento inteligente IoT con MQTT: sensores de plaza, recuento de ocupación y mapa de disponibilidad en vivo

Un plano práctico para el aparcamiento inteligente con IoT: elige sensores de plaza, diseña los topics MQTT, agrega las plazas libres por zona y alimenta un mapa en vivo en el navegador mediante WebSocket seguro.

Diagrama de aparcamiento inteligente IoT con sensores de plaza en un parking que publican la ocupación en un mapa de disponibilidad en vivo
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

Los sistemas de aparcamiento inteligente IoT (o estacionamiento inteligente, como se dice en buena parte de América Latina) indican a los conductores dónde hay plazas libres antes de que empiecen a dar vueltas, y muestran a los operadores cómo se usan realmente sus aparcamientos. Este artículo recorre un diseño completo: la elección de los sensores de plaza, la estructura de los topics MQTT, la agregación de plazas libres por zona y un mapa en vivo en el navegador que se actualiza en cuanto sale un vehículo.

Qué tiene que hacer un sistema de aparcamiento inteligente

Si quitamos el marketing, un sistema de guiado de aparcamiento tiene cuatro tareas:

  1. Detectar si cada plaza está ocupada.
  2. Transportar esos cambios de estado de forma fiable desde el terreno hasta el back end.
  3. Agregar las plazas individuales en las cifras que importan a la gente: plazas libres por planta, por zona y por aparcamiento.
  4. Mostrar el resultado en paneles, apps y mapas, casi en tiempo real.

MQTT encaja de forma natural en las capas de transporte y visualización. Cada plaza es un topic de estado retenido, los agregadores se suscriben con comodines y los navegadores se suscriben por WebSocket para recibir actualizaciones en vivo. El resto del artículo sigue los datos desde el asfalto hasta la pantalla.

Cómo elegir los sensores de plaza

Tipo de sensor Cómo funciona Ventajas Precauciones
Magnetómetro (empotrado o disco de superficie) Detecta la alteración del campo magnético terrestre que provoca un vehículo Larga duración de la batería, no le afectan la luz ni el clima Interferencias de plazas contiguas, necesita calibración
Radar (combinado con magnetómetro) Reflexión de corto alcance en los bajos del vehículo Menos falsos positivos que el magnetómetro solo Mayor coste y consumo
Ultrasónico (montado en techo) Mide la distancia hasta el techo del vehículo Sencillo, habitual en garajes cubiertos, a menudo con indicador LED Requiere alimentación de red y montaje en interior
Cámara con modelo de visión Una cámara cubre muchas plazas Bajo coste por plaza, puede leer matrículas Normas de privacidad, iluminación, procesamiento en el edge

Para aparcamientos al aire libre y plazas en la calzada, lo habitual son discos magnetómetro o radar alimentados por batería sobre LoRaWAN o NB-IoT. Los garajes cubiertos suelen usar sensores ultrasónicos de techo en un bus cableado con un gateway local. Los sistemas de cámara publican resultados, no vídeo: el dispositivo edge ejecuta la detección y publica solo occupied o free por plaza.

Vías de conectividad hasta el broker

La forma en que los sensores llegan al broker condiciona la arquitectura más que el tipo de sensor:

  • LoRaWAN: los sensores hablan con gateways, los gateways reenvían a un servidor de red como The Things Stack o ChirpStack, y el servidor de red, o un pequeño servicio puente, publica los datos decodificados en tu broker. Cientos de plazas se convierten en una sola conexión MQTT. Consulta The Things Network con MQTT para el paso de puenteo.
  • NB-IoT o LTE-M: cada sensor puede conectarse directamente por MQTT o informar a través de la plataforma del operador, que después puenteas.
  • Bus cableado más gateway: un gateway interior consulta los sensores ultrasónicos y publica los cambios.
  • Cámara edge: un pequeño ordenador ejecuta la detección y publica los resultados por plaza.

El enfoque con gateway resulta atractivo más allá del coste. Mantiene bajo el número de conexiones, de modo que incluso un plan de broker pequeño gestiona un aparcamiento grande, y el estado de cada plaza sigue siendo un topic MQTT limpio cuando llega a tus aplicaciones.

Diseño de topics para el aparcamiento inteligente IoT

Una jerarquía que refleje la distribución física convierte cada consulta en un comodín:

parking/<site>/<level>/<bay>/state          retained: {"occupied":true,"ts":1760600000}
parking/<site>/<level>/<bay>/battery        retained: 3.41
parking/<site>/<level>/summary              retained: {"free":37,"total":120}
parking/<site>/summary                      retained: {"free":112,"total":420}
parking/<site>/<level>/<bay>/availability   retained online/offline (gateway-reported)
  • parking/central/+/+/state son todas las plazas del aparcamiento central.
  • parking/+/summary es la cifra principal de cada emplazamiento, que es todo lo que necesita un panel a escala de ciudad.

Retener tanto los estados de las plazas como los resúmenes significa que una app o un panel nuevos muestran las cifras correctas en cuanto se conectan. Incluye una marca de tiempo en el payload, porque una plaza que no ha informado en un día está "desconocida", no "libre".

Agregación de plazas libres por planta

Un agregador se suscribe a todos los estados de plaza, los mantiene en memoria y vuelve a publicar los resúmenes cada vez que algo cambia. Esta versión en Python usa paho-mqtt 2.x y el servidor MQTT público gratuito de ConnectMQ, pensado para pruebas y prototipos, no para datos de producción:

import json
import time
from collections import defaultdict
import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/p3v6z8"         # tu propio prefijo aleatorio
SITE = "central"
STALE_AFTER = 6 * 3600                    # segundos sin informe = desconocido
bays = {}                                 # (level, bay) -> {"occupied": bool, "ts": float}

def publish_summaries(client):
    now = time.time()
    per_level = defaultdict(lambda: {"free": 0, "occupied": 0, "unknown": 0, "total": 0})
    for (level, _), s in bays.items():
        bucket = per_level[level]
        bucket["total"] += 1
        if now - s["ts"] > STALE_AFTER:
            bucket["unknown"] += 1
        elif s["occupied"]:
            bucket["occupied"] += 1
        else:
            bucket["free"] += 1
    site = {"free": 0, "occupied": 0, "unknown": 0, "total": 0}
    for level, b in per_level.items():
        client.publish(f"{PREFIX}/parking/{SITE}/{level}/summary", json.dumps(b), qos=1, retain=True)
        for k in site:
            site[k] += b[k]
    client.publish(f"{PREFIX}/parking/{SITE}/summary", json.dumps(site), qos=1, retain=True)

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

def on_message(client, userdata, msg):
    parts = msg.topic.split("/")
    level, bay = parts[-3], parts[-2]
    try:
        data = json.loads(msg.payload)
        bays[(level, bay)] = {"occupied": bool(data["occupied"]), "ts": float(data.get("ts", time.time()))}
    except (ValueError, KeyError):
        return
    publish_summaries(client)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="parking-agg-p3v6z8")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()

Simula unas cuantas plazas desde el terminal:

P=connectmq/demo/p3v6z8/parking/central
mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-p3v6z8 -r -q 1 -t $P/l1/b001/state -m "{\"occupied\":true,\"ts\":$(date +%s)}"
mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-p3v6z8 -r -q 1 -t $P/l1/b002/state -m "{\"occupied\":false,\"ts\":$(date +%s)}"
mosquitto_sub -h broker.connectmq.com -p 1883 -i view-p3v6z8 -t "$P/+/summary" -t "$P/summary" -v

Ten en cuenta que el prefijo de demostración añade niveles: el topic de estado de plaza anterior tiene ocho niveles de profundidad, el máximo que permite el servidor público. En un broker privado eliminarías el prefijo y empezarías en parking/.

En un despliegue grande, publicar todos los resúmenes en cada cambio es un desperdicio. Agrupa las actualizaciones cada uno o dos segundos y, si un agregador no basta, las suscripciones compartidas de MQTT 5 en un plan de pago permiten que varias instancias se repartan la carga.

El mapa de disponibilidad en vivo

El navegador se conecta por WebSocket seguro y se suscribe solo a los resúmenes, o a los estados de plaza para una vista detallada de una planta. Con MQTT.js:

import mqtt from "mqtt";

const PREFIX = "connectmq/demo/p3v6z8/parking/central";
const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
  clientId: "parking-map-" + Math.random().toString(16).slice(2, 8),
  protocolVersion: 5,
});

client.on("connect", () => {
  client.subscribe(`${PREFIX}/+/summary`, { qos: 1 });
  client.subscribe(`${PREFIX}/l1/+/state`, { qos: 0 });
});

client.on("message", (topic, payload) => {
  const data = JSON.parse(payload.toString());
  const parts = topic.split("/");
  if (topic.endsWith("/summary")) {
    const level = parts[parts.length - 2];
    const el = document.querySelector(`[data-level="${level}"] .free`);
    if (el) el.textContent = `${data.free} free of ${data.total}`;
  } else {
    const bay = parts[parts.length - 2];
    const cell = document.querySelector(`[data-bay="${bay}"]`);
    if (cell) cell.className = data.occupied ? "bay occupied" : "bay free";
  }
});

En una librería de mapas como Leaflet, el mismo manejador recolorearía un marcador por emplazamiento. Como los resúmenes están retenidos, el mapa pinta la situación actual en el instante en que carga la página. Nuestra guía de MQTT sobre WebSocket cubre los detalles de conexión desde el navegador y la gestión de credenciales, algo importante: una página web pública nunca debe incrustar credenciales capaces de publicar en los topics de plaza.

Lista de comprobación del despliegue

  1. Elige sensores según el entorno: discos en exterior, ultrasónicos en interior, cámaras donde las normas de privacidad lo permitan.
  2. Puentea las redes LoRaWAN o cableadas mediante gateways para mantener bajo el número de conexiones.
  3. Retén los estados de plaza y los resúmenes; incluye marcas de tiempo.
  4. Trata los sensores silenciosos como desconocidos y genera alertas por batería baja.
  5. Nunca entregues credenciales con permiso de publicación a clientes de mapa públicos; sirve los resúmenes a través de tu propio back end.
  6. Usa TLS en el puerto 8883 para los gateways y en el 8084 para los navegadores.
  7. Registra los cambios de estado en una base de datos con un suscriptor independiente para la analítica de ocupación.

Errores habituales en despliegues de aparcamiento

Interferencias de plazas contiguas. Una camioneta o un vehículo grande puede alterar el magnetómetro de la plaza de al lado. Calibra los sensores tras la instalación y prioriza unidades combinadas de magnetómetro y radar en distribuciones estrechas.

Ocupación fantasma. La nieve, el agua estancada o un objeto metálico caído pueden hacer que una plaza parezca ocupada durante días. Marca las plazas que no han cambiado de estado durante un tiempo inusualmente largo y revísalas.

Deriva del reloj. Si las marcas de tiempo provienen de los sensores, un reloj que deriva hace que los datos recientes parezcan obsoletos. Deja que el gateway o el servidor de red sellen los mensajes al llegar.

Exceso de publicación de resúmenes. Que cientos de paneles y apps reciban un resumen con cada cambio de plaza desperdicia ancho de banda. Limita la frecuencia de los resúmenes y publica solo cuando las cifras cambien realmente.

Escalar más allá de un único aparcamiento

Una vez que varios emplazamientos publican bajo parking/<site>/..., por ejemplo los estacionamientos de un centro comercial en Bogotá o de un casco histórico en Valencia, un panel de guiado a escala de ciudad se suscribe a parking/+/summary y a nada más. Es el mismo patrón de mensajería que se usa en la arquitectura IoT de ciudad inteligente más amplia, donde aparcamiento, alumbrado y calidad del aire comparten un broker pero permanecen en subárboles separados. La logística sensible a la temperatura usa un patrón de flota similar, como se describe en monitorización de la cadena de frío.

Gestionar el broker por tu cuenta implica parches, certificados y monitorización para un sistema del que los conductores dependen a diario. Un broker MQTT gestionado como ConnectMQ se encarga de TLS, los endpoints WebSocket y la gestión de conexiones, mientras que el explorador de topics en vivo del portal te permite ver cómo llegan los estados de plaza. Si estás comparando modelos de alojamiento, nuestra visión general del enfoque de broker MQTT en la nube te ayudará, y la guía de automatización IoT reúne proyectos relacionados.

Empieza tu piloto de aparcamiento inteligente en ConnectMQ

Pon en marcha un piloto en una planta con un puñado de sensores y un gateway, publica en ConnectMQ y lleva el mapa en vivo a una pantalla de pruebas. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, y pasa a un plan de pago o Dedicated cuando crezca el número de plazas.

Preguntas frecuentes

¿Cuántas conexiones MQTT necesita un sistema de aparcamiento inteligente?

Normalmente muchas menos que el número de plazas. Los servidores de red LoRaWAN y los gateways interiores publican en nombre de muchos sensores a través de una única conexión, de modo que el número de conexiones escala con los gateways y las apps, no con las plazas.

¿Qué sensor es mejor para plazas de aparcamiento en exterior?

Los discos magnetómetro alimentados por batería, idealmente combinados con radar para reducir las lecturas falsas, son la opción habitual en exterior porque resisten la intemperie y duran años con una batería.

¿Cómo evito que se haga un uso indebido del mapa público?

Haz pasar los datos por tu propio back end, por ejemplo un pequeño servidor que se suscribe a los resúmenes y los envía a la página. Nunca incrustes en una página pública credenciales que puedan publicar en los topics de plaza o de resumen.

¿Puedo usar cámaras en lugar de sensores de plaza?

Sí. Un dispositivo edge ejecuta la detección y publica solo la ocupación por plaza, nunca vídeo, lo que mantiene bajo el ancho de banda y facilita el cumplimiento de la normativa de privacidad.

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.