Por qué MQTT vale la pena en una casa con Raspberry Pi

Cuando tu smart home empieza a sumar varios sensores ESP32, un par de enchufes Shelly, lámparas Zigbee y un Home Assistant en el Raspberry Pi, el cableado lógico entre todos esos equipos se transforma en una madeja imposible de mantener con HTTP puro. MQTT resuelve ese problema con un modelo simple: cada dispositivo habla con un único broker central y nadie necesita conocer al resto.

En esta guía vas a montar Mosquitto. el broker MQTT más usado del mundo. sobre Raspberry Pi OS, vas a aprender a observar el tráfico con MQTT Explorer y vas a publicar mediciones reales desde un ESP32. Al final vas a tener un broker autenticado, un cliente gráfico para depurar, y un sketch funcional con sensor BME280 listo para copiar y modificar.

Cómo funciona el modelo Publish/Subscribe

MQTT (Message Queuing Telemetry Transport) reemplaza la pregunta respuesta de HTTP por un esquema de tablón de anuncios: alguien escribe en un topic, otros leen ese topic. El broker es solo el correo.

Esquema de comunicación MQTT en smart home con Raspberry Pi como broker Mosquitto

Tres roles que conviene tener claros antes de instalar nada:

  • Publisher: cualquier cosa que produzca datos. un ESP32 con sensor, un Shelly, un script en Python. y los empuje a un topic.
  • Broker: el intermediario que recibe todos los mensajes y los re distribuye a quienes hayan suscrito al topic. Acá vive Mosquitto.
  • Subscriber: cualquier consumidor (Home Assistant, Node RED, una pantalla con un ESP32, otro script) que esté escuchando ese topic.

La gran diferencia con HTTP es que publishers y subscribers no se conocen entre sí. Tu sensor de temperatura no necesita saber que existe Home Assistant, y Home Assistant no necesita una IP fija del sensor. Ambos hablan con el broker y listo. Eso es lo que permite agregar y sacar dispositivos sin tocar el resto del sistema.

Topics: la jerarquía de direcciones

Los topics se parecen a rutas de archivos. La convención es de lo general a lo específico:

Código
casa/living/temperatura
casa/cocina/movimiento
patio/riego/estado

A la hora de suscribirte podés usar comodines: # engancha todo lo que cuelga de una rama, y + reemplaza exactamente un nivel. Por ejemplo, casa/+/temperatura te entrega la temperatura de todas las piezas sin tener que listarlas una por una.

QoS. Calidad de servicio

QoS Garantía Cuándo conviene
0. At most once Se envía una sola vez, sin confirmación Telemetría frecuente donde perder un dato no duele (temperatura cada 30 s)
1. At least once Entrega garantizada, pueden llegar duplicados Estados de switches, alarmas
2. Exactly once Exactamente una vez, sin duplicados Comandos críticos (apagar bomba, abrir portón)

Para la mayoría de proyectos domésticos, QoS 1 es el punto dulce: garantiza entrega sin la sobrecarga del handshake doble del QoS 2.

Instalando Mosquitto en Raspberry Pi OS

Mosquitto está empaquetado en los repositorios oficiales de Raspberry Pi OS, así que la instalación es de manual. Antes de empezar, asegúrate de que tu Pi esté con el sistema actualizado.

Atajo para usuarios de Home Assistant

Si ya tienes Home Assistant corriendo en el Raspberry Pi (no Core, sino HAOS o Supervised), salta la consola: instala el add on Mosquitto broker desde Ajustes → Add ons → Add on Store. Te queda configurado y enganchado a la integración MQTT sin tocar terminal. La instalación nativa que viene abajo es para todos los demás casos: Raspberry Pi OS limpio, broker compartido entre varios servicios, o si querés mantener Mosquitto independiente de HA para que un reinicio de HA no se lleve puesto el broker.

Instalación nativa paso a paso

Actualiza los paquetes y luego instala el broker junto con las herramientas de consola:

Código
sudo apt update
sudo apt install mosquitto mosquitto-clients -y

El paquete mosquitto-clients trae mosquitto_pub y mosquitto_sub, dos utilidades chicas que vamos a usar enseguida para probar el broker desde la misma terminal.

Habilita el servicio para que arranque solo en cada boot y láncalo ahora:

Código
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

Verifica que esté vivo:

Código
sudo systemctl status mosquitto

Si ves active (running) en verde, el broker ya está escuchando en el puerto 1883.

Activar autenticación (no opcional en una casa)

Por defecto Mosquitto acepta conexiones anónimas. En una red doméstica con visitas, IoT chino de dudosa procedencia y vecinos curiosos, eso es un riesgo innecesario. Crea un usuario con contraseña:

