9.4. A kapcsolat felépítése¶
Az előző oldalon tárgyalt kapcsolati réteg többnyire automatikus, de van egy hely, ahol egy Python-szkriptnek be kell avatkoznia: meg kell mondania a kamerának, melyik hálózathoz csatlakozzon. Amíg ez a lépés sikerül, a szakasz hátralévő részében tárgyalt egyetlen hálózati funkció sem fog működni.
9.4.1. A network modul¶
A network modul a kamera hálózatkezelő hardverét teszi elérhetővé a Python számára. Az interfészek pontos halmaza a kártyától függ: sok kamerában van egy vezeték nélküli chip, és egy WLAN osztályt tesz elérhetővé (a Wireless Local Area Network, azaz vezeték nélküli helyi hálózat után elnevezve); egyes kártyák beépített Ethernet-porttal is rendelkeznek, és egy LAN osztályt tesznek elérhetővé (a Local Area Network, azaz helyi hálózat után elnevezve, vagyis a vezetékes változat). A használat mintázata mindkettőnél azonos, egy fontos különbséggel: egy vezeték nélküli interfésznek meg kell mondani, melyik hálózathoz csatlakozzon, míg az Ethernet felveszi, ami a kábelen van.
9.4.2. A Wi-Fi folyamat¶
Egy Wi-Fi hálózathoz való csatlakozás három lépésből áll: hozd létre az interfészt, indítsd el, és kérd meg, hogy csatlakozzon egy megnevezett hálózathoz jelszóval. Az interfész a háttérben egyeztet a hozzáférési ponttal; egy isconnected() hívás jelzi, amikor a kapcsolat felépülése befejeződött:
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")
Az IF_STA argumentum a station (állomás) módot választja ki – a kamera egy olyan hálózathoz csatlakozik, amelyet valaki más üzemeltet. Az ellentétes mód, az IF_AP, arra készteti a kamerát, hogy a saját kis hálózatát üzemeltesse, amelyhez más eszközök csatlakozhatnak; ez konfigurációs felületekhez és helyszíni beállításhoz hasznos, de nem a gyakori eset.
Amint az isconnected() True értéket ad vissza, a kamera a hálózaton van. Minden más, amire a magasabb rétegeknek szükségük volt a saját beállításukhoz, automatikusan megtörtént, miközben a kapcsolat felépült; az előttünk álló oldalak ezeket a részeket egyenként taglalják.
9.4.3. Mi mehet rosszra¶
Néhány gyakorlati hibamód jelentkezik ennél a lépésnél.
Rossz hálózatnév vagy jelszó. A kapcsolódási kísérlet csendben újrapróbálkozik, amíg az alkalmazás fel nem adja. Vedd körül a várakozást egy időtúllépéssel, hogy a fenti hurok ne blokkoljon örökre:
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)
Hatótávolságon kívül. A kamerának és a hozzáférési pontnak elég közel kell lenniük egymáshoz, hogy a jel elég erős legyen a kapcsolat fenntartásához. A
status()egy kódot ad vissza, amely jelzi, miért nincs felépülve a kapcsolat; ascan()visszaadja azoknak a hálózatoknak a listáját, amelyeket a rádió lát, ami az a diagnosztika, amit akkor kell lefuttatni, amikor aconnectnem jár sikerrel.A hozzáférési pont többet kér, mint egy jelszó. A nyílt hálózatokat (jelszó nélkül) és a gyakori jelszóval védett hálózatokat a
connectlefedi a fent bemutatott módon. A munkahelyeken és iskolákban lévő nagyobb hálózatok néha eltérő sémát használnak, ahol a kamerának egy külön bejelentkezési kiszolgálóval szemben kell hitelesítenie magát; ezekhez extra argumentumok kellenek aconnecthíváshoz. A teljes felületért lásd: WLAN osztály – beépített WiFi interfészek vezérlése.
9.4.4. Kapcsolatban maradás¶
A kapcsolat felépítése a probléma fele. Kapcsolatban maradni a másik fele – a hozzáférési pontok újraindulnak, a kamera kibarangol a hatótávolságból, a DHCP-bérletek lejárnak, a rádió firmware-e időnként elakad. Egy kamerának, amely hónapokig a hálózaton fog élni, ezt észre kell vennie, és magától helyre kell állnia.
Az észlelési minta az, hogy a fő hurok minden iterációjában egyszer meghívod az isconnected() hívást, és reagálsz, amikor False értéket ad vissza. Az isconnected() rövid ideig hazudhat, amikor egy kapcsolat megszakadt anélkül, hogy a rádió ezt még észrevette volna – egy socketküldés, amely meghiúsul, amikor a kapcsolatnak „fenn kellene állnia”, az alkalmazás másik bizonyítéka a megszakadásra. A status() a hitelesebb forrás, amikor a kettő nem egyezik.
Az újracsatlakozási minta az disconnect(), amelyet az connect() követ ugyanazokkal a hitelesítő adatokkal, a várakozást egy időtúllépéssel körülvéve, mint a kezdeti kapcsolódásnál. Várj egyre többet a kísérletek között – egy másodperc, kettő, négy, megduplázva körülbelül egy percig –, hogy egy hosszú kimaradás ne hajszolja a hozzáférési pontot, és ne égesse el a rádió energiakeretét pörgő hurkokon:
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
Amikor ez a segédfüggvény folyamatosan False értéket ad vissza, lehet, hogy maga a rádió firmware-e elakadt. A végső megoldás a rádió ki-be kapcsolása: active(False), egy rövid szünet, active(True), és újracsatlakozás a nulláról. Ez egy ismert állapotba hozza vissza a rádió firmware-ét, néhány extra másodperc állásidő árán:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
Egy kamera, amely percek óta hálózaton kívül van, valódi hiba, amelyet az alkalmazásnak látnia kell. A helyreállító kódnak fel kell színre hoznia ezt az állapotot – jelölje meg a hálózatot egészségtelennek egy zászlóban, amelyet a fő hurok ellenőriz, és engedje, hogy az alkalmazás kihagyja azokat a hálózati küldéseket, amelyeket egyébként megtett volna, amíg a zászló tiszta –, hogy egy hosszú kimaradás ne akassza meg az alkalmazást olyan socketekre várva, amelyek soha nem fognak írni.
9.4.5. Ethernet, ha jelen van¶
A beépített Ethernettel rendelkező kártyák ugyanazt a mintát teszik elérhetővé a connect lépés nélkül. A LAN interfész az active() hívással indítható el, és amint a kábelt bedugják, az interfész használatra kész:
import network
lan = network.LAN()
lan.active(True)
print("link up")
Ezután a szakasz többi oldala ugyanúgy alkalmazható, függetlenül attól, melyik interfész juttatta a kamerát a hálózatra. A magasabb rétegeket nem érdekli, hogy az alattuk lévő kapcsolat Wi-Fi vagy Ethernet – a „csatlakoztatva” az „csatlakoztatva”.
A teljes WLAN és LAN referenciáért, beleértve azokat a konfigurációs beállításokat is, amelyek ide nem fértek be, lásd: network — hálózati konfiguráció.