
ha-mqtt-autodiscovery
by dawiddutoit
Collection of Claude Code skills, agents, and plugins
SKILL.md
name: ha-mqtt-autodiscovery description: "Publish MQTT auto-discovery configurations to automatically register IoT devices and sensors with Home Assistant. Use when integrating custom IoT devices, creating MQTT sensors, or building ESP32/ESP8266/Pi-based devices that should auto-register with Home Assistant. Covers discovery payloads, device classes, state classes, and resilient MQTT patterns."
Home Assistant MQTT Auto-Discovery
Automatically register IoT devices and sensors with Home Assistant by publishing MQTT discovery configurations.
Overview
MQTT auto-discovery allows devices to automatically appear in Home Assistant without manual YAML configuration. Publish a JSON config to the discovery topic and HA creates the entity automatically.
Discovery Topic Pattern:
homeassistant/{component}/{node_id}/{object_id}/config
State Topic Pattern:
{node_id}/{sensor_type}/state
Quick Start
import json
import paho.mqtt.client as mqtt
# Connect to MQTT broker
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect("192.168.68.123", 1883, 60)
# Publish discovery config
discovery_topic = "homeassistant/sensor/enviroplus_temperature/config"
config = {
"name": "Enviro+ Temperature",
"unique_id": "enviroplus_temperature",
"state_topic": "enviroplus/temperature/state",
"device_class": "temperature",
"unit_of_measurement": "°C",
"state_class": "measurement",
"device": {
"identifiers": ["enviroplus"],
"name": "Enviro+ Environmental Sensor",
"manufacturer": "Pimoroni",
"model": "Enviro+",
},
}
client.publish(discovery_topic, json.dumps(config), qos=1, retain=True)
# Publish sensor value
client.publish("enviroplus/temperature/state", "23.5", qos=1)
After publishing, the sensor sensor.enviro_temperature appears in Home Assistant automatically.
Discovery Payload Structure
Required Fields
{
"name": "Friendly Name", # Display name in HA
"unique_id": "unique_identifier", # Must be globally unique
"state_topic": "device/sensor/state", # Topic where values are published
}
Recommended Fields
{
"device_class": "temperature", # Semantic type (enables icons, units)
"unit_of_measurement": "°C", # Unit for display
"state_class": "measurement", # Enables long-term statistics
"icon": "mdi:thermometer", # Custom icon (optional)
}
Device Information
Group sensors under a single device:
{
"device": {
"identifiers": ["device_unique_id"], # List of identifiers
"name": "Device Name",
"manufacturer": "Manufacturer",
"model": "Model Name",
"sw_version": "1.0.0",
}
}
Common Sensor Types
See references/sensor_configs.md for complete sensor configuration templates.
Environmental Sensors
# Temperature
{
"device_class": "temperature",
"unit_of_measurement": "°C",
"state_class": "measurement",
}
# Humidity
{
"device_class": "humidity",
"unit_of_measurement": "%",
"state_class": "measurement",
}
# Pressure
{
"device_class": "atmospheric_pressure",
"unit_of_measurement": "hPa",
"state_class": "measurement",
}
# Light
{
"device_class": "illuminance",
"unit_of_measurement": "lx",
"state_class": "measurement",
}
Air Quality Sensors
# PM2.5
{
"device_class": "pm25",
"unit_of_measurement": "µg/m³",
"state_class": "measurement",
}
# PM10
{
"device_class": "pm10",
"unit_of_measurement": "µg/m³",
"state_class": "measurement",
}
Energy Monitoring
# Power
{
"device_class": "power",
"unit_of_measurement": "W",
"state_class": "measurement",
}
# Energy (cumulative)
{
"device_class": "energy",
"unit_of_measurement": "kWh",
"state_class": "total_increasing",
}
State Classes
| State Class | Purpose | Resets? | Statistics? |
|---|---|---|---|
measurement | Current value (temp, power) | No | Yes (mean, min, max) |
total | Monotonically increasing (odometer) | No | Yes (rate of change) |
total_increasing | Cumulative with resets (daily energy) | Yes | Yes (rate of change) |
Complete Example: Multi-Sensor Device
import json
import paho.mqtt.client as mqtt
DEVICE_ID = "enviroplus"
BROKER = "192.168.68.123"
# Sensor definitions
SENSORS = {
"temperature": {
"name": "Temperature",
"device_class": "temperature",
"unit_of_measurement": "°C",
"state_class": "measurement",
},
"humidity": {
"name": "Humidity",
"device_class": "humidity",
"unit_of_measurement": "%",
"state_class": "measurement",
},
"pressure": {
"name": "Pressure",
"device_class": "atmospheric_pressure",
"unit_of_measurement": "hPa",
"state_class": "measurement",
},
"pm2_5": {
"name": "PM2.5",
"device_class": "pm25",
"unit_of_measurement": "µg/m³",
"state_class": "measurement",
},
}
def publish_discovery(client):
"""Publish discovery configs for all sensors."""
for sensor_key, config in SENSORS.items():
unique_id = f"{DEVICE_ID}_{sensor_key}"
discovery_topic = f"homeassistant/sensor/{unique_id}/config"
payload = {
"name": config["name"],
"unique_id": unique_id,
"state_topic": f"{DEVICE_ID}/{sensor_key}/state",
"device_class": config["device_class"],
"unit_of_measurement": config["unit_of_measurement"],
"state_class": config["state_class"],
"device": {
"identifiers": [DEVICE_ID],
"name": "Enviro+ Sensor",
"manufacturer": "Pimoroni",
"model": "Enviro+",
},
}
client.publish(discovery_topic, json.dumps(payload), qos=1, retain=True)
print(f"Published discovery for {config['name']}")
# Connect and publish
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect(BROKER, 1883, 60)
publish_discovery(client)
# Publish sample values
client.publish(f"{DEVICE_ID}/temperature/state", "23.5", qos=1)
client.publish(f"{DEVICE_ID}/humidity/state", "65", qos=1)
client.publish(f"{DEVICE_ID}/pressure/state", "1013.25", qos=1)
client.publish(f"{DEVICE_ID}/pm2_5/state", "12.3", qos=1)
client.disconnect()
Resilient MQTT Pattern
For production devices, use auto-reconnect and offline queuing:
from collections import deque
import paho.mqtt.client as mqtt
class ResilientMQTT:
"""MQTT client with offline queuing and auto-reconnect."""
def __init__(self, broker: str, port: int = 1883):
self.broker = broker
self.port = port
self.connected = False
self._message_queue = deque(maxlen=1000)
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
self.client.on_connect = self._on_connect
self.client.on_disconnect = self._on_disconnect
def connect(self):
"""Connect with auto-reconnect enabled."""
self.client.reconnect_delay_set(min_delay=1, max_delay=60)
self.client.connect_async(self.broker, self.port, keepalive=60)
self.client.loop_start()
def _on_connect(self, client, userdata, flags, reason_code, properties):
if reason_code == 0:
self.connected = True
self._publish_discovery() # Re-publish on reconnect
self._flush_queue()
def _on_disconnect(self, client, userdata, flags, reason_code, properties):
self.connected = False
def publish(self, topic: str, payload: str, qos: int = 1):
"""Publish with offline queuing."""
if self.connected:
self.client.publish(topic, payload, qos=qos)
else:
self._message_queue.append({"topic": topic, "payload": payload})
def _flush_queue(self):
"""Publish queued messages on reconnect."""
while self._message_queue and self.connected:
msg = self._message_queue.popleft()
self.client.publish(msg["topic"], msg["payload"], qos=1)
def _publish_discovery(self):
"""Re-publish discovery configs on reconnect."""
# Implement your discovery publishing logic here
pass
Workflow
- Define sensors - Create sensor configurations with device classes and units
- Publish discovery - Send discovery payloads to
homeassistant/sensor/{unique_id}/config - Verify in HA - Check that entities appear in Home Assistant
- Publish values - Send sensor readings to state topics
- Monitor - Ensure reliable delivery with QoS 1 and retained messages
Best Practices
- Use retain=True for discovery messages so HA gets them after restart
- Use QoS 1 for reliable delivery
- Re-publish discovery on reconnect in case HA restarted
- Group related sensors under a single device using
device.identifiers - Choose appropriate state_class to enable statistics and history
- Use standard device classes when possible for proper icons and units
Testing
# Subscribe to all discovery messages
mosquitto_sub -h 192.168.68.123 -t "homeassistant/#" -v
# Publish test discovery
mosquitto_pub -h 192.168.68.123 \
-t "homeassistant/sensor/test_temp/config" \
-m '{"name":"Test Temp","unique_id":"test_temp","state_topic":"test/temp/state","device_class":"temperature","unit_of_measurement":"°C","state_class":"measurement"}' \
-r
# Publish test value
mosquitto_pub -h 192.168.68.123 -t "test/temp/state" -m "25.5"
Removing Entities
To remove auto-discovered entities, publish an empty payload with retain:
mosquitto_pub -h 192.168.68.123 \
-t "homeassistant/sensor/test_temp/config" \
-n -r
Resources
- references/sensor_configs.md - Complete sensor configuration templates
- scripts/mqtt_discovery.py - Multi-sensor discovery publisher
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon