Using polling to auto-discover tags
The polling updater (see auto-update-polling.js) can (since v0.6.0) be used in "discovery mode". In this mode, all tag updates returned by the polling API endpoint are reported as tag objects with a data
event, whether a tag has been previously registered for receiving updates or not. This can be used to receive data updates on any tag accessible to the account, including tags dynamically added since the program first started.
In this mode, it is up to the application to either register newly discovered tags with the updater (which in essence caches the tag objects, and thus all additional state, such as their sensors), or to initialize each object from scratch. The former saves time between receiving the tag object and having access to all sensor data, whereas the latter keeps the memory footprint low even with thousands of tags.
The code in this tutorial is also available as a JavaScript file
(generated automatically from this tutorial) that can be run with
nodejs
. See the examples/
directory of the package.
Principle flow
The principle flow is similar to auto-update-polling.js, except that there is no need to first find tag manager and tag objects.
- Connect to cloud.
- Create polling tag updater, enabling discovery mode.
- Register event handler for
data
event. - If the
data
event fires, discover the tag's sensors. (Optionally, register handler for tag'sdata
event, and register tag for receiving future updates from the updater.) - Do something useful with the new data. Here we simply log useful properties for each sensor and tag (see read-sensors.js).
- Continue updating for a set period of time.
Create platform object
var Platform = require('wirelesstags');
var platform = Platform.create();
Create tag updater
For this we need to use the polling updater.
var TagUpdater = require('wirelesstags/plugins/polling-updater');
// must pass either 'platform' or 'options.factory' in discovery mode
var updater = new TagUpdater(platform, { discoveryMode: true });
How long to keep looping?
const END_AFTER = 30 * 60 * 1000; // value is in milliseconds
Connect to platform
For a better overview, we will use the Promise-based API for the principle flow here:
var connect = platform.signin(Platform.loadConfig());
Create and install event handler for updates
Next, we create and then install an event handler for the data
event. We write this so that it doesn't matter whether the event is
fired by the tag updater object or a tag, which allows changing the
code to register (cache) auto-discovered tag objects without changing
anything about the event handler.
function dataHandler(tag) {
// We can register new tag objects so their sensors don't need rediscovering
// However, this is optional, so feel free to comment it out.
if (tag.eachSensor().length === 0) {
tag.on('data', dataHandler);
updater.addTags(tag);
}
// tag.discoverSensors() always promises _all_ of the tag's sensors,
// so is robust to whether they were already discovered previously
tag.discoverSensors().then((sensors) => {
logTag(tag);
sensors.forEach(logSensor);
}).catch((e) => { console.error(e.stack ? e.stack : e); });
}
Then we register the handler with the updater for its data
event:
updater.on('data', dataHandler);
Start auto-update loop
Once platform.signin()
has succeeded, we can start the auto-update
loop (which now is an auto-discovery with update) loop.
connect.then(() => {
updater.startUpdateLoop();
// also stop after set duration
setTimeout(updater.stopUpdateLoop.bind(updater), END_AFTER);
}).catch((e) => { console.error(e.stack ? e.stack : e) });
Do something with tags and sensors
The actions for tags and sensors here are simply copied from read-sensors.js.
function logTag(tag) {
console.log("Tag", tag.name, "(slaveId=" + tag.slaveId + ")",
"of", tag.wirelessTagManager.name,
"(mac=" + tag.wirelessTagManager.mac + ")");
// console.log(".. properties:", tag.toString());
}
function logSensor(sensor) {
console.log("..", sensor.sensorType,
"of", sensor.wirelessTag.name + ":");
console.log(" reading:", sensor.reading);
if (sensor.eventState !== undefined) {
console.log(" state:", sensor.eventState);
console.log(" armed:", sensor.isArmed());
}
// console.log("... sensor properties:", sensor.toString());
}