9.4. Levantar el enlace¶
La capa de enlace cubierta en la página anterior es en su mayoría automática, pero hay un lugar en el que un script de Python tiene que intervenir: decirle a la cámara a qué red unirse. Hasta que ese paso tenga éxito, ninguna de las funciones de red que cubre el resto de esta sección funcionará.
9.4.1. El módulo network¶
El módulo network expone a Python el hardware de redes de la cámara. El conjunto exacto de interfaces depende de la placa: muchas cámaras tienen un chip inalámbrico y exponen una clase WLAN (llamada así por Wireless Local Area Network); algunas placas también tienen un puerto Ethernet integrado y exponen una clase LAN (llamada así por Local Area Network, es decir, la versión cableada). El patrón de uso es el mismo para ambas, con una diferencia importante: hay que indicarle a una interfaz inalámbrica a qué red unirse, mientras que Ethernet toma lo que haya en el cable.
9.4.2. El flujo de Wi-Fi¶
Unirse a una red Wi-Fi son tres pasos: construir la interfaz, levantarla y pedirle que se conecte a una red nombrada con una contraseña. La interfaz negocia con el punto de acceso en segundo plano; una llamada a isconnected() informa de cuándo ha terminado de levantarse el enlace:
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")
El argumento IF_STA selecciona el modo station – la cámara se une a una red que aloja otra persona. El modo opuesto, IF_AP, hace que la cámara aloje su propia pequeña red a la que otros dispositivos pueden unirse; útil para interfaces de configuración y para la puesta en marcha in situ, pero no es el caso común.
Una vez que isconnected() retorna True, la cámara está en la red. Todo lo demás que las capas superiores necesitaban para configurarse ha ocurrido automáticamente mientras se levantaba el enlace; las páginas siguientes detallan esas piezas una a una.
9.4.3. Qué puede salir mal¶
Unos cuantos modos de fallo prácticos aparecen en este paso.
Nombre de red o contraseña incorrectos. El intento de conexión reintenta en silencio hasta que la aplicación se rinde. Envuelve la espera con un tiempo límite para que el bucle anterior no se bloquee para siempre:
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)
Fuera de alcance. La cámara y el punto de acceso tienen que estar lo bastante cerca como para que la señal sea lo bastante fuerte para mantener un enlace.
status()retorna un código que indica por qué el enlace no está activo;scan()retorna la lista de redes que la radio puede ver, que es el diagnóstico a ejecutar cuandoconnectno tiene éxito.El punto de acceso pide más que una contraseña. Las redes abiertas (sin contraseña) y las comunes protegidas por contraseña están cubiertas por
connectcomo se muestra arriba. Las redes más grandes en lugares de trabajo y escuelas a veces usan un esquema diferente en el que la cámara tiene que autenticarse contra un servidor de inicio de sesión separado; esas necesitan argumentos adicionales paraconnect. Consulta clase WLAN – controla las interfaces WiFi integradas para ver toda la superficie.
9.4.4. Mantenerse conectado¶
Levantar el enlace es la mitad del problema. Mantenerse conectado es la otra mitad – los puntos de acceso se reinician, la cámara se aleja del alcance, las concesiones DHCP caducan, el firmware de la radio de vez en cuando se atasca. Una cámara que va a vivir en la red durante meses tiene que detectar eso y recuperarse por sí misma.
El patrón de detección es llamar a isconnected() una vez por iteración del bucle principal y reaccionar cuando retorne False. isconnected() puede mentir brevemente cuando una conexión se ha caído sin que la radio se haya dado cuenta todavía – un envío de socket que falla cuando el enlace «debería» estar activo es la otra evidencia de una caída que tiene la aplicación. status() es la fuente más autoritativa cuando ambos discrepan.
El patrón de reconexión es disconnect() seguido de connect() con las mismas credenciales, con la espera envuelta en un tiempo límite como en la conexión inicial. Aplica un retroceso entre intentos – un segundo, dos, cuatro, duplicando hasta un minuto más o menos – para que una interrupción larga no machaque al punto de acceso y no consuma el presupuesto de energía de la radio en bucles de espera activa:
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
Cuando ese helper sigue retornando False, puede que el propio firmware de la radio esté atascado. El último recurso es apagar y encender la radio: active(False), una breve pausa, active(True), y reconectar desde cero. Esto devuelve el firmware de la radio a un estado conocido, a costa de unos segundos adicionales de inactividad:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
Una cámara que ha estado fuera de la red durante minutos es un fallo real que la aplicación tiene que ver. El código de recuperación debería exponer ese estado – marcar la red como no saludable en un indicador que el bucle principal compruebe, y dejar que la aplicación se salte los envíos de red que habría hecho mientras el indicador esté activo – para que una interrupción larga no detenga la aplicación esperando en sockets que nunca van a escribir.
9.4.5. Ethernet, cuando está presente¶
Las placas con Ethernet integrado exponen el mismo patrón sin el paso de connect. La interfaz LAN se levanta con active(), y en cuanto se enchufa el cable la interfaz está lista para usarse:
import network
lan = network.LAN()
lan.active(True)
print("link up")
A partir de este punto, el resto de las páginas de esta sección se aplican del mismo modo, independientemente de qué interfaz haya puesto a la cámara en la red. A las capas superiores no les importa si el enlace que tienen debajo es Wi-Fi o Ethernet – «conectado» es «conectado».
Para la referencia completa de WLAN y LAN, incluyendo los ajustes de configuración que no cabían aquí, consulta network — configuración de red.