Código
sudo mosquitto_passwd -c /etc/mosquitto/passwd mqttuser

El comando te va a pedir la contraseña dos veces. Después abre el archivo de configuración local:

Código
sudo nano /etc/mosquitto/conf.d/default.conf

Y pega lo siguiente:

Código
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd

Guarda con Ctrl+O, sale con Ctrl+X, y reinicia el servicio para aplicar:

Código
sudo systemctl restart mosquitto

Desde este momento, cualquier cliente que se quiera conectar tiene que presentar usuario y contraseña. Si un dispositivo tuyo deja de funcionar después de este paso es porque le quedó la config anónima vieja. actualízalo y listo.

Primer test con la consola

Antes de meter hardware, vale la pena confirmar que el broker funciona usando solo Mosquitto contra sí mismo. Abre dos terminales en el Pi (o dos sesiones SSH).

Terminal A (suscriptor). se queda esperando mensajes del topic test/sensor:

Código
mosquitto_sub -h localhost -t "test/sensor" -u mqttuser -P tu_password

Terminal B (publicador). manda un mensaje:

Código
mosquitto_pub -h localhost -t "test/sensor" -m "Temperatura: 22.5°C" -u mqttuser -P tu_password

En la terminal A debería aparecer Temperatura: 22.5°C al instante. Si lo ves, el broker está funcionando y la autenticación pasó. Si no aparece nada, revisa que el password sea el mismo en los dos comandos y que el firewall del Pi no esté bloqueando 1883.

MQTT Explorer: ver el tráfico en vivo

La consola sirve para debug rápido pero no escala cuando empezás a tener decenas de topics. MQTT Explorer es gratuito (Windows/macOS/Linux), liviano, y te muestra todos los topics como un árbol vivo que se actualiza solo. Es la herramienta que más vas a usar a la hora de depurar.

Descarga e instalación

Descarga el instalador desde mqtt explorer.com y lo corres en tu PC, no en el Pi. Para Linux hay AppImage (no requiere instalación) y para Windows/macOS hay instalador clásico.

Conexión al Raspberry Pi

Al abrirlo aparece un diálogo de conexión. Completa así:

Campo Valor
Host IP del Raspberry Pi en tu red (ej. 192.168.1.100)
Port 1883
Username mqttuser
Password el que pusiste con mosquitto_passwd

Configurando la conexión de MQTT Explorer al broker Mosquitto del Raspberry Pi

Click en Connect y vas a ver el árbol de topics activos. Cada vez que un cliente publica algo, el nodo aparece o se actualiza con valor y timestamp. También podés publicar manualmente a cualquier topic desde la pestaña Publish, lo que sirve para simular sensores o forzar estados durante el debug.

Vista principal de MQTT Explorer mostrando topics activos en el broker

Caso práctico: ESP32 + BME280 publicando al broker

Hasta acá tenés el broker, autenticación y un cliente gráfico. Ahora vamos a meter un sensor real. En vez del DHT22 que aparece en muchos tutoriales, voy a usar el BME280 porque mide temperatura, humedad y presión barométrica en el mismo módulo I2C, se vende en MechatronicStore (link al final), y es más preciso. Si tienes un DHT22, el sketch cambia solo la sección del sensor; la parte MQTT queda igual.

Conexión BME280 al ESP32

El BME280 habla I2C, así que son solo 4 cables:

BME280 ESP32 DevKit
VCC 3V3
GND GND
SDA GPIO 21
SCL GPIO 22

Sketch para Arduino IDE

Instala las librerías PubSubClient (Nick O'Leary) y Adafruit BME280 desde el gestor de librerías. Luego carga este sketch reemplazando SSID, password y la IP del broker:

Código
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BME280.h>

const char* ssid         = "TU_WIFI";
const char* password     = "TU_PASSWORD_WIFI";
const char* mqttServer   = "192.168.1.100";   // IP del Raspberry Pi
const int   mqttPort     = 1883;
const char* mqttUser     = "mqttuser";
const char* mqttPassword = "tu_password_mqtt";

Adafruit_BME280 bme;
WiFiClient espClient;
PubSubClient client(espClient);

void connectWifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); }
}

void connectMqtt() {
  while (!client.connected()) {
    if (client.connect("esp32-bme280", mqttUser, mqttPassword)) break;
    delay(2000);
  }
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  bme.begin(0x76);                  // dirección I2C habitual del BME280
  connectWifi();
  client.setServer(mqttServer, mqttPort);
}

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

  float temp     = bme.readTemperature();
  float hum      = bme.readHumidity();
  float pressure = bme.readPressure() / 100.0F;   // hPa

  client.publish("casa/living/temperatura", String(temp, 2).c_str(),     true);
  client.publish("casa/living/humedad",     String(hum, 1).c_str(),      true);
  client.publish("casa/living/presion",     String(pressure, 1).c_str(), true);

  delay(30000);
}

