24 KiB
🏠 Spécifications Home Assistant pour IPWatch MQTT
Ce document définit les spécifications pour intégrer les équipements IPWatch dans Home Assistant via MQTT Discovery.
1. Vue d'ensemble
L'intégration Home Assistant permet de :
- Détecter automatiquement les équipements IPWatch via MQTT Discovery
- Visualiser l'état des équipements (online/offline)
- Contrôler les équipements (shutdown, reboot)
- Monitorer les métriques système (CPU, RAM, Disk, Uptime)
- Créer des automatisations basées sur l'état des équipements
2. MQTT Discovery
2.1 Principe
MQTT Discovery permet à Home Assistant de détecter automatiquement les entités sans configuration manuelle.
Topic de découverte : homeassistant/{component}/ipwatch_{unique_id}/{object_id}/config
Composants supportés :
sensor: Métriques systèmebinary_sensor: État de disponibilitébutton: Actions (shutdown, reboot)
2.2 Configuration Discovery pour Sensor
L'agent MQTT publie automatiquement sa configuration au démarrage :
Topic : homeassistant/sensor/ipwatch_10_0_0_100/system/config
Payload :
{
"name": "Server 01 - Système",
"unique_id": "ipwatch_10_0_0_100_system",
"state_topic": "ipwatch/device/10.0.0.100/status",
"value_template": "{{ value_json.hostname }}",
"json_attributes_topic": "ipwatch/device/10.0.0.100/status",
"availability": {
"topic": "ipwatch/device/10.0.0.100/availability",
"payload_available": "online",
"payload_not_available": "offline"
},
"device": {
"identifiers": ["ipwatch_10_0_0_100"],
"name": "Server 01",
"model": "IPWatch MQTT Agent v1.0",
"manufacturer": "IPWatch",
"sw_version": "1.0.0"
},
"icon": "mdi:desktop-tower",
"qos": 1
}
2.3 Configuration Discovery pour Binary Sensor (Availability)
Topic : homeassistant/binary_sensor/ipwatch_10_0_0_100/availability/config
Payload :
{
"name": "Server 01 - Disponibilité",
"unique_id": "ipwatch_10_0_0_100_availability",
"state_topic": "ipwatch/device/10.0.0.100/availability",
"payload_on": "online",
"payload_off": "offline",
"device_class": "connectivity",
"device": {
"identifiers": ["ipwatch_10_0_0_100"],
"name": "Server 01"
},
"icon": "mdi:lan-connect",
"qos": 1
}
2.4 Configuration Discovery pour Buttons
Shutdown Button :
Topic : homeassistant/button/ipwatch_10_0_0_100/shutdown/config
Payload :
{
"name": "Server 01 - Shutdown",
"unique_id": "ipwatch_10_0_0_100_shutdown",
"command_topic": "ipwatch/device/10.0.0.100/command",
"payload_press": "{\"command\":\"shutdown\",\"timestamp\":\"{{ now().isoformat() }}\"}",
"availability": {
"topic": "ipwatch/device/10.0.0.100/availability",
"payload_available": "online",
"payload_not_available": "offline"
},
"device": {
"identifiers": ["ipwatch_10_0_0_100"],
"name": "Server 01"
},
"icon": "mdi:power-off",
"qos": 1
}
Reboot Button :
Topic : homeassistant/button/ipwatch_10_0_0_100/reboot/config
Payload :
{
"name": "Server 01 - Reboot",
"unique_id": "ipwatch_10_0_0_100_reboot",
"command_topic": "ipwatch/device/10.0.0.100/command",
"payload_press": "{\"command\":\"reboot\",\"timestamp\":\"{{ now().isoformat() }}\"}",
"availability": {
"topic": "ipwatch/device/10.0.0.100/availability",
"payload_available": "online",
"payload_not_available": "offline"
},
"device": {
"identifiers": ["ipwatch_10_0_0_100"],
"name": "Server 01"
},
"icon": "mdi:restart",
"qos": 1
}
3. Entités Créées dans Home Assistant
3.1 Sensors (Métriques Système)
Chaque équipement IPWatch crée automatiquement ces sensors :
| Entity ID | Nom | Description | Attribut JSON |
|---|---|---|---|
sensor.server_01_systeme |
Server 01 - Système | État général | Tous les attributs |
sensor.server_01_cpu |
Server 01 - CPU | Usage CPU | cpu_percent |
sensor.server_01_memory |
Server 01 - RAM | Usage mémoire | memory_percent |
sensor.server_01_disk |
Server 01 - Disk | Usage disque | disk_percent |
sensor.server_01_uptime |
Server 01 - Uptime | Temps de fonctionnement | uptime |
Exemple de valeur du sensor système :
{
"hostname": "server-01",
"ip": "10.0.0.100",
"platform": "Linux",
"platform_version": "5.15.0-91-generic",
"uptime": 86400,
"cpu_percent": 45.2,
"memory_percent": 62.5,
"disk_percent": 78.3,
"timestamp": "2025-12-23T10:30:00Z"
}
3.2 Binary Sensors
| Entity ID | Nom | État | Icon |
|---|---|---|---|
binary_sensor.server_01_disponibilite |
Server 01 - Disponibilité | on/off | mdi:lan-connect |
3.3 Buttons
| Entity ID | Nom | Action | Icon |
|---|---|---|---|
button.server_01_shutdown |
Server 01 - Shutdown | Éteindre | mdi:power-off |
button.server_01_reboot |
Server 01 - Reboot | Redémarrer | mdi:restart |
4. Configuration Home Assistant
4.1 Configuration MQTT
Dans configuration.yaml :
# Configuration MQTT
mqtt:
broker: localhost
port: 1883
username: !secret mqtt_username
password: !secret mqtt_password
discovery: true
discovery_prefix: homeassistant
birth_message:
topic: 'homeassistant/status'
payload: 'online'
will_message:
topic: 'homeassistant/status'
payload: 'offline'
4.2 Secrets
Dans secrets.yaml :
mqtt_username: ipwatch
mqtt_password: VotreMotDePasse
4.3 Templates pour Sensors Individuels (Optionnel)
Si vous souhaitez créer des sensors séparés pour chaque métrique :
# Sensor CPU
mqtt:
- sensor:
name: "Server 01 CPU"
unique_id: ipwatch_10_0_0_100_cpu
state_topic: "ipwatch/device/10.0.0.100/status"
value_template: "{{ value_json.cpu_percent }}"
unit_of_measurement: "%"
icon: mdi:cpu-64-bit
availability:
topic: "ipwatch/device/10.0.0.100/availability"
payload_available: "online"
payload_not_available: "offline"
device:
identifiers: ["ipwatch_10_0_0_100"]
name: "Server 01"
# Sensor RAM
- sensor:
name: "Server 01 Memory"
unique_id: ipwatch_10_0_0_100_memory
state_topic: "ipwatch/device/10.0.0.100/status"
value_template: "{{ value_json.memory_percent }}"
unit_of_measurement: "%"
icon: mdi:memory
availability:
topic: "ipwatch/device/10.0.0.100/availability"
device:
identifiers: ["ipwatch_10_0_0_100"]
# Sensor Disk
- sensor:
name: "Server 01 Disk"
unique_id: ipwatch_10_0_0_100_disk
state_topic: "ipwatch/device/10.0.0.100/status"
value_template: "{{ value_json.disk_percent }}"
unit_of_measurement: "%"
icon: mdi:harddisk
availability:
topic: "ipwatch/device/10.0.0.100/availability"
device:
identifiers: ["ipwatch_10_0_0_100"]
# Sensor Uptime
- sensor:
name: "Server 01 Uptime"
unique_id: ipwatch_10_0_0_100_uptime
state_topic: "ipwatch/device/10.0.0.100/status"
value_template: "{{ (value_json.uptime / 3600) | round(1) }}"
unit_of_measurement: "h"
icon: mdi:clock-outline
availability:
topic: "ipwatch/device/10.0.0.100/availability"
device:
identifiers: ["ipwatch_10_0_0_100"]
5. Lovelace UI Cards
5.1 Entity Card (Simple)
type: entities
title: Server 01
entities:
- entity: binary_sensor.server_01_disponibilite
name: Disponibilité
- entity: sensor.server_01_cpu
name: CPU
- entity: sensor.server_01_memory
name: RAM
- entity: sensor.server_01_disk
name: Disque
- entity: sensor.server_01_uptime
name: Uptime
- entity: button.server_01_shutdown
name: Éteindre
- entity: button.server_01_reboot
name: Redémarrer
5.2 Glance Card (Compact)
type: glance
title: Server 01
entities:
- entity: binary_sensor.server_01_disponibilite
name: État
- entity: sensor.server_01_cpu
name: CPU
- entity: sensor.server_01_memory
name: RAM
- entity: sensor.server_01_disk
name: Disque
5.3 Gauge Card (Métriques visuelles)
type: vertical-stack
cards:
- type: gauge
entity: sensor.server_01_cpu
name: CPU
min: 0
max: 100
severity:
green: 0
yellow: 60
red: 80
- type: gauge
entity: sensor.server_01_memory
name: RAM
min: 0
max: 100
severity:
green: 0
yellow: 70
red: 90
- type: gauge
entity: sensor.server_01_disk
name: Disque
min: 0
max: 100
severity:
green: 0
yellow: 80
red: 95
5.4 Custom Card (Markdown)
type: markdown
content: |
## 🖥️ Server 01
**État** : {{ states('binary_sensor.server_01_disponibilite') }}
**CPU** : {{ states('sensor.server_01_cpu') }}%
**RAM** : {{ states('sensor.server_01_memory') }}%
**Disque** : {{ states('sensor.server_01_disk') }}%
**Uptime** : {{ states('sensor.server_01_uptime') }}h
{% if is_state('binary_sensor.server_01_disponibilite', 'on') %}
✅ Serveur en ligne
{% else %}
❌ Serveur hors ligne
{% endif %}
5.5 Button Card (Actions rapides)
type: horizontal-stack
cards:
- type: button
entity: button.server_01_shutdown
name: Éteindre
icon: mdi:power-off
tap_action:
action: call-service
service: button.press
service_data:
entity_id: button.server_01_shutdown
hold_action:
action: none
- type: button
entity: button.server_01_reboot
name: Redémarrer
icon: mdi:restart
tap_action:
action: call-service
service: button.press
service_data:
entity_id: button.server_01_reboot
6. Automatisations
6.1 Alerte si serveur offline
alias: "Alert - Server 01 Offline"
description: Notification si serveur hors ligne
trigger:
- platform: state
entity_id: binary_sensor.server_01_disponibilite
to: "off"
for:
minutes: 5
action:
- service: notify.mobile_app
data:
title: "⚠️ Serveur Offline"
message: "Server 01 (10.0.0.100) est hors ligne depuis 5 minutes"
data:
priority: high
mode: single
6.2 Alerte CPU élevé
alias: "Alert - Server 01 High CPU"
description: Notification si CPU > 90%
trigger:
- platform: numeric_state
entity_id: sensor.server_01_cpu
above: 90
for:
minutes: 10
condition:
- condition: state
entity_id: binary_sensor.server_01_disponibilite
state: "on"
action:
- service: notify.mobile_app
data:
title: "🔥 CPU élevé"
message: "Server 01 - CPU à {{ states('sensor.server_01_cpu') }}%"
mode: single
6.3 Shutdown programmé (extinction nocturne)
alias: "Scheduled Shutdown - Server 01"
description: Éteindre le serveur à 23h chaque soir
trigger:
- platform: time
at: "23:00:00"
condition:
- condition: state
entity_id: binary_sensor.server_01_disponibilite
state: "on"
action:
- service: button.press
target:
entity_id: button.server_01_shutdown
mode: single
6.4 Wake-on-LAN au démarrage de HA
alias: "WOL - Server 01 on HA Start"
description: Démarrer le serveur quand Home Assistant démarre
trigger:
- platform: homeassistant
event: start
action:
- service: wake_on_lan.send_magic_packet
data:
mac: "AA:BB:CC:DD:EE:FF"
broadcast_address: "192.168.1.255"
mode: single
7. Intégration Personnalisée (Custom Integration)
7.1 Structure du Custom Component
Pour créer une intégration personnalisée plus avancée :
custom_components/
└── ipwatch/
├── __init__.py
├── manifest.json
├── config_flow.py
├── const.py
├── sensor.py
├── binary_sensor.py
├── button.py
└── strings.json
7.2 Manifest
manifest.json :
{
"domain": "ipwatch",
"name": "IPWatch Network Monitor",
"version": "1.0.0",
"documentation": "https://github.com/your-repo/ipwatch-ha",
"requirements": ["paho-mqtt==1.6.1"],
"dependencies": ["mqtt"],
"codeowners": ["@yourusername"],
"iot_class": "local_push",
"config_flow": true
}
7.3 Constants
const.py :
"""Constants for IPWatch integration."""
DOMAIN = "ipwatch"
CONF_MQTT_BROKER = "mqtt_broker"
CONF_MQTT_PORT = "mqtt_port"
CONF_DEVICE_IP = "device_ip"
CONF_DEVICE_NAME = "device_name"
# MQTT Topics
TOPIC_PREFIX = "ipwatch/device"
TOPIC_COMMAND = "command"
TOPIC_STATUS = "status"
TOPIC_AVAILABILITY = "availability"
TOPIC_RESPONSE = "response"
# Commands
COMMAND_SHUTDOWN = "shutdown"
COMMAND_REBOOT = "reboot"
COMMAND_STATUS = "status"
# Platforms
PLATFORMS = ["sensor", "binary_sensor", "button"]
7.4 Config Flow (UI Configuration)
config_flow.py :
"""Config flow for IPWatch integration."""
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from .const import DOMAIN, CONF_DEVICE_IP, CONF_DEVICE_NAME
class IPWatchConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for IPWatch."""
VERSION = 1
async def async_step_user(self, user_input=None):
"""Handle the initial step."""
errors = {}
if user_input is not None:
# Validate user input
await self.async_set_unique_id(user_input[CONF_DEVICE_IP])
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[CONF_DEVICE_NAME],
data=user_input
)
data_schema = vol.Schema({
vol.Required(CONF_DEVICE_IP): str,
vol.Required(CONF_DEVICE_NAME): str,
})
return self.async_show_form(
step_id="user",
data_schema=data_schema,
errors=errors
)
7.5 Sensor Platform
sensor.py :
"""Sensor platform for IPWatch."""
from homeassistant.components.sensor import SensorEntity
from homeassistant.core import callback
from .const import DOMAIN
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up IPWatch sensor based on a config entry."""
device_ip = config_entry.data[CONF_DEVICE_IP]
device_name = config_entry.data[CONF_DEVICE_NAME]
sensors = [
IPWatchCPUSensor(device_ip, device_name),
IPWatchMemorySensor(device_ip, device_name),
IPWatchDiskSensor(device_ip, device_name),
IPWatchUptimeSensor(device_ip, device_name),
]
async_add_entities(sensors)
class IPWatchCPUSensor(SensorEntity):
"""Representation of IPWatch CPU sensor."""
def __init__(self, device_ip, device_name):
"""Initialize the sensor."""
self._device_ip = device_ip
self._device_name = device_name
self._state = None
self._available = False
@property
def name(self):
"""Return the name of the sensor."""
return f"{self._device_name} CPU"
@property
def unique_id(self):
"""Return a unique ID."""
return f"ipwatch_{self._device_ip.replace('.', '_')}_cpu"
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return "%"
@property
def icon(self):
"""Return the icon."""
return "mdi:cpu-64-bit"
@property
def available(self):
"""Return True if entity is available."""
return self._available
@callback
def _handle_status_update(self, msg):
"""Handle MQTT status updates."""
import json
payload = json.loads(msg.payload)
self._state = payload.get("cpu_percent")
self._available = True
self.async_write_ha_state()
async def async_added_to_hass(self):
"""Subscribe to MQTT topics."""
await self.hass.components.mqtt.async_subscribe(
f"ipwatch/device/{self._device_ip}/status",
self._handle_status_update
)
7.6 Button Platform
button.py :
"""Button platform for IPWatch."""
from homeassistant.components.button import ButtonEntity
from .const import DOMAIN, COMMAND_SHUTDOWN, COMMAND_REBOOT
import json
from datetime import datetime
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up IPWatch buttons."""
device_ip = config_entry.data[CONF_DEVICE_IP]
device_name = config_entry.data[CONF_DEVICE_NAME]
buttons = [
IPWatchShutdownButton(hass, device_ip, device_name),
IPWatchRebootButton(hass, device_ip, device_name),
]
async_add_entities(buttons)
class IPWatchShutdownButton(ButtonEntity):
"""Shutdown button for IPWatch device."""
def __init__(self, hass, device_ip, device_name):
"""Initialize the button."""
self.hass = hass
self._device_ip = device_ip
self._device_name = device_name
@property
def name(self):
"""Return the name."""
return f"{self._device_name} Shutdown"
@property
def unique_id(self):
"""Return unique ID."""
return f"ipwatch_{self._device_ip.replace('.', '_')}_shutdown"
@property
def icon(self):
"""Return icon."""
return "mdi:power-off"
async def async_press(self):
"""Handle button press."""
topic = f"ipwatch/device/{self._device_ip}/command"
payload = json.dumps({
"command": COMMAND_SHUTDOWN,
"timestamp": datetime.now().isoformat()
})
await self.hass.components.mqtt.async_publish(
topic,
payload,
qos=1
)
8. Scripts Python pour Administration
8.1 Script de Découverte Automatique
scripts/publish_discovery.py :
#!/usr/bin/env python3
"""
Publie la configuration MQTT Discovery pour tous les équipements IPWatch
"""
import paho.mqtt.client as mqtt
import json
import sys
def publish_discovery(broker, port, device_ip, device_name):
"""Publie les configs Discovery pour un équipement"""
client = mqtt.Client()
client.connect(broker, port)
unique_id = f"ipwatch_{device_ip.replace('.', '_')}"
# Sensor système
config = {
"name": f"{device_name} - Système",
"unique_id": f"{unique_id}_system",
"state_topic": f"ipwatch/device/{device_ip}/status",
"value_template": "{{ value_json.hostname }}",
"json_attributes_topic": f"ipwatch/device/{device_ip}/status",
"availability": {
"topic": f"ipwatch/device/{device_ip}/availability",
"payload_available": "online",
"payload_not_available": "offline"
},
"device": {
"identifiers": [unique_id],
"name": device_name,
"model": "IPWatch MQTT Agent v1.0",
"manufacturer": "IPWatch"
},
"icon": "mdi:desktop-tower",
"qos": 1
}
topic = f"homeassistant/sensor/{unique_id}/system/config"
client.publish(topic, json.dumps(config), qos=1, retain=True)
print(f"✓ Published sensor config for {device_name}")
# Binary sensor availability
config = {
"name": f"{device_name} - Disponibilité",
"unique_id": f"{unique_id}_availability",
"state_topic": f"ipwatch/device/{device_ip}/availability",
"payload_on": "online",
"payload_off": "offline",
"device_class": "connectivity",
"device": {"identifiers": [unique_id]},
"icon": "mdi:lan-connect",
"qos": 1
}
topic = f"homeassistant/binary_sensor/{unique_id}/availability/config"
client.publish(topic, json.dumps(config), qos=1, retain=True)
print(f"✓ Published binary_sensor config for {device_name}")
# Buttons
for cmd in ["shutdown", "reboot"]:
config = {
"name": f"{device_name} - {cmd.capitalize()}",
"unique_id": f"{unique_id}_{cmd}",
"command_topic": f"ipwatch/device/{device_ip}/command",
"payload_press": json.dumps({"command": cmd}),
"availability": {
"topic": f"ipwatch/device/{device_ip}/availability",
"payload_available": "online",
"payload_not_available": "offline"
},
"device": {"identifiers": [unique_id]},
"icon": f"mdi:{'power-off' if cmd == 'shutdown' else 'restart'}",
"qos": 1
}
topic = f"homeassistant/button/{unique_id}/{cmd}/config"
client.publish(topic, json.dumps(config), qos=1, retain=True)
print(f"✓ Published button {cmd} config for {device_name}")
client.disconnect()
if __name__ == "__main__":
if len(sys.argv) != 5:
print("Usage: python publish_discovery.py <broker> <port> <device_ip> <device_name>")
sys.exit(1)
publish_discovery(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4])
Utilisation :
python3 scripts/publish_discovery.py localhost 1883 10.0.0.100 "Server 01"
9. Développement de l'App Home Assistant
9.1 Recommandations
Pour développer une application Home Assistant dédiée à IPWatch :
- Utiliser MQTT Discovery : Simplifie l'ajout d'équipements
- Créer un Custom Component : Intégration native dans Home Assistant
- Implémenter Config Flow : Configuration via UI (Settings → Integrations)
- Supporter Multiple Devices : Un équipement IPWatch = un device HA
- Gérer les états : Mapping clair entre MQTT et entités HA
- Ajouter des diagnostics : Logs et debugging pour faciliter le support
9.2 Fonctionnalités Avancées
WOL depuis Home Assistant :
# Configuration Wake-on-LAN
wake_on_lan:
# Service call
service: wake_on_lan.send_magic_packet
data:
mac: "AA:BB:CC:DD:EE:FF"
broadcast_address: "192.168.1.255"
Intégration avec Lovelace Dashboard :
- Card personnalisée pour afficher grille IPWatch
- Actions rapides (shutdown, reboot, WOL)
- Graphiques historiques des métriques
Notifications Push :
- Alertes sur changements d'état
- Notifications sur nouveaux équipements détectés
10. Tests et Validation
10.1 Tester Discovery
# Écouter les messages Discovery
mosquitto_sub -h localhost -t "homeassistant/#" -v
# Vérifier que Home Assistant a créé les entités
# Developer Tools → States
# Rechercher : sensor.server_01, binary_sensor.server_01, button.server_01
10.2 Tester les Commandes
# Tester shutdown via MQTT
mosquitto_pub -h localhost \
-t "ipwatch/device/10.0.0.100/command" \
-m '{"command":"shutdown","timestamp":"2025-12-23T10:30:00Z"}'
# Vérifier la réponse
mosquitto_sub -h localhost \
-t "ipwatch/device/10.0.0.100/response" -v
10.3 Tester les Automatisations
- Créer une automatisation simple
- Déclencher manuellement
- Vérifier les logs HA : Settings → System → Logs
11. Dépannage
Entités non découvertes
# Vérifier que Discovery est activé
# configuration.yaml
mqtt:
discovery: true
# Republier les configs
python3 scripts/publish_discovery.py localhost 1883 10.0.0.100 "Server 01"
# Redémarrer Home Assistant
Boutons ne fonctionnent pas
- Vérifier que l'agent MQTT est en ligne
- Vérifier les permissions sudo sur le client
- Consulter les logs de l'agent :
sudo journalctl -u ipwatch-mqtt-agent -f
Sensors non mis à jour
- Vérifier que le topic status est publié toutes les 30 secondes
- Vérifier le QoS (doit être 1)
- Vérifier la disponibilité du broker MQTT
12. Références
- Home Assistant MQTT Discovery : https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery
- Home Assistant Developer Docs : https://developers.home-assistant.io/
- MQTT Sensor : https://www.home-assistant.io/integrations/sensor.mqtt/
- MQTT Button : https://www.home-assistant.io/integrations/button.mqtt/
- Config Flow : https://developers.home-assistant.io/docs/config_entries_config_flow_handler/
13. Checklist de Développement
Avant de publier l'intégration Home Assistant :
- MQTT Discovery implémenté pour tous les composants
- Config Flow pour configuration via UI
- Gestion des erreurs et retry automatique
- Documentation complète (README, HACS)
- Tests unitaires et d'intégration
- Validation HACS (Home Assistant Community Store)
- Icônes et traductions
- Changelog et versioning sémantique
- CI/CD pour tests automatisés
- Support multi-langues (i18n)