← Retour
domotique

Saturation de la table de routage dans les réseaux Zigbee domestiques

Cédrix · 04/06/2026

Diagnostic, analyse et remédiation d’un phénomène de cascade.

1. Introduction

Le protocole Zigbee, normalisé sous IEEE 802.15.4 et géré par la Connectivity Standards Alliance (anciennement Zigbee Alliance), est largement adopté dans l’automatisation résidentielle pour ses qualités de faible consommation énergétique, de topologie maillée auto-réparatrice et d’interopérabilité entre équipementiers. Un réseau Zigbee typique comprend trois catégories de nœuds :

  • Coordinateur — unique initiateur et gestionnaire du réseau
  • Routeurs — appareils alimentés en secteur qui relayent les messages
  • Terminaux — généralement à piles, communiquent uniquement avec leur parent

La robustesse théorique de la topologie maillée masque cependant une fragilité pratique : la table de routage du coordinateur est de taille fixe et limitée, imposée par le firmware ZStack embarqué sur les puces Texas Instruments (CC2530, CC2652P, etc.). Lorsque cette table atteint sa capacité maximale, toute tentative de découverte de route échoue avec le code d’erreur NWK_TABLE_FULL (0xc7), précipitant une série de défaillances en cascade.


2. Rappel des principes fondamentaux du routage Zigbee

2.1 Le protocole de routage dans IEEE 802.15.4 / Zigbee NWK

La couche réseau Zigbee (NWK) implémente un algorithme de routage dérivé du protocole AODV (Ad hoc On-Demand Distance Vector). Lorsqu’un nœud source souhaite communiquer avec un nœud destination pour lequel il ne dispose pas encore de route, il émet un paquet RREQ (Route REQuest) en diffusion. Les nœuds intermédiaires propagent ce RREQ jusqu’à la destination ou un nœud connaissant la route, qui répond par un RREP (Route REPly). L’entrée de route ainsi créée est stockée dans la table de routage du coordinateur, dont la taille est bornée dans le firmware ZStack.

2.2 Capacité de la table de routage ZStack

Le coordinateur ZStack CC2652P supporte typiquement entre 16 et 40 entrées de table de routage actives simultanément — une limite héritée des contraintes mémoire SRAM des microcontrôleurs cibles. Chaque entrée encode :

  • adresse courte destination (2 octets)
  • adresse du prochain saut (2 octets)
  • statut de la route
  • compteur d’expiration

La durée de vie d’une entrée est gérée par un mécanisme d’expiration (aging), mais sous forte sollicitation, de nouvelles découvertes de routes créent des entrées plus vite qu’elles n’expirent.

2.3 Le mécanisme de cascade (livelock)

La séquence d’états suivante formalise le phénomène observé :

État Description
Σ₀ N appareils envoient des données → N routes actives → table partiellement remplie
Σ₁ Redémarrage Z2M → HA publie M commandes simultanées
Σ₂ M découvertes RREQ simultanées → table saturée (NWK_TABLE_FULL)
Σ₃ Commandes échouent → HA ré-émet → délai MQTT non respecté
Σ₄ Z2M ne maintient plus le keepalive MQTT (bloqué sur timeouts ZCL)
Σ₅ Déconnexion MQTT → redémarrage automatique → retour à Σ₁

Ce cycle auto-entretenu constitue un verrouillage livelock : le service se redémarre indéfiniment, chaque redémarrage déclenchant une nouvelle vague de commandes, aggravant la saturation.


3. Infrastructure étudiée

Composant Détail
Coordinateur ZStack CC2652P — tcp://192.168.100.30:6638
Nœuds actifs 80 (≈20 routeurs secteur · ≈60 terminaux)
Modèles routeurs Tuya TS011F, TS0001, TS0004
Middleware Zigbee2MQTT v2.9.2 (LXC Proxmox, systemd)
Contrôleur Home Assistant OS 2026.x, intégration MQTT + Z2M

4. Résultats du diagnostic

4.1 Analyse des logs

Fréquence des erreurs sur une session (~5 min) :

Type d’erreur Occurrences / session
NWK_TABLE_FULL 58
TIMEOUT (ZCL) 380+
NWK_NO_ROUTE 42
Déconnexions MQTT 1 (terminaison de session)

4.2 Nœuds les plus impliqués

Appareil Occurrences dans les logs
sdb1_radiateur 406
cuisine_radiateur_fenetre 400
switch_sechelinge_2_7 341
PtExtSud 335
salon_radiateur_entree 331
cmn_contact_chauffeeau 324

4.3 Identification des appareils problématiques

Les appareils TS011F (prises intelligentes avec monitoring de puissance) se distinguent par leur comportement de publication : ils émettent un rapport Zigbee ZCL à chaque variation significative de puissance active, courant, tension ou énergie cumulée.

Le flux de trames généré peut être modélisé comme un processus de Poisson non-homogène :

λ(t) = λ₀ + α · |dP/dt|

λ₀ est le taux de base (~1 trame/min à charge stable) et α le coefficient de sensibilité aux variations de puissance P(t). Sous forte variation (plaque à induction, sèche-linge), λ(t) peut dépasser 10 trames/seconde, saturant le canal radio IEEE 802.15.4 (canal 15, 250 kbps bruts).


