Automatiser la configuration des YoctoHubs

Automatiser la configuration des YoctoHubs

Les YoctoHubs permettent de rendre accessible n'importe quel module Yoctopuce depuis d'un réseau Ethernet ou Wifi. Cela permet, par exemple, d'utiliser plusieurs capteurs de température dans différents bâtiments. Cependant, avant de pouvoir accéder au YoctoHub par un réseau, il faut tout d'abord configurer les paramètres du réseau. Il est possible d'utiliser le VirtualHub ou nos outils en ligne de commande, mais cette semaine nous allons voir comment automatiser cette étape en utilisant nos librairies.


Les YoctoHubs, comme tous nos modules, possèdent un port micro USB qui permet d'alimenter le module, mais aussi de configurer les paramètres réseau que le YoctoHub doit utiliser. Si vous avez de nombreux YoctoHubs à gérer, il est pratique de réaliser son propre programme de configuration qui applique automatiquement les paramètres réseau des YoctoHubs connecté par USB.

Les YoctoHub-Ethernet


Commençons par le YoctoHub-Ethernet qui permet de se connecter à un réseau filaire IPv4. Tous les paramètres réseau sont regroupés dans la fonction network du YoctoHub.

La plupart du temps lorsqu'on utilise un réseau filaire, la configuration réseau est fournie par un serveur DHCP. La méthode useDHCPauto de la classe YNetwork configure le YoctoHub pour qu'il interroge le serveur DHCP et récupéré ses paramètres réseau. Par défaut les YoctoHub-Ethernet sont configurés pour fonctionner dans ce mode, donc si vous avez un serveur DHCP sur votre réseau local, il n'est même pas nécessaire de se préoccuper de la configuration réseau.

Cependant, si vous avez besoin de configurer l'interface réseau pour utiliser une adresse IP fixe, c'est tout à fait possible. La méthode useStaticIP de la classe YNetwork prend en paramètre l'adresse IP, le masque de sous-réseau et l'adresse IP de la passerelle à utiliser. Attention, cette fonction n'utilise pas le masque de sous-réseau sous forme textuelle mais sous la forme d'un entier qui représente la longueur du masque. Par exemple pour utiliser le masque de sous-réseau "255.255.255.0" il faut passer 24 à la fonction useStaticIP, ce qui correspond au nombre de bits à 1. Les méthodes set_primaryDNS et set_secondaryDNS configurent le DNS primaire et secondaire.

La méthode get_readiness de la classe YNetwork retourne l'état le la connexion réseau, et permet par exemple de détecter si le câble n'est pas branché ou si le serveur DHCP ne répond pas.

Le code suivant est un exemple d'utilisation des fonctions mentionnées plus haut. La fonction configureNetwork a récupéré l'objet YNetwork du module avec le numéro de série passé en paramètre. Elle appelle la méthode useDHCPauto ou useStaticIP en fonction des paramètres passés, et attend que l'interface réseau ait appliqué la nouvelle configuration. Finalement l’adresse IP utilisée par le YoctoHub est affichée.

def getSubnetLen(subnet):
    split = subnet.split('.')
    subnet_int = (16777216 * int(split[0])) \
                 + (65536 * int(split[1])) \
                 + (256 * int(split[2])) \
                 + int(split[3])
    i = 0
    while (subnet_int & (1 << i)) == 0:
        i += 1
    return 32 - i


def configureNetwork(serial, useDHCP=True, ip="",
                     subnet="", gateway="", dns1="", dns2=""):
    print("Configure network function of " + serial)
    network = YNetwork.FindNetwork(serial + ".network")
    if not network.isOnline():
        print("Not a YoctoHub")
        return
    if useDHCP:
        print(" - Use DHCP")
        network.useDHCPauto()
    else:
        subnet_len = getSubnetLen(subnet)
        print(" - Use Static ip %s with subnet=%d  gateway=%s)" %
              (ip, subnet_len, gateway))
        network.useStaticIP(ip, subnet_len, gateway)
        network.set_primaryDNS(dns1)
        network.set_secondaryDNS(dns2)
    readiness = network.get_readiness()
    old_readiness = YNetwork.READINESS_INVALID
    while readiness != YNetwork.READINESS_LAN_OK and \
          readiness != YNetwork.READINESS_WWW_OK:
        YAPI.Sleep(500)
        if old_readiness != readiness:
            if readiness == YNetwork.READINESS_DOWN:
                print(" - Network is down")
            if readiness == YNetwork.READINESS_EXISTS:
                print(" - Network exists")
            if readiness == YNetwork.READINESS_LINKED:
                print(" - Network is linked")
            if readiness == YNetwork.READINESS_LAN_OK:
                print(" - Network is LAN ready")
            if readiness == YNetwork.READINESS_WWW_OK:
                print(" - Network has Internet access")
            old_readiness = readiness
        readiness = network.get_readiness()
    print("YoctoHub is accessible with the IP %s." %
          (network.get_ipAddress()))
    # do not forget to call saveToFlash() to make these settings persistent



