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.