5. Mesures correctives appliquées

5.1 Throttle et filtrage des attributs publiés

Pour chaque appareil TS011F, les paramètres suivants ont été ajoutés dans configuration.yaml :

friendly_name: nom_appareil
throttle: 10                    # délai minimal inter-publication MQTT (secondes)
measurement_poll_interval: -1   # désactive le polling actif
filtered_attributes:
  - ^last_seen$
  - ^linkquality$
  - ^update$
filtered_cache:
  - ^last_seen$
  - ^linkquality$
  - ^update$

Le paramètre throttle agit comme un token bucket côté publication MQTT : quelle que soit la fréquence des rapports Zigbee reçus par le coordinateur, Z2M ne publie vers MQTT qu’un message toutes les throttle secondes minimum. Cela ne réduit pas le trafic radio Zigbee brut, mais soulage le broker MQTT et le moteur de règles de Home Assistant.

measurement_poll_interval: -1 désactive le sondage actif périodique (polling ZCL), éliminant une source de trafic initiée par le coordinateur lui-même. Le filtrage des attributs last_seen, linkquality et update supprime les publications systématiques de métadonnées à chaque message entrant.

Appareils modifiés (TS011F) : bureau_pc_extensionMix, switch_ext_terrasse, sdb1_radiateur, exterieur_lux_sud_3_10, switch_maison_generale, cmn_contact_chauffeeau_3_11, cuisine_plaqueCuisson, sdb0_radiateur_serviette, plug prise guirlande interieure

Appareils modifiés (TS0001/autres actifs) : cuisine_radiateur_fenetre, salon_radiateur_entree, cmn_radiateurs_pac, PtExtSud, cmn_vmc_switch, cmn_vmc_ctrl

5.2 Ajustement des paramètres de file d’attente

Paramètre Avant Après Effet
queue.delay 100 ms 300 ms Espace les commandes sortantes, réduit les RREQ simultanés d’un facteur 3
advanced.adapter_delay 300 ms 500 ms Augmente la fenêtre de réponse du coordinateur ZStack

L’augmentation de queue.delay laisse aux entrées de table de routage le temps d’expirer entre deux découvertes de routes, conformément au mécanisme d’aging ZStack.


6. Résultats post-correction

Indicateur Avant correction Après correction
Durée de vie du service < 5 minutes > 98 minutes (stable)
Erreurs NWK_TABLE_FULL 58 / session 0
Erreurs TIMEOUT 380+ / session ~10 (appareils injoignables)
Crashs MQTT 1 / session 0
Lignes de log / 5 min ~400 ~1

Les erreurs de timeout résiduelles (sdb1_radiateur, switch_sechelinge_2_7, lux_cuisine_spot1) correspondent à des appareils physiquement injoignables (hors tension ou nécessitant un ré-appairage) — ils ne participent pas à la saturation du bus.


7. Discussion

7.1 Limites des corrections appliquées

throttle et filtered_attributes agissent exclusivement au niveau de la couche applicative MQTT de Zigbee2MQTT. Ils ne modifient pas le comportement radio des appareils TS011F, qui continuent d’émettre des trames Zigbee à leur fréquence native. La réduction du trafic radio nécessiterait une reconfiguration ZCL des intervalles de rapport directement sur le firmware des appareils — opération possible via les commandes configure reporting de Zigbee2MQTT, mais dépendante du support firmware de chaque modèle.

7.2 Perspectives

Une solution pérenne impliquerait :

  1. La reconfiguration ZCL des intervalles de rapport (min_interval, max_interval, reportable_change) pour les appareils TS011F, afin de réduire le trafic radio à la source.
  2. La segmentation réseau : déplacer certains appareils vers une troisième instance Zigbee2MQTT avec un coordinateur dédié, réduisant mécaniquement la densité de la table de routage.
  3. Un firmware ZStack avec table de routage étendue : certaines versions expérimentales de Z-Stack 3.x supportent jusqu’à 40 entrées contre 16 dans les versions standard.

7.3 Portée générale

Le phénomène décrit n’est pas spécifique à cette installation. Tout réseau Zigbee dépassant une quarantaine de nœuds actifs avec des appareils de monitoring de puissance est susceptible d’y être exposé, particulièrement lors des redémarrages qui déclenchent une synchronisation massive de l’état applicatif.


8. Conclusion

Nous avons caractérisé et résolu un phénomène de verrouillage par saturation de table de routage dans un réseau Zigbee résidentiel de 80 nœuds. L’analyse a mis en évidence le rôle déterminant des appareils TS011F dans l’émission de trames à haute fréquence, aggravé par l’absence de limitation de publication côté middleware.

Les corrections apportées — throttle, filtered_attributes, ajustement de queue.delay et adapter_delay — ont permis d’éliminer intégralement les erreurs NWK_TABLE_FULL et de stabiliser le service sur une durée vingt fois supérieure à la situation initiale.

En IoT domestique, la robustesse d’un système distribué dépend autant de la discipline de publication de ses nœuds que de la topologie physique du réseau.

Partager : ✉ Mail X in 🐘
Commentaires

Aucun commentaire pour l'instant. Soyez le premier !

Laisser un commentaire
Un code de vérification sera envoyé à votre adresse email.