En utilisant cette fonction, on peut configurer le YoctoHub YHUBETH1-1234 en mode DHCP avec le code suivant:

configureNetwork("YHUBETH1-1234", True)



Si, au contraire, on veut lui attribuer l'adresse IP 192.168.1.15 pour le sous réseau 255.255.0.0, la passerelle 192.168.1.1 et utiliser le serveur DNS 8.8.8.8, les paramètres à passer sont:

configureNetwork("YHUBETH1-1234", "192.168.1.15", "255.255.0.0",
                 "192.168.1.1", "8.8.8.8")



Attention, cette fonction ne sauve pas la nouvelle configuration. Pour que ces paramètres soient sauvés dans la mémoire flash du YoctoHub, il faut appeler la méthode saveToFlash du module.

Les YoctoHubs wireless


Les YoctoHubs wireless (YoctoHub-Wireless, YoctoHub-Wireless-SR et YoctoHub-Wireless-g) possèdent une fonction wireless en plus de la fonction network. La fonction network fonctionne de la même manière que le YoctoHub-Ethernet. La fonction wireless permet de configurer les paramètres du réseau sans fils: le SSID et le mot de passe. Cette fonction permet aussi de scanner les réseaux sans fils disponibles.

La classe YWireless possède une méthode joinNetwork qui permet de se connecter à un réseau WiFi. Cette méthode prend en paramètre le SSID du réseau ainsi que la clef d'authentification.

La méthode get_wlanState retourne l'état courant de l'interface wireless. Les différents états sont: WLANSTATE_DOWN, WLANSTATE_SCANNING, WLANSTATE_CONNECTED et WLANSTATE_REJECTED.

L'état WLANSTATE_DOWN signifie que l'interface réseau n'est pas utilisable. L'état WLANSTATE_SCANNING signifie que la carte réseau effectue un balayage des fréquences. C'est le cas lorsque la carte réseau construit la liste des réseaux disponibles mais aussi lorsque la carte réseau établit la connexion à un réseau sans fil. L'état WLANSTATE_CONNECTED signifie que la carte réseau a réussi à se connecter avec succès au réseau sans fil. Et l'état WLANSTATE_REJECTED, au contraire, signifie que la carte réseau n'a pas pu se connecter au réseau, soit car le réseau n'existe pas, soit car l'authentification n'a pas fonctionné. Dans ce cas, il est possible d'obtenir la raisons de l’échec à l'aide de la méthode get_message.

La fonction suivante utilise les méthodes que nous venons de mentionner pour configurer les paramètres WiFi et les paramètres réseau d'un YoctoHub wireless:

def configureWireless(serial, ssid, passkey="", useDHCP=True, ip="", subnet="",
                      gateway="", dns1="", dns2=""):
    print("Configure Wireless for " + serial)
    wireless = YWireless.FindWireless(serial + ".wireless")
    network = YNetwork.FindNetwork(serial + ".network")
    if not wireless.isOnline() or not network.isOnline():
        print("Not a wireless YoctoHub")
        return
    if wireless.get_wlanState() == YWireless.WLANSTATE_INVALID:
        print("YoctoHub " + serial + " is too old. ")
        print("please upgrade the firmware to use this function")
        return
    # set wireless settings
    wireless.joinNetwork(ssid, passkey)
    # set IP settings
    if useDHCP:
        print(" - Use DHCP")
        network.useDHCPauto()
    else:
        subnet_len = getSubnetLen(subnet)
        print(" - Use Static ip %s with  subnet=%d and gateway =%s)" %
              (ip, subnet_len, gateway))
        network.useStaticIP(ip, subnet_len, gateway)
        network.set_primaryDNS(dns1)
        network.set_secondaryDNS(dns2)
    # ensure that the wireless settings are correct
    last_message = ""
    networkState = wireless.get_wlanState()
    while networkState != YWireless.WLANSTATE_CONNECTED and \
          networkState != YWireless.WLANSTATE_REJECTED:
        message = wireless.get_message()
        if last_message != message:
            print(" - " + message)
            last_message = message
        YAPI.Sleep(500)
        networkState = wireless.get_wlanState()
    if networkState == YWireless.WLANSTATE_REJECTED:
        print("Unable to connect to %s network : %s" %
              (ssid, wireless.get_message()))
        return
    readiness = network.get_readiness()
    old_readiness = YNetwork.READINESS_INVALID
    while readiness != YNetwork.READINESS_LAN_OK and \
          readiness != YNetwork.READINESS_WWW_OK:
        if old_readiness != readiness:
            if readiness == YNetwork.READINESS_DOWN:
                print(" - Network is down")
            if readiness == YNetwork.READINESS_EXISTS:
                print(" - Network exists")
            if readiness == YNetwork.READINESS_LINKED:
                print(" - Network is linked")
            if readiness == YNetwork.READINESS_LAN_OK:
                print(" - Network is LAN ready OK")
            if readiness == YNetwork.READINESS_WWW_OK:
                print(" - Network as WWW ready")
            old_readiness = readiness
        YAPI.Sleep(500)
        readiness = network.get_readiness()

    print("YoctoHub is accessible with the IP %s (link=%d%%)." %
          (network.get_ipAddress(), wireless.get_linkQuality()))
    # do not forget to call saveToFlash() to make these settings persistent



