YoctoHubs and Discovery

YoctoHubs and Discovery

You may have guessed it because you have already used Yocto-Discovery, but if your application uses network hubs, it doesn't necessarily need to know their IP address to establish communication with them. It can also try to discover them by itself: the YoctoHub-Ethernet and YoctoHub-Wireless implement the SSDP protocol (Simple Service Discovery Protocol) which makes possible to discover devices present on a local network.



In almost all Yoctopuce programming libraries you can find examples which enable you to discover the Yoctopuce hubs present on your network. In fact, there are two variants of the discovery code.

Variant 1

The first technique consists in using YAPI.RegisterHubDiscoveryCallback() to setup a callback which is called each time a hub is discovered, then to wait for hubs to show up. Note, the callback is only called during a call to YAPI.UpdateDeviceList().

The callback is called each time a hub shows up. The calling parameters of the callback are the serial number and the character string that you can use to connect to the hub with a call to YAPI.RegisterHub(). The simplest example than one could write looks like the code below. It's in Python, but it works also in most other languages.

from yocto_api import *

def HubDiscovered(serial, url):
    print("hub found: " + serial + " (" + url + ")")

YAPI.RegisterHubDiscoveryCallback(HubDiscovered)
errmsg = YRefParam()

# wait for 30 seconds, doing nothing but waiting
for j in range(30):
    YAPI.UpdateDeviceList(errmsg)
    YAPI.Sleep(1000, errmsg)


When you call YAPI.RegisterHubDiscoveryCallback(), the API automatically broadcasts a UDP packet on the local network, asking all devices connected to this network to manifest themselves. As UDP doesn't guarantee that each packet reaches its destination, this discovery packet is in fact sent twice with a small random delay between the two packets. When they receive one of these packets, network devices supporting SSDP answer though a UDP packet to register. In real life, there is a small risk that devices try to answer at more or less the same time and that a few answers get lost. Therefore, each hub, when it receives the SSPD discovery packet, registers twice in a row with a more or less random interval before each of the two answers.

The HubDiscoveryCallback() callback is systematically called for each received answer. It's therefore likely that it is called up to four times for each found hub. It's normal and it's your job to filter the hubs that you already know. In the library examples, we do it with a simple dictionary.

Moreover, you must know that hubs spontaneously announce their presence at start up and then twice per hour. If you need to trigger a new discovery cycle, you can call YAPI.TriggerHubDiscovery().

Variant 2

There is a second method enabling you to discover all the hubs present on a local network: if you call YAPI.RegisterHub() with the "net" parameter, the effect is to trigger a discovery and to automatically register all the hubs which answer. You can then detect the arrival of new hubs with YAPI.RegisterDeviceArrivalCallback().

from yocto_api import *

def arrivalCallback(dev):
    print("new device : " + dev.get_friendlyName())

errmsg = YRefParam()
if YAPI.RegisterHub("net", errmsg) != YAPI.SUCCESS:
    sys.exit("init error" + errmsg.value)

YAPI.RegisterDeviceArrivalCallback(arrivalCallback)

# wait for 30 seconds, doing nothing.
for j in range(30):
    YAPI.UpdateDeviceList(errmsg)
    YAPI.Sleep(1000, errmsg)



With this method, the API literally performs the equivalent of a YAPI.RegisterHub() for all the hubs that it finds, which implies that we will received a DeviceArrivalCallback not only for each discovered hub but also for all the modules which are connected to them.

Limitations

The discovery feature of the API has its limitations: for it to work, all the players involved must be able to receive UDP packets on port 1900. So, if it doesn't work at all, start by checking the configuration of your firewalls. Moreover, you must know that as SSDP is based on multicast addresses, SSDP packets cannot cross from one sub-network to another, unless you explicitly configured your routers so that they accept to let them go through. On top of this, SSDP packets cannot for any reason go out of your local network. In other words, most of the time you can only see the hubs which are on the same sub-network as the machine which runs your discovery code.

SSDP is not implemented in the YoctoHub-GSM because it wouldn't make any sense. YoctoHub-GSM will never find themselves on the same local network as the machine which runs your code.

Discovery is not available in the JavaScript, TypeScript, and PHP libraries because they are languages which do not allow you to easily send or receive UDP packets.

The API filters the SSDP answers that it receives and keeps only those which are related to Yoctopuce hardware. You can't use it to discover non-Yoctopuce devices.

Disabling

If, for your own reasons, you don't want applications to be able to discover your Yoctopuce hubs, you can disable this feature in their network configuration with, for example, the command line API. Let's assume that the IP address of the hub of which you want to disable the discovery is 192.168.1.123, the command line is then:

C:\>ynetwork -r 192.168.1.123 -s any set_discoverable 0


One last thing

We recently discovered and corrected a bug in the discovery code of the YoctoHubs. If you intend to use this feature, you had better update the firmware of all you hubs :-)

Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.