dawiddutoit/custom-claude

ha-mqtt-autodiscovery

Configures and publishes MQTT auto-discovery messages to automatically register IoT devices and sensors with Home Assistant, defining discovery payloads with device classes, state classes, units, and device grouping for multi-sensor devices. Use when integrating custom IoT devices, creating MQTT sensors, building ESP32/ESP8266/Pi-based devices that auto-register with HA, or implementing resilient MQTT patterns with offline queuing and auto-reconnect.

First seen Jan 26, 2026

Installation

$ npx skills add dawiddutoit/custom-claude --skill ha-mqtt-autodiscovery

Also in this package

Other skills from dawiddutoit/custom-claude · top by installs.

npx skills add dawiddutoit/custom-claude

Browse all from dawiddutoit/custom-claude

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 2
License MIT
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,151 B
  • docs SUMMARY.md 483 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 10 installs

SKILL.md

Works with MQTT brokers (Mosquitto), paho-mqtt Python library, and Home Assistant MQTT integration.

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

When to Use This Skill

Use this skill when you need to:

  • Automatically register custom IoT devices with Home Assistant via MQTT
  • Build ESP32/ESP8266/Raspberry Pi-based sensors that self-register
  • Create multi-sensor devices grouped under a single device entry
  • Implement resilient MQTT patterns with offline queuing and auto-reconnect
  • Configure proper device classes and state classes for long-term statistics
  • Avoid manual YAML configuration for frequently changing device deployments

Do NOT use when:

  • You can use existing Home Assistant integrations (prefer official integrations)
  • Building devices without MQTT broker infrastructure
  • You need real-time control with minimal latency (consider direct API instead)

Usage

Follow these steps to set up MQTT auto-discovery:

  1. Define sensor configurations with device classes and units
  2. Publish discovery payloads to discovery topics with retain=True
  3. Verify entities appear in Home Assistant
  4. Publish sensor values to state topics
  5. Implement resilient patterns with auto-reconnect and offline queuing

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/sensorconfigs.md](references/sensorconfigs.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

See references/sensor_configs.md for complete sensor configuration templates, best practices, testing commands, and entity removal procedures.

Resources

  • [references/sensorconfigs.md](references/sensorconfigs.md) - Complete sensor configuration templates
  • [scripts/mqttdiscovery.py](scripts/mqttdiscovery.py) - Multi-sensor discovery publisher