Publish Unraid server events to MQTT brokers for IoT integration and Home Assistant automation.
The Unraid Management Agent can publish system events to MQTT brokers in real-time, enabling:
- Home Assistant integration for smart home automation
- IoT dashboards like Node-RED
- Custom automation scripts
- Multi-server monitoring from a central MQTT broker
Edit /boot/config/plugins/unraid-management-agent/unraid-management-agent.cfg:
# Enable MQTT publishing
MQTT_ENABLED=true
# MQTT broker address (required)
MQTT_BROKER=tcp://192.168.1.100:1883
# Optional: Authentication
MQTT_USERNAME=unraid_agent
MQTT_PASSWORD=your_secure_password
# Optional: Topic prefix (default: unraid)
MQTT_TOPIC_PREFIX=homelab/unraid/etc/rc.d/rc.unraid-management-agent restartCheck logs for MQTT connection:
tail -f /var/log/unraid-management-agent.log | grep MQTTYou should see: MQTT client connected to tcp://...
The agent publishes to hierarchical topics under your configured prefix.
<prefix>/system # System metrics (CPU, RAM, temps)
<prefix>/array # Array status and capacity
<prefix>/disks # All disk information
<prefix>/shares # User share list
<prefix>/containers # Docker container status
<prefix>/vms # Virtual machine status
<prefix>/ups # UPS status (if configured)
<prefix>/gpu # GPU metrics (if available)
<prefix>/network # Network interface info
<prefix>/notifications # System notifications (full list + counts)
<prefix>/notifications/event # Per-notification event (fires once per new notification)
All messages are published as JSON payloads with QoS 1 (at least once delivery).
Topic: unraid/system
Payload:
{
"hostname": "Tower",
"version": "7.2.0",
"agent_version": "2025.11.0",
"uptime": 345600,
"cpu_usage": 15.3,
"cpu_temp": 45.5,
"cpu_model": "Intel Core i7-9700K",
"cpu_cores": 8,
"cpu_threads": 8,
"ram_used": 8589934592,
"ram_total": 34359738368,
"ram_usage": 25.0,
"swap_total_bytes": 8589934592,
"swap_used_bytes": 1073741824,
"swap_free_bytes": 7516192768,
"swap_usage_percent": 12.5,
"swappiness": 60,
"timestamp": "2025-01-20T10:30:00Z"
}Swap fields are parsed from
/proc/meminfo;swappinessreflects/proc/sys/vm/swappiness(-1when unavailable). Byte fields are machine-readable;swap_usage_percentis the human-friendly view.
Topic: unraid/array
Payload:
{
"state": "STARTED",
"size": 12000000000000,
"free": 8000000000000,
"used_percent": 33.3,
"num_disks": 6,
"parity_valid": true,
"parity_check_status": "idle",
"timestamp": "2025-01-20T10:30:00Z"
}Topic: unraid/containers
Payload:
[
{
"id": "abc123def456",
"name": "plex",
"state": "running",
"status": "Up 2 hours",
"image": "plexinc/pms-docker:latest",
"cpu_percent": 5.2,
"memory_usage": 2147483648,
"timestamp": "2025-01-20T10:30:00Z"
}
]Add to your configuration.yaml:
mqtt:
sensor:
# CPU Usage
- name: "Unraid CPU Usage"
state_topic: "unraid/system"
value_template: "{{ value_json.cpu_usage | round(1) }}"
unit_of_measurement: "%"
icon: mdi:cpu-64-bit
# RAM Usage
- name: "Unraid RAM Usage"
state_topic: "unraid/system"
value_template: "{{ value_json.ram_usage | round(1) }}"
unit_of_measurement: "%"
icon: mdi:memory
# CPU Temperature
- name: "Unraid CPU Temperature"
state_topic: "unraid/system"
value_template: "{{ value_json.cpu_temp | round(1) }}"
unit_of_measurement: "°C"
device_class: temperature
# Array Status
- name: "Unraid Array State"
state_topic: "unraid/array"
value_template: "{{ value_json.state }}"
icon: mdi:server
# Array Usage
- name: "Unraid Array Usage"
state_topic: "unraid/array"
value_template: "{{ value_json.used_percent | round(1) }}"
unit_of_measurement: "%"
icon: mdi:harddisk
# Parity Valid
- name: "Unraid Parity Status"
state_topic: "unraid/array"
value_template: "{{ 'Valid' if value_json.parity_valid else 'Invalid' }}"
icon: mdi:shield-checkautomation:
- alias: "Unraid High CPU Alert"
trigger:
- platform: numeric_state
entity_id: sensor.unraid_cpu_usage
above: 90
for:
minutes: 5
action:
- service: notify.mobile_app
data:
message: "Unraid CPU usage is {{ states('sensor.unraid_cpu_usage') }}%"
title: "⚠️ Unraid Alert"automation:
- alias: "Unraid Parity Invalid Alert"
trigger:
- platform: state
entity_id: sensor.unraid_parity_status
to: "Invalid"
action:
- service: notify.mobile_app
data:
message: "Unraid array parity is INVALID!"
title: "🚨 Unraid Critical Alert"automation:
- alias: "Plex Container Stopped"
trigger:
- platform: mqtt
topic: "unraid/containers"
condition:
- condition: template
value_template: >
{% set containers = trigger.payload_json %}
{% set plex = containers | selectattr('name', 'eq', 'plex') | list | first %}
{{ plex.state != 'running' }}
action:
- service: notify.mobile_app
data:
message: "Plex container has stopped!"
title: "⚠️ Unraid Container Alert"Configure an MQTT In node:
- Server: Your MQTT broker
- Topic:
unraid/#(subscribe to all topics) - QoS: 1
- Output: Parsed JSON object
[
{
"id": "mqtt_in",
"type": "mqtt in",
"topic": "unraid/system",
"qos": "1",
"broker": "mqtt_broker"
},
{
"id": "cpu_check",
"type": "function",
"func": "if (msg.payload.cpu_usage > 80) {\n msg.payload = {\n title: 'High CPU Usage',\n message: `CPU at ${msg.payload.cpu_usage}%`\n };\n return msg;\n}"
},
{
"id": "notification",
"type": "pushover",
"title": "{{payload.title}}",
"message": "{{payload.message}}"
}
]In addition to the notifications topic (full list + unread counts), the agent
publishes a per-notification event to <prefix>/notifications/event and
registers a Home Assistant MQTT event entity for it. One message is published
the first time each notification ID is seen; the existing backlog is seeded
silently on startup so an agent restart never replays old notifications. Event
messages are not retained, so Home Assistant does not refire them on reconnect.
Topic: unraid/notifications/event
Payload:
{
"event_type": "alert",
"id": "notify_1737368400_0",
"title": "Array Started",
"subject": "Array Status",
"description": "The array has been started",
"importance": "alert",
"type": "unread",
"link": "/Dashboard",
"timestamp": "2025-01-20T10:30:00Z",
"formatted_timestamp": "2025-01-20 10:30:00"
}event_type is one of alert, warning, or info (HA fires the event under
this type). All notification details are carried as event attributes so
automations have the full context. timestamp is machine-readable (RFC 3339);
formatted_timestamp is the human-readable form.
# Using mosquitto_sub
mosquitto_sub -h localhost -t "unraid/#" -v
# With authentication
mosquitto_sub -h localhost -u username -P password -t "unraid/#" -vcurl -X POST http://localhost:8043/api/v1/mqtt/publish \
-H "Content-Type: application/json" \
-d '{
"topic": "unraid/test",
"payload": {"message": "test"},
"retained": false
}'For secure MQTT connections:
# Use ssl:// instead of tcp://
MQTT_BROKER=ssl://mqtt.example.com:8883Note: TLS certificate validation is performed. Ensure valid certificates or configure your broker accordingly.
- QoS: Messages are published with QoS 1 (at least once delivery)
- Retained: Messages are NOT retained by default (latest state only)
To enable retained messages for persistent state, this would require a code modification.
Use hierarchical topics for multi-server setups:
# Server 1
MQTT_TOPIC_PREFIX=homelab/tower1
# Server 2
MQTT_TOPIC_PREFIX=homelab/tower2Topics become:
homelab/tower1/systemhomelab/tower2/system
# Check logs
tail -f /var/log/unraid-management-agent.log | grep MQTT
# Test broker connectivity
mosquitto_sub -h BROKER_IP -p 1883 -t "test"
# Test with authentication
mosquitto_pub -h BROKER_IP -u username -P password -t "test" -m "hello"- Verify MQTT is enabled in config
- Check broker is running:
ps aux | grep mosquitto - Verify topic subscription:
mosquitto_sub -t "unraid/#" -v - Check firewall rules on broker
# Verify credentials
mosquitto_pub -h BROKER_IP -u username -P password -t "test" -m "test"
# Check broker logs
tail -f /var/log/mosquitto/mosquitto.logversion: "3"
services:
mosquitto:
image: eclipse-mosquitto:latest
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./config:/mosquitto/config
- ./data:/mosquitto/data
- ./log:/mosquitto/logCreate config/mosquitto.conf:
listener 1883
allow_anonymous true
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
With authentication:
listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd
Create password file:
docker exec mosquitto mosquitto_passwd -c /mosquitto/config/passwd usernameWith default collection intervals:
- Fast topics (5-10s): system, array, containers, vms
- Moderate topics (30-60s): disks, shares, network
- Total message rate: ~10-15 messages/minute
Typical bandwidth usage:
- Average message size: 200-500 bytes
- Peak bandwidth: <1 KB/s
- Daily data: <50 MB
Impact on MQTT broker:
- CPU: Negligible
- Memory: ~5-10 MB per client
- Connections: 1 persistent connection
- Home Assistant Integration - Complete HA setup
- Grafana Integration - Monitoring dashboards
- REST API Reference - Control via API
- Configuration Guide - Customize settings
Last Updated: January 2026
MQTT Protocol Version: 3.1.1
Topics Published: 10+