936 lines
24 KiB
Markdown
936 lines
24 KiB
Markdown
# 🏠 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)
|