Tres detalles que el tutorial original no menciona y que valen oro:

  1. El tercer argumento true en client.publish activa el flag retain: el broker recuerda el último valor y se lo entrega a cualquier subscriber que se conecte después. Sin retain, si Home Assistant arranca después que el ESP32 publica, no ve nada hasta el próximo ciclo (30 segundos perdidos).
  2. Llamar client.loop() en cada iteración es obligatorio: ahí ocurre la mantención del socket TCP y el procesamiento de mensajes entrantes. Olvidarlo causa desconexiones cada 60-90 segundos.
  3. El BME280 tiene dos direcciones I2C posibles: 0x76 (por defecto) y 0x77 (si el pin SDO está a VCC). Si bme.begin(0x76) falla, probá 0x77.

Integración con Home Assistant

En configuration.yaml de Home Assistant agregas un sensor MQTT que se suscribe a los topics que publica el ESP32:

Código
mqtt:
  sensor:
    - name: "Living Temperatura"
      state_topic: "casa/living/temperatura"
      unit_of_measurement: "°C"
      device_class: temperature
    - name: "Living Humedad"
      state_topic: "casa/living/humedad"
      unit_of_measurement: "%"
      device_class: humidity
    - name: "Living Presion"
      state_topic: "casa/living/presion"
      unit_of_measurement: "hPa"
      device_class: pressure

Reinicia Home Assistant y las tres lecturas aparecen como entidades disponibles para dashboards, automatizaciones y gráficos históricos.

Variantes y mejoras

Tres extensiones concretas para llevar el proyecto más lejos:

  • Alertas a Telegram con Node RED: con Node RED instalado en el mismo Pi, un flow de tres nodos (mqtt infunction con if (temp > 28) return msg;telegram sender) te avisa al teléfono cada vez que la temperatura supera el umbral. La ventaja sobre las notificaciones nativas de HA es que el flow puede combinar varios topics (alerta solo si humedad además es alta) sin escribir YAML.
  • Dashboard con node red-dashboard: agregando los nodos chart y gauge al mismo flow, exponés un panel web en http://ip-del-pi:1880/ui con gráficos en tiempo real. Útil cuando querés ver datos sin abrir Home Assistant.
  • Backup automático de mediciones a InfluxDB: instalando InfluxDB en el Pi y agregando el nodo node-red-contrib-influxdb, las lecturas quedan en una serie temporal que después podés graficar con Grafana. Útil si querés ver tendencias de meses, no solo el estado actual.

Personalización para Chile

Todo el hardware del proyecto está disponible en MechatronicStore con stock local. Estos son los componentes verificados:

  • Raspberry Pi 5 4GB RAM (SKU X5-14). $107.990 CLP. Sirve perfecto como host de Mosquitto + Home Assistant + Node RED en paralelo. Si solo necesitas el broker, un Pi 4 o incluso un Pi Zero 2 W es suficiente.
  • Placa ESP32 DevKit con WiFi (SKU X2-10V2). $7.990 CLP. La variante WROOM-32 es la que mejor anda con el sketch de arriba.
  • Sensor BME280 I2C (SKU GR1-10). $8.690 CLP. Tres mediciones en un módulo del tamaño de una uña, comunicación I2C de 4 cables, alimentación 3.3 V.
  • Fuente USB-C 5V 3A (SKU B-006). $3.990 CLP. La fuente oficial recomendada para alimentar el Raspberry Pi 5 sin throttling.
  • Tarjeta microSD 32GB (SKU B-450). $9.990 CLP. Para el sistema operativo del Raspberry Pi; 32 GB alcanzan de sobra para Raspberry Pi OS + Mosquitto + Home Assistant + flows de Node RED.
  • Cable USB-C a USB-A 1m (SKU B-101). $2.190 CLP. Para flashear el ESP32 desde tu PC.
  • Protoboard 830 puntos MB-102 (SKU C-302). $3.790 CLP. Para montar el BME280 sin soldar.
  • Cables Dupont macho macho (SKU C-417). $2.990 CLP. Los cuatro cables de conexión I2C.

Si en el tutorial original encuentras referencia al sensor DHT22 (Adafruit) o al Zigbee Sonoff Dongle, son componentes que actualmente no aparecen en el catálogo MechatronicStore con stock confirmado. para el DHT22, el BME280 listado arriba es funcionalmente superior (agrega presión, más preciso, mismo bus I2C). Para Zigbee, conviene revisar el catálogo en el momento de comprar.

Recursos

Versión chilena con componentes en stock local en MechatronicStore.