While implementing Yocto-Discovery, we noticed that we were missing a feature in our API: a fast and asynchronous way to detect state changes for the localisation beacon. This week, we publish a new version of our programming libraries including this new feature.
You could already obtain the state of the localisation beacon with the get_beacon() method of the YModule object, but you needed to do it explicitly and, in the case of an application monitoring many modules such as Yocto-Discovery, this implied having a dedicated thread which periodically queried all the modules. Not only was it complex to code, but also it wasn't very efficient. Indeed, if you wanted the application to quickly detect state changes, for example within a second, you had to call this method at least each second on all the connected modules.
This solution had another side effect. To be more efficient, the get_XXX methods download all the attributes of a module at the same time and caches them. Most of the time, this strategy enables us to minimize network traffic. However, in the case of an application which monitors only the state of the localisation beacon, this strategy is counter-productive and increases the quantity of transferred data.
The registerBeaconCallback() method
Our new method works asynchronously, that is, instead of periodically querying the module to know if the localisation beacon changed states, we register a callback which is called as soon as a change is detected. This solution has several advantages.
First, it is a lot more efficient. It's the module CPU which detects the beacon change of state and sends a packet of a few bytes to the programming library. This enables us to decrease the quantity of transferred data. If no one presses the localisation beacon, no data is transferred.
Moreover, you don't need to code the detection of the localisation beacon state change in the application, you only need to register a callback function with the registerBeaconCallback() method of the YModule object.
The callback function receives as arguments the pointer to the YModule object of the module under scrutiny, and the new value of the beacon. As with value callbacks, this callback is called only during the execution of YAPI.Sleep() or YAPI.HandleEvents(). This enables the application to control when callbacks can occur.
A C# example
We must start by defining the callback function. The first argument of this function is the object of type YModule referencing our module. the second argument is an integer corresponding to the state of the localisation beacon.
{
string serial = m.get_serialNumber();
string b_state = beacon == YModule.BEACON_ON ? "ON" : "OFF";
Console.WriteLine("Beacon of " + serial + " changed to " + b_state);
}
Then, for the modules that we want to monitor, we must call the registerBeaconCallback method to register our callback function.
while (m != null) {
m.registerBeaconCallback(beaconChange);
Console.WriteLine("monitor "+ m.get_serialNumber() + " beacon");
m = m.nextModule();
}
Finally, we must add in our main loop a call to YAPI.Sleep or to YAPI.HandleEvents.
....
YAPI.Sleep(500, ref errmsg)
...
YAPI.HandleEvents(ref errmsg);
}
A few comments
In this post, we showed you how to use this callback in C#, but the same methods are available in all of our libraries. The name of the methods and the way they work are identical with two exceptions:
For the JavaScript/EcmaScript 2017 library, you don't need to call the YAPI.Sleep or YAPI.HandleEvents method as JavaScript doesn't use threads.
In Java and under Android, the registerBeaconCallback() method takes as argument an object which implements the YModule.BeaconCallback interface.
We have modified the Prog-EventBased example in all of our libraries to add the use of the registerBeaconCallback() method. This provides you with a working example in any language.
You can download our libraries from our web site or from GitHub. Naturally, if you encounter any issue, you can always contact support: support@yoctopuce.com.