Add French docstrings and README
- Docstrings for all modules, classes and methods - README.md with installation and usage instructions - Update CLAUDE.md with dns.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
131
lan_checker.py
131
lan_checker.py
@@ -1,6 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
LAN Checker - Network health monitoring with MQTT reporting for Home Assistant.
|
||||
LAN Checker - Surveillance réseau avec reporting MQTT pour Home Assistant.
|
||||
|
||||
Ce script vérifie périodiquement l'état de services et équipements réseau,
|
||||
puis publie les résultats via MQTT en utilisant le protocole MQTT Discovery
|
||||
de Home Assistant pour créer automatiquement les entités.
|
||||
|
||||
Usage:
|
||||
python lan_checker.py [-c CONFIG]
|
||||
|
||||
Exemples:
|
||||
python lan_checker.py
|
||||
python lan_checker.py -c /etc/lan_checker/config.yaml
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -24,13 +35,47 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LanChecker:
|
||||
"""
|
||||
Gestionnaire principal de surveillance réseau.
|
||||
|
||||
Charge la configuration, établit la connexion MQTT, exécute les
|
||||
vérifications périodiques et publie les résultats.
|
||||
|
||||
Attributes:
|
||||
config: Configuration chargée depuis le fichier YAML.
|
||||
mqtt_client: Client MQTT pour la publication des résultats.
|
||||
running: Flag d'exécution de la boucle principale.
|
||||
checks: Liste des vérifications configurées.
|
||||
"""
|
||||
|
||||
def __init__(self, config_path: str):
|
||||
"""
|
||||
Initialise le gestionnaire.
|
||||
|
||||
Args:
|
||||
config_path: Chemin vers le fichier de configuration YAML.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: Si le fichier de configuration n'existe pas.
|
||||
"""
|
||||
self.config = self._load_config(config_path)
|
||||
self.mqtt_client: mqtt.Client | None = None
|
||||
self.running = False
|
||||
self.checks = []
|
||||
|
||||
def _load_config(self, config_path: str) -> dict:
|
||||
"""
|
||||
Charge la configuration depuis un fichier YAML.
|
||||
|
||||
Args:
|
||||
config_path: Chemin vers le fichier de configuration.
|
||||
|
||||
Returns:
|
||||
Dictionnaire contenant la configuration.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: Si le fichier n'existe pas.
|
||||
"""
|
||||
path = Path(config_path)
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
||||
@@ -39,6 +84,12 @@ class LanChecker:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
def _setup_mqtt(self):
|
||||
"""
|
||||
Configure et connecte le client MQTT.
|
||||
|
||||
Utilise les paramètres de la section 'mqtt' de la configuration.
|
||||
Configure l'authentification si un nom d'utilisateur est fourni.
|
||||
"""
|
||||
mqtt_config = self.config["mqtt"]
|
||||
self.mqtt_client = mqtt.Client(
|
||||
mqtt.CallbackAPIVersion.VERSION2,
|
||||
@@ -62,6 +113,19 @@ class LanChecker:
|
||||
self.mqtt_client.loop_start()
|
||||
|
||||
def _on_mqtt_connect(self, client, userdata, flags, reason_code, properties):
|
||||
"""
|
||||
Callback appelé lors de la connexion au broker MQTT.
|
||||
|
||||
Publie les messages de découverte Home Assistant si la connexion
|
||||
est réussie.
|
||||
|
||||
Args:
|
||||
client: Instance du client MQTT.
|
||||
userdata: Données utilisateur (non utilisé).
|
||||
flags: Flags de connexion.
|
||||
reason_code: Code de résultat de la connexion.
|
||||
properties: Propriétés MQTT v5 (non utilisé).
|
||||
"""
|
||||
if reason_code == 0:
|
||||
logger.info("Connected to MQTT broker")
|
||||
self._publish_discovery()
|
||||
@@ -69,15 +133,35 @@ class LanChecker:
|
||||
logger.error(f"MQTT connection failed: {reason_code}")
|
||||
|
||||
def _on_mqtt_disconnect(self, client, userdata, flags, reason_code, properties):
|
||||
"""
|
||||
Callback appelé lors de la déconnexion du broker MQTT.
|
||||
|
||||
Args:
|
||||
client: Instance du client MQTT.
|
||||
userdata: Données utilisateur (non utilisé).
|
||||
flags: Flags de déconnexion.
|
||||
reason_code: Code de raison de la déconnexion.
|
||||
properties: Propriétés MQTT v5 (non utilisé).
|
||||
"""
|
||||
logger.warning(f"Disconnected from MQTT broker: {reason_code}")
|
||||
|
||||
def _publish_discovery(self):
|
||||
"""Publish MQTT Discovery messages for Home Assistant."""
|
||||
"""
|
||||
Publie les messages MQTT Discovery pour Home Assistant.
|
||||
|
||||
Pour chaque check configuré, publie:
|
||||
- Un binary_sensor pour l'état online/offline
|
||||
- Un sensor pour la latence (temps de réponse)
|
||||
- Un sensor pour la température (SNMP uniquement, si configuré)
|
||||
|
||||
Les entités sont automatiquement créées dans Home Assistant
|
||||
grâce au protocole MQTT Discovery.
|
||||
"""
|
||||
for check in self.config["checks"]:
|
||||
device_id = check["id"]
|
||||
device_name = check["name"]
|
||||
|
||||
# Binary sensor for online/offline status
|
||||
# Binary sensor pour l'état online/offline
|
||||
status_config = {
|
||||
"name": f"{device_name} Status",
|
||||
"unique_id": f"lan_checker_{device_id}_status",
|
||||
@@ -99,7 +183,7 @@ class LanChecker:
|
||||
retain=True
|
||||
)
|
||||
|
||||
# Sensor for response time
|
||||
# Sensor pour le temps de réponse
|
||||
latency_config = {
|
||||
"name": f"{device_name} Latency",
|
||||
"unique_id": f"lan_checker_{device_id}_latency",
|
||||
@@ -121,7 +205,7 @@ class LanChecker:
|
||||
retain=True
|
||||
)
|
||||
|
||||
# Sensor for temperature (SNMP only, if temperature_oid configured)
|
||||
# Sensor pour la température (SNMP uniquement)
|
||||
if check.get("type") == "snmp" and check.get("temperature_oid"):
|
||||
temp_config = {
|
||||
"name": f"{device_name} Temperature",
|
||||
@@ -147,7 +231,12 @@ class LanChecker:
|
||||
logger.info(f"Published discovery for: {device_name}")
|
||||
|
||||
def _setup_checks(self):
|
||||
"""Initialize check instances from configuration."""
|
||||
"""
|
||||
Initialise les instances de checkers depuis la configuration.
|
||||
|
||||
Parcourt la liste des checks dans la configuration et crée
|
||||
une instance du checker approprié pour chacun.
|
||||
"""
|
||||
for check_config in self.config["checks"]:
|
||||
check_type = check_config["type"]
|
||||
if check_type not in CHECKERS:
|
||||
@@ -165,7 +254,13 @@ class LanChecker:
|
||||
})
|
||||
|
||||
def _run_check(self, check: dict):
|
||||
"""Execute a single check and publish results."""
|
||||
"""
|
||||
Exécute une vérification et publie le résultat via MQTT.
|
||||
|
||||
Args:
|
||||
check: Dictionnaire contenant l'id, le nom, le checker
|
||||
et l'intervalle de vérification.
|
||||
"""
|
||||
result = check["checker"].check()
|
||||
|
||||
state = "online" if result.success else "offline"
|
||||
@@ -177,7 +272,7 @@ class LanChecker:
|
||||
}
|
||||
|
||||
if result.details:
|
||||
# Extract temperature for SNMP checks
|
||||
# Extrait la température des détails pour la mettre à la racine
|
||||
if "temperature" in result.details:
|
||||
payload["temperature"] = result.details.pop("temperature")
|
||||
if result.details:
|
||||
@@ -190,7 +285,12 @@ class LanChecker:
|
||||
logger.log(log_level, f"{check['name']}: {state} - {result.message}")
|
||||
|
||||
def run(self):
|
||||
"""Main loop."""
|
||||
"""
|
||||
Lance la boucle principale de surveillance.
|
||||
|
||||
Configure MQTT, initialise les checkers, puis exécute les
|
||||
vérifications en boucle selon leurs intervalles respectifs.
|
||||
"""
|
||||
self._setup_mqtt()
|
||||
self._setup_checks()
|
||||
|
||||
@@ -208,7 +308,11 @@ class LanChecker:
|
||||
time.sleep(1)
|
||||
|
||||
def stop(self):
|
||||
"""Stop the checker gracefully."""
|
||||
"""
|
||||
Arrête proprement le gestionnaire.
|
||||
|
||||
Stoppe la boucle principale et déconnecte le client MQTT.
|
||||
"""
|
||||
logger.info("Stopping LAN Checker...")
|
||||
self.running = False
|
||||
if self.mqtt_client:
|
||||
@@ -217,6 +321,12 @@ class LanChecker:
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Point d'entrée principal.
|
||||
|
||||
Parse les arguments de ligne de commande, configure les gestionnaires
|
||||
de signaux et lance le checker.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description="LAN Checker - Network health monitoring")
|
||||
parser.add_argument(
|
||||
"-c", "--config",
|
||||
@@ -228,6 +338,7 @@ def main():
|
||||
checker = LanChecker(args.config)
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
"""Gestionnaire de signaux pour arrêt propre."""
|
||||
checker.stop()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user