9.4. Aktywowanie łącza¶
Warstwa łącza omówiona na poprzedniej stronie jest w większości automatyczna, ale jest jedno miejsce, w którym skrypt Pythona musi wkroczyć: poinformowanie kamery, do której sieci ma dołączyć. Dopóki ten krok się nie powiedzie, żadna z funkcji sieciowych omawianych w dalszej części tej sekcji nie zadziała.
9.4.1. Moduł network¶
Moduł network udostępnia Pythonowi sprzęt sieciowy kamery. Dokładny zestaw interfejsów zależy od płytki: wiele kamer ma układ bezprzewodowy i udostępnia klasę WLAN (nazwaną od Wireless Local Area Network); niektóre płytki mają również wbudowany port Ethernet i udostępniają klasę LAN (nazwaną od Local Area Network, czyli wersji przewodowej). Sposób użycia jest taki sam dla obu, z jedną ważną różnicą: interfejsowi bezprzewodowemu trzeba powiedzieć, do której sieci ma dołączyć, podczas gdy Ethernet odbiera to, co jest na kablu.
9.4.2. Przebieg dla Wi-Fi¶
Dołączenie do sieci Wi-Fi to trzy kroki: utworzenie interfejsu, jego aktywowanie i poproszenie go o połączenie z nazwaną siecią przy użyciu hasła. Interfejs negocjuje z punktem dostępowym w tle; wywołanie isconnected() informuje, kiedy łącze zakończyło aktywację:
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")
Argument IF_STA wybiera tryb station – kamera dołącza do sieci, którą hostuje ktoś inny. Tryb przeciwny, IF_AP, sprawia, że kamera hostuje własną małą sieć, do której mogą dołączyć inne urządzenia; przydatne w przypadku interfejsów konfiguracyjnych i konfiguracji na miejscu, ale nie jest to typowy przypadek.
Gdy isconnected() zwróci True, kamera jest w sieci. Wszystko inne, czego wyższe warstwy potrzebowały do skonfigurowania się, wydarzyło się automatycznie, gdy łącze było aktywowane; kolejne strony omawiają te elementy po kolei.
9.4.3. Co może pójść nie tak¶
Na tym etapie pojawia się kilka praktycznych trybów awarii.
Błędna nazwa sieci lub hasło. Próba połączenia po cichu ponawia się, dopóki aplikacja nie zrezygnuje. Otocz oczekiwanie limitem czasu, aby powyższa pętla nie blokowała się w nieskończoność:
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)
Poza zasięgiem. Kamera i punkt dostępowy muszą być na tyle blisko siebie, aby sygnał był wystarczająco silny do utrzymania łącza.
status()zwraca kod wskazujący, dlaczego łącze nie jest aktywne;scan()zwraca listę sieci, które widzi radio, co jest diagnostyką do uruchomienia, gdyconnectsię nie powiedzie.Punkt dostępowy wymaga czegoś więcej niż hasła. Sieci otwarte (bez hasła) oraz powszechne sieci chronione hasłem są obsługiwane przez
connectw sposób pokazany powyżej. Większe sieci w miejscach pracy i szkołach czasami używają innego schematu, w którym kamera musi uwierzytelnić się względem osobnego serwera logowania; te wymagają dodatkowych argumentów dlaconnect. Pełną powierzchnię znajdziesz w klasa WLAN – sterowanie wbudowanymi interfejsami WiFi.
9.4.4. Utrzymywanie połączenia¶
Aktywowanie łącza to połowa problemu. Utrzymanie połączenia to druga połowa – punkty dostępowe się restartują, kamera wychodzi poza zasięg, dzierżawy DHCP wygasają, a oprogramowanie układowe radia od czasu do czasu się zawiesza. Kamera, która ma żyć w sieci przez miesiące, musi to zauważyć i samodzielnie się odbudować.
Wzorzec wykrywania polega na wywoływaniu isconnected() raz na iterację głównej pętli i reagowaniu, gdy zwróci False. isconnected() może chwilowo kłamać, gdy połączenie zostało zerwane, zanim radio to zauważyło – nieudane wysłanie przez gniazdo, gdy łącze „powinno” być aktywne, to drugi dowód aplikacji na zerwanie. status() jest bardziej wiarygodnym źródłem, gdy te dwa się nie zgadzają.
Wzorzec ponownego łączenia to disconnect(), a następnie connect() z tymi samymi poświadczeniami, z oczekiwaniem otoczonym limitem czasu jak przy pierwszym połączeniu. Stosuj odczekiwanie między próbami – jedna sekunda, dwie, cztery, podwajając aż do około minuty – aby długa awaria nie zarzucała punktu dostępowego żądaniami i nie zużywała budżetu mocy radia na pętle aktywnego oczekiwania:
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
Gdy ten pomocnik wciąż zwraca False, samo oprogramowanie układowe radia może być zaklinowane. Ostatecznością jest wyłączenie i ponowne włączenie radia: active(False), krótka pauza, active(True), ponowne połączenie od zera. To przywraca oprogramowanie układowe radia do znanego stanu kosztem kilku dodatkowych sekund niedostępności:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
Kamera, która od kilku minut jest poza siecią, to prawdziwa awaria, którą aplikacja musi dostrzec. Kod odzyskiwania powinien uwidocznić ten stan – oznaczyć sieć jako niesprawną we fladze sprawdzanej przez główną pętlę i pozwolić aplikacji pomijać wysyłki sieciowe, które wykonałaby, gdy flaga jest wyczyszczona – tak aby długa awaria nie wstrzymywała aplikacji oczekującej na gniazda, które nigdy nie zapiszą danych.
9.4.5. Ethernet, gdy jest obecny¶
Płytki z wbudowanym Ethernetem udostępniają ten sam wzorzec bez kroku connect. Interfejs LAN jest aktywowany za pomocą active(), i gdy tylko kabel zostanie podłączony, interfejs jest gotowy do użycia:
import network
lan = network.LAN()
lan.active(True)
print("link up")
Od tego momentu pozostałe strony tej sekcji mają zastosowanie w ten sam sposób, niezależnie od tego, który interfejs wprowadził kamerę do sieci. Wyższe warstwy nie dbają o to, czy łącze pod nimi to Wi-Fi czy Ethernet – „połączony” znaczy „połączony”.
Pełną dokumentację WLAN i LAN, w tym pokrętła konfiguracyjne, które się tutaj nie zmieściły, znajdziesz w network — konfiguracja sieci.