MQTT is the backbone protocol of professional home automation systems. If you are building a smart home with multiple ESP32 devices — switches, sensors, cameras, and controllers — MQTT provides the reliable, efficient communication layer that ties everything together. Combined with Mosquitto as the message broker and Home Assistant as the automation platform, MQTT gives you a local-first, privacy-respecting smart home that works even when the internet is down.
This comprehensive guide takes you from zero to a fully functional MQTT-based home automation system, with practical ESP32 code examples and Home Assistant configuration.
What Is MQTT and Why Use It?
MQTT (Message Queuing Telemetry Transport) is a lightweight publish/subscribe messaging protocol designed for IoT devices. Instead of each device talking directly to every other device (which becomes unmanageable with more than a few devices), all devices communicate through a central broker.
How It Works
- Publish: An ESP32 temperature sensor publishes data to a topic like
home/bedroom/temperature - Subscribe: Home Assistant subscribes to
home/bedroom/temperatureand receives the data - Broker: Mosquitto sits in the middle, receiving published messages and forwarding them to all subscribers
Why MQTT Over HTTP/WebSockets?
- Minimal overhead: MQTT messages are tiny (2 bytes header minimum) compared to HTTP
- Persistent connections: Devices maintain a single connection to the broker instead of opening new connections for each message
- QoS levels: Guaranteed message delivery with QoS 1 and 2
- Last Will: Automatic notification when a device goes offline
- Retained messages: New subscribers immediately get the last known state
- Scales effortlessly: Adding a new device requires zero changes to existing devices
System Architecture
A typical MQTT-based smart home in India looks like this:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ ESP32 #1 │ │ Mosquitto │ │ Home │
│ Bedroom │───→│ Broker │←───│ Assistant │
│ Light+Temp │←───│ (RPi/PC) │───→│ Dashboard │
└─────────────┘ └──────────────┘ └─────────────┘
↕
┌─────────────┐ ┌──────────────┐
│ ESP32 #2 │ │ ESP32 #3 │
│ Living Room │ │ Water Tank │
│ Fan+Humid │ │ Level Sensor│
└─────────────┘ └──────────────┘
All ESP32 devices connect to the Mosquitto broker. Home Assistant also connects to the same broker. Commands flow from Home Assistant → Broker → ESP32, and sensor data flows from ESP32 → Broker → Home Assistant.
Setting Up Mosquitto Broker
Mosquitto is the most popular MQTT broker for home automation. Install it on a Raspberry Pi, old laptop, or any always-on computer on your home network.
Installation on Raspberry Pi / Ubuntu
sudo apt update
sudo apt install mosquitto mosquitto-clients
# Create a password file for authentication
sudo mosquitto_passwd -c /etc/mosquitto/passwd homeuser
# Enter password when prompted
# Configure Mosquitto
sudo nano /etc/mosquitto/conf.d/default.conf
Add to the configuration file:
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
# Restart Mosquitto
sudo systemctl restart mosquitto
sudo systemctl enable mosquitto
# Test with command-line client
# Terminal 1 (subscribe):
mosquitto_sub -h localhost -u homeuser -P yourpassword -t "test/topic"
# Terminal 2 (publish):
mosquitto_pub -h localhost -u homeuser -P yourpassword -t "test/topic" -m "Hello MQTT!"
ESP32 Publishing Sensor Data
This ESP32 reads a DHT22 sensor and publishes temperature and humidity to MQTT topics every 30 seconds:
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
// WiFi
const char* ssid = "Your_WiFi";
const char* password = "Your_Password";
// MQTT Broker
const char* mqtt_server = "192.168.1.100"; // Your broker IP
const int mqtt_port = 1883;
const char* mqtt_user = "homeuser";
const char* mqtt_password = "yourpassword";
// Topics
const char* topic_temp = "home/bedroom/temperature";
const char* topic_humid = "home/bedroom/humidity";
const char* topic_status = "home/bedroom/status";
const char* topic_cmd = "home/bedroom/relay/set";
const char* topic_relay_state = "home/bedroom/relay/state";
// Hardware
#define DHT_PIN 4
#define RELAY_PIN 26
DHT dht(DHT_PIN, DHT22);
WiFiClient espClient;
PubSubClient mqtt(espClient);
unsigned long lastPublish = 0;
#define PUBLISH_INTERVAL 30000 // 30 seconds
void connectWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("
WiFi connected: " + WiFi.localIP().toString());
}
void connectMQTT() {
while (!mqtt.connected()) {
Serial.print("Connecting MQTT...");
// Client ID should be unique
String clientId = "ESP32-Bedroom-" + String(random(0xffff), HEX);
// Last Will message - sent automatically if device disconnects
if (mqtt.connect(clientId.c_str(), mqtt_user, mqtt_password,
topic_status, 1, true, "offline")) {
Serial.println("connected!");
// Publish online status (retained)
mqtt.publish(topic_status, "online", true);
// Subscribe to command topic
mqtt.subscribe(topic_cmd);
} else {
Serial.print("failed, rc=");
Serial.println(mqtt.state());
delay(5000);
}
}
}
// Called when a message arrives on subscribed topics
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i PUBLISH_INTERVAL) {
publishSensorData();
lastPublish = millis();
}
}
ESP32 Subscribing to Commands
The code above already includes subscription handling in the mqttCallback function. When Home Assistant publishes “ON” or “OFF” to home/bedroom/relay/set, the ESP32 receives the message and controls the relay accordingly.
MQTT Topic Structure Best Practices
home/
├── bedroom/
│ ├── temperature (sensor → HA)
│ ├── humidity (sensor → HA)
│ ├── relay/
│ │ ├── set (HA → device, command)
│ │ └── state (device → HA, current state)
│ └── status (online/offline)
├── living_room/
│ ├── temperature
│ ├── fan/
│ │ ├── set
│ │ └── state
│ └── status
└── water_tank/
├── level
├── pump/
│ ├── set
│ └── state
└── status
Home Assistant Integration
Home Assistant natively supports MQTT. Add your ESP32 devices to the configuration.yaml file:
# configuration.yaml
mqtt:
sensor:
- name: "Bedroom Temperature"
state_topic: "home/bedroom/temperature"
unit_of_measurement: "°C"
device_class: temperature
- name: "Bedroom Humidity"
state_topic: "home/bedroom/humidity"
unit_of_measurement: "%"
device_class: humidity
switch:
- name: "Bedroom Light"
state_topic: "home/bedroom/relay/state"
command_topic: "home/bedroom/relay/set"
payload_on: "ON"
payload_off: "OFF"
state_on: "ON"
state_off: "OFF"
binary_sensor:
- name: "Bedroom Controller"
state_topic: "home/bedroom/status"
payload_on: "online"
payload_off: "offline"
device_class: connectivity
After restarting Home Assistant, your ESP32 devices appear on the dashboard with real-time data and switch controls.
Creating Powerful Automations
Home Assistant automations use MQTT sensor data to trigger actions across your entire home:
Example 1: Temperature-Based Fan Control
automation:
- alias: "Turn on fan when hot"
trigger:
platform: numeric_state
entity_id: sensor.bedroom_temperature
above: 30
action:
service: switch.turn_on
entity_id: switch.bedroom_fan
- alias: "Turn off fan when cool"
trigger:
platform: numeric_state
entity_id: sensor.bedroom_temperature
below: 25
action:
service: switch.turn_off
entity_id: switch.bedroom_fan
Example 2: Sunset-Based Lighting
- alias: "Porch light at sunset"
trigger:
platform: sun
event: sunset
offset: "+00:15:00"
action:
service: switch.turn_on
entity_id: switch.porch_light
- alias: "Porch light off at night"
trigger:
platform: time
at: "23:00:00"
action:
service: switch.turn_off
entity_id: switch.porch_light
Example 3: Presence-Based All-Off
- alias: "All off when leaving"
trigger:
platform: state
entity_id: device_tracker.jayesh_phone
to: "not_home"
for: "00:05:00"
action:
- service: switch.turn_off
entity_id:
- switch.bedroom_light
- switch.living_room_light
- switch.kitchen_light
- service: notify.mobile_app
data:
message: "All lights turned off. You left home."
Frequently Asked Questions
What happens if the Mosquitto broker goes down?
ESP32 devices lose their MQTT connection and cannot receive commands from Home Assistant. However, physical buttons (if implemented) continue to work. The PubSubClient library automatically attempts to reconnect. When the broker comes back, all devices reconnect within seconds and the Last Will messages update their status.
How many devices can Mosquitto handle?
A Raspberry Pi 4 running Mosquitto can easily handle 100+ connected devices with thousands of messages per minute. For a typical home with 10–20 ESP32 nodes, a Raspberry Pi 3 is more than sufficient.
Is MQTT secure?
Basic MQTT uses plaintext. For security: (1) Use username/password authentication (as shown above), (2) Restrict Mosquitto to listen only on the local network interface, (3) For internet access, use MQTT over TLS (port 8883). For a home network behind a router, username/password is usually sufficient.
Can I use MQTT without Home Assistant?
Absolutely. You can build a complete MQTT system with just Mosquitto and ESP32 devices — each device can subscribe to commands from other devices directly. Home Assistant adds a nice dashboard and automation engine, but is not required.
What is the difference between QoS 0, 1, and 2?
QoS 0: Fire and forget (fastest, may lose messages). QoS 1: At least once delivery (recommended for most home automation). QoS 2: Exactly once delivery (slowest, rarely needed). Use QoS 1 for switch commands and QoS 0 for frequent sensor readings.
Conclusion
MQTT is the protocol that transforms a collection of individual smart devices into a cohesive, responsive smart home system. Its lightweight design is perfect for ESP32 microcontrollers, and its publish/subscribe model makes adding new devices trivially easy. Combined with Mosquitto and Home Assistant, you get a professional-grade automation platform that runs entirely on your local network — no cloud, no subscription fees, no privacy concerns.
Build your MQTT-powered smart home with components from Zbotic.in. Get ESP32 boards, relay modules, and sensors — everything you need for a complete home automation ecosystem, delivered across India.
Add comment