Objetivo

 

  • Veremos que hay dos modos de trabajo de nuestro esp8266: STATION y Access Point.
  • Jugaremos con las librerías network y Socket.
  • Hablaremos de los sockets TCPIP y de cómo usarlos en MicroPython.
  •  

    Material requerido

     

    Node MCU board Node MCU V2 o V3

    micro usb
    Un cable USB a microUSB, como el de cualquier teléfono móvil

     

    Micropython y WIFI

     

    En esta sesión, vamos a jugar un poco más con instrucciones en el intérprete REPL, especialmente en lo que se refiere al WIFI interno, porque nos interesa poner encima de la mesa algunos conceptos adicionales, antes de entrar en otros temas, como volcar y ejecutar programas.

    Para ello voy poco menos que a copiar el magnífico tuto de que MicroPython dispone en la web oficial sobre el ESP8266.

    Y el primer concepto que necesitamos destacar, es que el ESP8266 tiene dos interfaces WIFI:

      • STATION: Que usamos para conectar a un Reuter WIFI.
      • AP, Access Point: al que se pueden conectar otros equipos en ausencia de Router WIFI.[/fancy-ul] [/three-fourth]

    Si queremos que nuestro modulo se conecte a un Router WIFI basta con activar el interface Station y suministrar el identificador de red o SSID mas la contraseña de acceso.

    Pero también podemos usar nuestro ESP8266 como un Router que proporciona acceso a otros dispositivos  y montar una red WIFI propia con los nodos que conectemos, lo cual nos facilitará mucha la vida cuando nos metamos con la IOT (Internet of Things).

      • Se piensa que el futuro inmediato de nuestra sociedad es moverse hacia una comunidad en la que incluso los objetos inanimados como ruedas, cerraduras o lámparas, además de hogares, frigoríficos y lavadoras, estarán conectadas a una red global TCPIP que permitirá la recolección y envío de información relativa a las cosas más nimias.
      • Esto unido a una red global que permita la conexión de todo con todo y bancos de servidores que procesen esa información va a cambiar profundamente la sociedad y el mundo que conocemos.

    En MicroPython disponemos de una serie de librerías para controlar las conexiones WIFI:

    import network

    Y ahora podemos levantar ambos Interfaces:

    sta_if = network.WLAN(network.STA_IF)
    ap_if = network.WLAN(network.AP_IF)

    instrucciones micropython

    Podemos ver la situación de los dos interfaces:

    >>> sta_if.active()
    False
    >>> ap_if.active()
    True

    Micropython interfaces

    Aquí tenemos ya la primera noticia interesante. El NodeMCU activa por defecto el interface AP o Access Point, pero no el Station (Aunque podemos programarlo en el arranque). De este modo viene preprogramado como un punto de acceso para otros dispositivos WIFI, de modo que no necesitemos un router adicional para configurar una red entre nodos.

    Si queremos conocer que valores trae por defecto:

    ap_if.ifconfig()

    configuando interfaces

    Que son, respectivamente: dirección IP, Mascara, Gateway y DNS.

    Vamos a conectar nuestro interface Station a mi red WIFI:

    sta_if.active(True)                               # Activar interface
    sta_if.connect('prometec', 'contrase')            # Conectar con SSID / Pass
    sta_if.ifconfig()                                 # Muestra datos de la conexión
    ap_if.active(False)                               # Desactiva el ap interface

    Observa como el sta_if tiene ya un valor IP que corresponde con mi red (192.168.0.xx, podéis creerme, es lo que corresponde a  mi red)    

    Como podéis ver, la sintaxis es más o menos liosa, pero una vez que la conectes, es muy fácil programar una conexión. SI quieres escribir un programa que conecte automáticamente a la red de tu entorno, los chicos de micropython nos proponen este programa:

    def do_connect():
        import network
        sta_if = network.WLAN(network.STA_IF)
        if not sta_if.isconnected():
            print('connecting to network...')
            sta_if.active(True)
            sta_if.connect('<essid>', '<password>')
            while not sta_if.isconnected():
                pass
        print('network config:', sta_if.ifconfig())

     

    Sockets

     

    Hemos visto como activar los interfaces y conectarlos a una red WIFI, pero en TCPIP la comunicación real se efectúa a través de un concepto que suele dar muchos dolores de cabeza a los novicios y que se llama Sockets (Zócalos en cristiano).

    Para fijar la idea básica diremos que cuando dos nodos conectados mediante TCPIP, deben establecer un socket. Es algo que se parece bastante a establecer una llamada de teléfono, necesitamos abrir una línea de comunicación y para eso es imprescindible el número de teléfono del destino. Una vez abierta la línea, es como haber conectado un punto con otro mediante un cable y por tanto hay un camino físico entre los dos extremos (Antiguamente era así).

    Hay todo un protocolo en el que solicitas línea, el otro extremos la acepta y se abre la comunicación hasta que uno de los dos la corte, y abrir un socket se parece mucho a esto, pero si los teléfonos necesitan un número de teléfono ajeno (Con quien queremos hablar) en TCPIP necesitamos la dirección IP del destino… y un puerto, que es un concepto que no existe en las llamadas de teléfono.

    Ten en cuenta que cuando tu llamas por teléfono solo quieres abrir una línea porque no puedes mantener más de una conversación simultánea, pero en cambio los ordenadores pueden requerir más de una línea de comunicación, (Porque a veces estás hablando con un servidor de email para coger correo y a la vez accediendo a la página web que existe en el mismo servidor, y eso mientras descargas un fichero del mismo servidor con FTP) y cada línea debe estar aislada de los mensajes que envías y recibes en las demás líneas.

    En Internet, toda la comunicación entre nodos se realiza abriendo un socket entre tu nodo y el remoto que se asigna a una dirección IP (La remota) y con una puerta definida (Port) que encapsula los mensajes entre origen y destino con un canal adicional de modo que puedes mantener varias líneas simultaneas con un servidor de destino, para programas diferentes (Email, FTP, HHTP… etc.),

    • La idea de port se parece más a una dirección  postal en el que tu dirección y la del vecino del 4º son la misma pero se diferencian por un numero de puerta de la vivienda (O bien por el número de piso, mano, etc.)
    • La costumbre de traducir port por puerto, en lugar de puerta, ha producido muchos dolores de cabeza innecesarios a los que empiezan con estas cosas.

    Quédate con la idea de que siempre que estableces una conexión para comunicación en TCPIP lo haces mediante un socket con una dirección IP y un port. Existen ports mas o menos estándar para ciertos servicios básicos ( Como el 80 para HTTP) porque si no, no podrías saber en que puerto se le ha ocurrido al colgado del informático poner el servidor.

    • De hecho se montan rutinariamente servicios, como servidores web, en puertos no estándar.
    • Imagínate que montamos un servidor web en el puerto 23215. Aunque conozcas la dirección IP del servidor, necesitas saber el port en que el servidor web responde, y como hay 65.536 ports posibles, ir probando no es buena idea.
    • Imagínate que quieres poner un servidor interno solo para empleados, lo puedes poner en Internet en un puerto no estándar y así limitas que entre nadie por casualidad, aunque los piratas tienen otras herramientas para encontrarlos.

    Una vez establecida nuestra conexión WIFI con el NodeMCU, podemos abrir sockets desde nuestro nodo a otros en la red, mediante el uso de (Sorpresa) otra librería:

    import socket

    Y ahora podemos buscar la dirección IP del servidor mediante su URL:

    addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)

    import sockets

    La función socket.getaddrinfo () trae un poco más de información de la que necesitamos (Cosas raras del TCPIP) y por eso queremos quedarnos solo con la dirección IP y el Puerto que nos recomienda,

    addr = addr_info[0][-1]                 # Solo queremos IP & port

    Comprueba la diferencia entre ambos:

    >>> addr_info
    [(2, 1, 0, '', ('94.142.241.111', 23))]
    >>> addr
    ('94.142.241.111', 23)
    >>>

    obteniendo la direccion IP

    Una vez que tenemos la dirección IP y el port adecuado podemos conectar con el servidor:

    s = socket.socket()
    s.connect(addr)

    informacion del socket

    Fíjate que hemos usado un puerto 23, o sea es un telnet, y una vez que tenemos el socket abierto podemos recibir la información del servidor con:

    while True:
    ...     data = s.recv(500)
    ...     print(str(data, 'utf8'), end='')

    accediendo a telnet

    Cuando pulses unos cuantos intros recibirás en pantalla una serie de textos relativos a star wars que demuestran que hay cantidad de gente a quien le sobra el tiempo por ahí.

     

    Resumen de la sesión

     

  • Hemos visto. que tenmos dos modos de trabajo: Station y Acces Point.
  • Vimos como conectar a la red.
  • Presentamos las librerias network y socket. [/three-fourth][margin value=»5″ /]
  •    

    Deja una respuesta