# 🏠 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ème
- `binary_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** :
```json
{
  "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** :
```json
{
  "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** :
```json
{
  "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** :
```json
{
  "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** :
```json
{
  "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` :

```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` :

```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 :

```yaml
# 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)

```yaml
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)

```yaml
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)

```yaml
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)

```yaml
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)

```yaml
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

```yaml
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é

```yaml
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)

```yaml
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

```yaml
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`** :
```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`** :
```python
"""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`** :
```python
"""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`** :
```python
"""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`** :
```python
"""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`** :
```python
#!/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** :
```bash
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 :

1. **Utiliser MQTT Discovery** : Simplifie l'ajout d'équipements
2. **Créer un Custom Component** : Intégration native dans Home Assistant
3. **Implémenter Config Flow** : Configuration via UI (Settings → Integrations)
4. **Supporter Multiple Devices** : Un équipement IPWatch = un device HA
5. **Gérer les états** : Mapping clair entre MQTT et entités HA
6. **Ajouter des diagnostics** : Logs et debugging pour faciliter le support

### 9.2 Fonctionnalités Avancées

**WOL depuis Home Assistant** :
```yaml
# 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

```bash
# É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

```bash
# 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

1. Créer une automatisation simple
2. Déclencher manuellement
3. Vérifier les logs HA : Settings → System → Logs

## 11. Dépannage

### Entités non découvertes

```bash
# 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)
