9.4. Attivare il collegamento#
Il livello di collegamento trattato nella pagina precedente e perlopiu automatico, ma c’e un punto in cui uno script Python deve intervenire: indicare alla camera a quale rete unirsi. Finche quel passaggio non riesce, nessuna delle funzionalita di rete che il resto di questa sezione tratta funzionera.
9.4.1. Il modulo network#
Il modulo network espone a Python l’hardware di rete della camera. L’esatto insieme di interfacce dipende dalla scheda: molte camere hanno un chip wireless ed espongono una classe WLAN (chiamata cosi da Wireless Local Area Network); alcune schede hanno anche una porta Ethernet integrata ed espongono una classe LAN (chiamata cosi da Local Area Network, ovvero la versione cablata). Lo schema d’uso e lo stesso per entrambe, con una differenza importante: a un’interfaccia wireless va indicato a quale rete unirsi, mentre Ethernet recepisce qualunque cosa ci sia sul cavo.
9.4.2. Il flusso Wi-Fi#
Unirsi a una rete Wi-Fi avviene in tre passaggi: costruire l’interfaccia, attivarla, chiederle di connettersi a una rete nominata con una password. L’interfaccia negozia con il punto di accesso in background; una chiamata a isconnected() segnala quando il collegamento ha terminato di attivarsi:
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’argomento IF_STA seleziona la modalita station – la camera si unisce a una rete ospitata da qualcun altro. La modalita opposta, IF_AP, fa si che la camera ospiti la propria piccola rete a cui altri dispositivi possono unirsi; utile per interfacce di configurazione e installazioni sul posto, ma non e il caso comune.
Una volta che isconnected() ritorna True, la camera e sulla rete. Tutto il resto di cui i livelli superiori avevano bisogno per configurarsi e avvenuto automaticamente mentre il collegamento si attivava; le pagine che seguono illustrano quei pezzi uno alla volta.
9.4.3. Cosa puo andare storto#
A questo passaggio si presentano alcune modalita pratiche di fallimento.
Nome di rete o password errati. Il tentativo di connessione riprova silenziosamente finche l’applicazione non si arrende. Avvolgi l’attesa con un timeout in modo che il ciclo sopra non si blocchi per sempre:
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)
Fuori portata. La camera e il punto di accesso devono essere abbastanza vicini da garantire che il segnale sia abbastanza forte da mantenere un collegamento.
status()ritorna un codice che indica perche il collegamento non e attivo;scan()ritorna l’elenco delle reti che la radio riesce a vedere, ed e la diagnostica da eseguire quandoconnectnon ha successo.Il punto di accesso chiede piu di una password. Le reti aperte (senza password) e quelle comuni protette da password sono coperte da
connectcome mostrato sopra. Reti piu grandi presso luoghi di lavoro e scuole talvolta usano uno schema diverso in cui la camera deve autenticarsi presso un server di login separato; queste richiedono argomenti aggiuntivi perconnect. Vedi classe WLAN – controllo delle interfacce WiFi integrate per la superficie completa.
9.4.4. Restare connessi#
Attivare il collegamento e meta del problema. Restare connessi e l’altra meta – i punti di accesso si riavviano, la camera si allontana fuori portata, i lease DHCP scadono, il firmware della radio occasionalmente si blocca. Una camera destinata a vivere sulla rete per mesi deve accorgersene e recuperare da sola.
Lo schema di rilevamento consiste nel chiamare isconnected() una volta per ogni iterazione del ciclo principale e reagire quando ritorna False. isconnected() puo mentire per un breve istante quando una connessione e caduta senza che la radio se ne sia ancora accorta – un invio su socket che fallisce quando il collegamento «dovrebbe» essere attivo e l’altra prova della caduta a disposizione dell’applicazione. status() e la fonte piu autorevole quando le due sono in disaccordo.
Lo schema di riconnessione e disconnect() seguito da connect() con le stesse credenziali, con l’attesa avvolta in un timeout come nella connessione iniziale. Applica un’attesa crescente tra i tentativi – un secondo, due, quattro, raddoppiando fino a un minuto circa – in modo che un’interruzione prolungata non martelli l’AP e non bruci il budget di potenza della radio in cicli a vuoto:
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
Quando quella funzione di supporto continua a ritornare False, il firmware della radio stesso potrebbe essere bloccato. L’ultima risorsa e spegnere e riaccendere la radio: active(False), una breve pausa, active(True), riconnessione da zero. Questo riporta il firmware della radio a uno stato noto al costo di qualche secondo aggiuntivo di inattivita:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
Una camera rimasta fuori dalla rete per minuti e un fallimento reale che l’applicazione deve vedere. Il codice di recupero dovrebbe far emergere quello stato – contrassegnare la rete come non integra in un flag che il ciclo principale controlla, e lasciare che l’applicazione salti gli invii di rete che avrebbe effettuato finche il flag e attivo – in modo che un’interruzione prolungata non blocchi l’applicazione in attesa su socket che non scriveranno mai.
9.4.5. Ethernet, quando presente#
Le schede con Ethernet integrata espongono lo stesso schema senza il passaggio connect. L’interfaccia LAN viene attivata con active(), e non appena il cavo viene inserito l’interfaccia e pronta all’uso:
import network
lan = network.LAN()
lan.active(True)
print("link up")
Da questo punto in poi il resto delle pagine di questa sezione si applica allo stesso modo indipendentemente da quale interfaccia abbia portato la camera sulla rete. I livelli superiori non si curano se il collegamento sottostante sia Wi-Fi o Ethernet – «connesso» e «connesso».
Per il riferimento completo di WLAN e LAN, comprese le manopole di configurazione che non hanno trovato spazio qui, vedi network — configurazione di rete.