9.4. Établir la liaison¶
La couche liaison abordée dans la page précédente est en grande partie automatique, mais il y a un endroit où un script Python doit intervenir : indiquer à la caméra quel réseau rejoindre. Tant que cette étape n’a pas réussi, aucune des fonctionnalités réseau couvertes par le reste de cette section ne fonctionnera.
9.4.1. Le module network¶
Le module network expose le matériel réseau de la caméra à Python. L’ensemble exact des interfaces dépend de la carte : de nombreuses caméras possèdent une puce sans fil et exposent une classe WLAN (nommée d’après Wireless Local Area Network) ; certaines cartes disposent également d’un port Ethernet intégré et exposent une classe LAN (nommée d’après Local Area Network, c’est-à-dire la version filaire). Le mode d’utilisation est le même pour les deux, avec une différence importante : une interface sans fil doit se voir indiquer quel réseau rejoindre, tandis qu’Ethernet prend ce qui se trouve sur le câble.
9.4.2. Le déroulement Wi-Fi¶
Rejoindre un réseau Wi-Fi se fait en trois étapes : construire l’interface, l’activer, lui demander de se connecter à un réseau nommé avec un mot de passe. L’interface négocie avec le point d’accès en arrière-plan ; un appel à isconnected() indique quand la liaison a fini de s’établir:
import network
import time
wlan = network.WLAN(network.WLAN.IF_STA)
wlan.active(True)
wlan.connect("my-network", "my-password")
while not wlan.isconnected():
time.sleep_ms(100)
print("link up")
L’argument IF_STA sélectionne le mode station – la caméra rejoint un réseau hébergé par quelqu’un d’autre. Le mode inverse, IF_AP, fait en sorte que la caméra héberge son propre petit réseau que d’autres appareils peuvent rejoindre ; utile pour les interfaces de configuration et la mise en service sur site, mais ce n’est pas le cas courant.
Une fois que isconnected() retourne True, la caméra est sur le réseau. Tout le reste dont les couches supérieures avaient besoin pour se configurer s’est produit automatiquement pendant que la liaison s’établissait ; les pages qui suivent détaillent ces éléments un par un.
9.4.3. Ce qui peut mal tourner¶
Quelques modes de défaillance pratiques apparaissent à cette étape.
Nom de réseau ou mot de passe erroné. La tentative de connexion réessaie silencieusement jusqu’à ce que l’application abandonne. Encadrez l’attente d’un délai d’expiration afin que la boucle ci-dessus ne bloque pas indéfiniment:
start = time.ticks_ms() while not wlan.isconnected(): if time.ticks_diff(time.ticks_ms(), start) > 10000: raise OSError("Wi-Fi did not come up in 10 s") time.sleep_ms(100)
Hors de portée. La caméra et le point d’accès doivent être suffisamment proches pour que le signal soit assez fort pour maintenir une liaison.
status()retourne un code indiquant pourquoi la liaison n’est pas établie ;scan()retourne la liste des réseaux que la radio peut voir, ce qui est le diagnostic à exécuter lorsqueconnectn’aboutit pas.Le point d’accès demande plus qu’un mot de passe. Les réseaux ouverts (sans mot de passe) et les réseaux courants protégés par mot de passe sont pris en charge par
connectcomme illustré ci-dessus. Les réseaux plus importants sur les lieux de travail et dans les écoles utilisent parfois un schéma différent où la caméra doit s’authentifier auprès d’un serveur de connexion distinct ; ceux-ci nécessitent des arguments supplémentaires àconnect. Voir classe WLAN – contrôle des interfaces WiFi intégrées pour la surface complète.
9.4.4. Rester connecté¶
Établir la liaison ne représente que la moitié du problème. Rester connecté est l’autre moitié – les points d’accès redémarrent, la caméra se déplace hors de portée, les baux DHCP expirent, le micrologiciel de la radio se bloque parfois. Une caméra censée vivre sur le réseau pendant des mois doit s’en apercevoir et se rétablir par elle-même.
Le schéma de détection consiste à appeler isconnected() une fois par itération de la boucle principale et à réagir lorsqu’il retourne False. isconnected() peut mentir brièvement lorsqu’une connexion a chuté sans que la radio s’en soit encore aperçue – un envoi sur socket qui échoue alors que la liaison « devrait » être établie est l’autre preuve dont dispose l’application d’une chute. status() est la source la plus fiable lorsque les deux sont en désaccord.
Le schéma de reconnexion est disconnect() suivi de connect() avec les mêmes identifiants, l’attente étant encadrée d’un délai d’expiration comme lors de la connexion initiale. Espacez les tentatives – une seconde, deux, quatre, en doublant jusqu’à une minute environ – afin qu’une longue panne ne harcèle pas le point d’accès et ne consomme pas le budget énergétique de la radio en boucles d’attente active:
import network
import time
_BACKOFF_S = (1, 2, 4, 8, 16, 32, 60)
def reconnect(wlan, ssid, password):
for delay in _BACKOFF_S:
wlan.disconnect()
wlan.connect(ssid, password)
deadline = time.ticks_add(time.ticks_ms(), 10_000)
while not wlan.isconnected():
if time.ticks_diff(deadline, time.ticks_ms()) < 0:
break
time.sleep_ms(100)
if wlan.isconnected():
return True
time.sleep(delay)
return False
Lorsque cette fonction utilitaire continue de retourner False, le micrologiciel de la radio lui-même est peut-être coincé. Le dernier recours est de redémarrer la radio par coupure d’alimentation : active(False), une brève pause, active(True), reconnexion à partir de zéro. Cela ramène le micrologiciel de la radio à un état connu au prix de quelques secondes supplémentaires d’indisponibilité:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
Une caméra hors réseau depuis plusieurs minutes constitue une véritable défaillance que l’application doit voir. Le code de récupération devrait faire remonter cet état – marquer le réseau comme défaillant dans un indicateur que la boucle principale vérifie, et laisser l’application ignorer les envois réseau qu’elle aurait effectués tant que l’indicateur n’est pas clair – afin qu’une longue panne ne bloque pas l’application en attente sur des sockets qui n’écriront jamais.
9.4.5. Ethernet, lorsqu’il est présent¶
Les cartes dotées d’un Ethernet intégré exposent le même schéma sans l’étape connect. L’interface LAN est activée avec active(), et dès que le câble est branché, l’interface est prête à l’emploi:
import network
lan = network.LAN()
lan.active(True)
print("link up")
À partir de ce point, le reste des pages de cette section s’applique de la même manière, quelle que soit l’interface qui a amené la caméra sur le réseau. Les couches supérieures ne se soucient pas de savoir si la liaison sous elles est du Wi-Fi ou de l’Ethernet – « connecté » est « connecté ».
Pour la référence complète de WLAN et LAN, y compris les paramètres de configuration qui n’ont pas trouvé leur place ici, voir network — configuration réseau.