Dans un premier temps, cette fonction applique les paramètres du réseau sans fil et les paramètres IP à l'aide des méthodes joinNetwork et useDHCPauto (ou useStaticIP). Ensuite, la fonction surveille l'état de la connexion et vérifie que le YoctoHub a pu s'enregistrer sur le réseau WiFi. Finalement, la fonction vérifie que la configuration IP a pu être appliquée et affiche l'adresse IP utilisée par le YoctoHub ainsi que la qualité du signal WiFi.

Tout comme pour l'exemple précédent, cette fonction ne sauve pas la nouvelle configuration. Pour que ces paramètres soient sauvés dans la mémoire flash du YoctoHub, il faut appeler la méthode saveToFlash du module.

Énumérer les réseaux disponibles


Nous venons de voir comment se connecter à un réseau sans fil, mais il est aussi possible de récupérer la liste des réseaux sans fil existants.

Attention, les YoctoHub wireless ne permettent pas de scanner les différentes fréquences WiFi en étant connecté à un réseau. Par conséquent, lorsque vous déclenchez un scan des réseaux, le YoctoHub se déconnecte du réseau actuel et n'est plus joignable. Cependant une fois le scan terminé, il se reconnecte automatiquement au réseau configuré.

Pour démarrer un balayage des fréquences Wifi, il faut appeler la méthode startWlanScan. La liste des réseaux détectés peut être récupérée à l'aide de la méthode get_detectedWlans. Cependant, bien que startWlanScan rende la main immédiatement, le balayage prend plusieurs secondes. Il faut donc attendre que le scannage des fréquences soit terminé avant d'appeler get_detectedWlans.

La fonction suivante déclenche un scan des réseaux disponibles et attend la fin de cette opération. Pour finir, elle affiche la liste des réseaux détectés.

def getAvailableWirelessNetwork(serial):
    print("Scan available wireless network from " + serial)
    wireless = YWireless.FindWireless(serial + ".wireless")
    if not wireless.isOnline():
        print("Not a wireless YoctoHub")
        return
    if wireless.get_wlanState() == YWireless.WLANSTATE_INVALID:
        print("YoctoHub " + serial + " is too old. ")
        print("please upgrade the firmware to use this function")
        return
    wireless.startWlanScan()
    networkState = wireless.get_wlanState()
    last_message = ""
    while networkState == YWireless.WLANSTATE_DOWN or \
          networkState == YWireless.WLANSTATE_SCANNING:
        message = wireless.get_message()
        if last_message != message:
            print(" - %s" % message)
            last_message = message
        YAPI.Sleep(100)
        networkState = wireless.get_wlanState()
    wlans = wireless.get_detectedWlans()
    print("Detected networks:")
    for wl in wlans:
        assert isinstance(wl, YWlanRecord)
        print(" - ssid:%s channel:%d quality:%d security:%s" %
              (wl.get_ssid(), wl.get_channel(),
              wl.get_linkQuality(), wl.get_security()))



Attention!


La méthode get_wlanState a été ajoutée très récemment, assurez-vous d'avoir une librairie et un firmware à jour.

Conclusion


Vous savez, dorénavant comment automatiser la configuration réseau de vos YoctoHubs. Dans un prochain article, on vous présentera comment automatiser la configuration d'une pile de modules branchés sur un YoctoHub.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.