Automating YoctoHub configuration

Automating YoctoHub configuration

YoctoHubs allow you to make available any Yoctopuce module from an Ethernet or Wifi network. This enables you, for example, to use several temperature sensors in distinct buildings. However, before you can access a YoctoHub through the network, you must first configure its network parameters. You can use the VirtualHub or our command line tools, but this week, we are going to see how to automate this step using our libraries.


YoctoHubs, like all of our modules, have a micro USB port used to power the module, but also to configure the network parameters that the YoctoHub must use. If you need to manage a large number of YoctoHubs, you should consider implementing your own configuration software to automatically apply the network parameters of YoctoHubs connected by USB.

YoctoHub-Ethernet


Let's start with the YoctoHub-Ethernet which enables you to be connected through the IPv4 wired network. All the network parameters are grouped together in the network function of the YoctoHub.

Most of the time, when you use a wired network, the network configuration is provided by a DHCP server. The useDHCPauto method of the YNetwork class configures the YoctoHub to question the DHCP server and to retrieve its network parameters. By default, YoctoHub-Ethernet are configured to work in this mode. So, if you have a DHCP server on your local network, you don't even have to take care of the network configuration.

However, if you need to configure the network interface to use a fixed IP address, it's quite feasible. The useStaticIP method of the YNetwork class takes as parameters the IP address, the subnet mask, and the IP address of the gateway to be used. Note, this function doesn't use the subnet mask in a text format, but as an integer representing the length of the mask. For example, to use the "255.255.255.0" subnet mask, you must pass 24 to the useStaticIP function, which corresponds to the number of bits at 1. The methods set_primaryDNS and set_secondaryDNS set the primary and secondary DNS server.

The get_readiness method of the YNetwork class returns the state of the network connection and enables you to detect if a cable isn't connected or if a DHCP server doesn't answer.

The following code is a usage example of the functions mentioned above. The configureNetwork function retrieved the YNetwork object of the module of which the serial number was given as parameter. It calls the useDHCPauto or useStaticIP function depending on the given parameters, and waits for the network interface to apply the new configuration. Finally, the IP address used by the YoctoHub is displayed.

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



By using this function, you can configure the YoctoHub YHUBETH1-1234 in DHCP mode with the following piece of code:

configureNetwork("YHUBETH1-1234", True)



If, in the opposite, you want to assign is the 192.168.1.15 IP address, for the 255.255.0.0 subnet, the 192.168.1.1 gateway and the DNS server 8.8.8.8, you must pass the following parameters:

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



Note, this function doesn't save the new configuration. For these parameters to be saved in the YoctoHub flash memory, you must call the module saveToFlash method.

Wireless YoctoHubs


The wireless YocoHubs (YoctoHub-Wireless, YoctoHub-Wireless-SR, and YoctoHub-Wireless-g) have a wireless function on top of the network function. The network function works in the same way as that of the YoctoHub-Ethernet. The wireless function enables you to configure the wireless network parameters: SSID and password. This function also allows you to scan the available wireless networks.

The YWireless class has a joinNetwork method enabling it to connect itself to a Wifi network. This function takes as parameter the network SSID as well as its authentication key.

The get_wlanState method returns the current state of the wireless interface. The possible states are WLANSTATE_DOWN, WLANSTATE_SCANNING, WLANSTATE_CONNECTED, and WLANSTATE_REJECTED.

The WLANSTATE_DOWN state means that the network interface is not ready. The WLANSTATE_SCANNING state means that the network card is scanning the frequencies. This happens when the network card builds the list of available networks, but also when the network card sets up the connection with a wireless network. The WLANSTATE_CONNECTED state means that the network card succeeded in connecting to the wireless network. And the WLANSTATE_REJECTED state, in the opposite, means that the network card couldn't connect to the network, whether because the network doesn't exist, or because the authentication wasn't successful. In this case, you can obtain the cause of the failure with the get_message method.

The following function uses the methods that we mentioned just now to configure the Wifi parameters and the network parameters of a wireless YoctoHub:

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



Firstly, this function applies the wireless network parameters and IP parameters with the joinNetwork and useDHCPauto (or useStaticIP) methods. Then, the function monitors the connection state and checks that the YoctoHub was able to register on the Wifi network. Finally, the function checks that the IP configuration was applied and displays the IP address used by the YoctoHub as well as the quality of the Wifi signal.

As for the preceding example, this function doesn't save the new configuration. For these parameters to be saved in the YoctoHub flash memory, you must call the module saveToFlash method.

Listing the available networks


We saw how to connect a YoctoHub to a wireless network, but you can also retrieve the list of existing wireless networks.

Note, the wireless YoctoHubs cannot scan the different Wifi frequencies while staying connected to a network. Therefore, when you trigger a network scan, the YoctoHub disconnects from the current network and you can't reach it. However, when the scan is done, it reconnects itself automatically on the configured network.

To start a Wifi frequency scan, you must call the startWlanScan method. You can retrieve the list of detected networks with the get_detectedWlans method. However, although startWlanScan returns control immediately, the scan can take several seconds. You must therefore wait until the frequency scan is done before you call get_detectedWlans.

The following function triggers a network scan and waits for the end of this process. Finally, it displays the list of detected networks.

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()))



Important note!


Note that we added the get_wlanState method very recently. Make sure you have up-to-date firmware and libraries.

Conclusion


You now know how to automate the network configuration of your YoctoHubs. In a coming post, we'll show you how to automate the configuration of a stack of modules connected to a YoctoHub.

Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.