Razberry, binding to events and communicating device state changes

It all started about a week ago, when I became the owner of a very good looking Fibaro Motion sensor:

Fibaro FGMS-001

Compared to a Visonic motion sensor (to the right), this Fibaro is small. And very nice to see as well if I may say so. And that’s not it, there’s more inside than just motion:

  • A temperature sensor;
  • Light intensity;
  • an accelerometer to detect tampering.

And now that I’ve got one, it was time to give the Razberry, which has been unused for the last 18 months, another try.

So I took a spare Raspberry Pi, downloaded a complete image from hereĀ and started fiddling with the web-interface which is at http://<RPi-IP-address>:8083 . I have more Zwave devices than just this Fibaro FGMS-001 Motion sensor, so I chose to start with including a Fibaro Door/Window sensor, the FGK-101 – because it’s easier to test with a sensor on your desk that doesn’t require you to wave at it all the time šŸ˜‰ All went well, I saw the sensor switching from on to off and vice versa.

Now how do I get this infomation into my own Home Automation system without too much hassle? I’m used to subscribing to MQTT topics lately, so I started searching for a way to catch events or hook up to ‘something’ that could help me to export device data in some way. The Developers Documentation PDFĀ gave a clue: binding. Ah, so that’s how it’s called in Z-Way world.

The PDF says: “A very powerful function of the JS API is the ability to bind functions to certain values ofĀ the device tree. They get then executed when the value changes.” Yeah, that sounds like what I want. Lets give it a try.

To run the “binding to *everything*” code I had to make sure an additional (Java-)script was executed when the z-way-server service was started; for that I added an additional line to the end of the fileĀ /opt/z-way-server/automation/main.js file (showing just the last 3 lines here):

  });
  executeFile('bind_all.js')
}

And this bind_all.js file, which has to be placed in the same directory as the main.js we just changed, goes like this:

var callback = function(type,arg) {
  console.log('### here I am ###');
};

for (var dv in zway.devices) {
 var dv = zway.devices[dv];
 dv.data.bind(callback, null, true);
}

I restarted the z-way-server service (sudo service z-way-server restart) and moved the magnet of the Door/Window sensor away; bingo! The ‘### here I am ###’ showed up in the z-way-server log (tail -f /var/log/z-way-server.log). OK, nice.

Now what? I had a look at what others did; the only thingĀ Ā I could find was executing a system() call to notify the outside world that something had changed but I didn’t like that approach; sounds like too much overhead? Getting a MQTT client running would be nice, but way out of reach with what the JS API has to offer šŸ˜‰

I preferred to keep it all wrapped up in a single script without any other dependencies, so I went back to theĀ Developers Documentation PDF I mentioned earlier. It says: “The JavaScript implementation of Z-Way allows to directly accessing HTTP objects”. So I can do a HTTP request from inside my callback? Let’s try it. With a few lines of code I managed to POST the result of a JSON.stringify(this) to a NodeJS HTTP server that was running on my PC. Nice, and the information I was looking for was in there, great. But this POST resulted in 15 KB of data (including headers and other usual stuff), just for an opening/closing binary sensor? Come on, still not good enough!

Now the JSON API came to the rescue; again from the Developer Documentation PDF: “/ZWaveAPI/Data/<timestamp> returns an associative array of changes in Z-Way data tree since <timestamp>”

Let’s use that and POST that response to my little HTTP server. Yes! Same result (as in: it also contains the information I need) and the size has decreased to 1/9th of what it was.

About 1700 bytes to ‘communicate’ a state change of a binary sensor is still too much, but I couldn’t find any other way to do this. Maybe I’ll parse the result further inside the callback to minimize the I/O to a more ‘sane’ amount. So here’s the complete bind_all.js script that’s now communicating state changes of my Fibaro Door/Window sensor:

var callback = function(type,arg) {
 try {
   var options = {};
   // timestamp
   var ts = (new Date()).getTime();
   ts = Math.floor(ts/1000).toString();
   // query local ZWave API
   options.url = "http://127.0.0.1:8083/ZWaveAPI/Data/"+ts;
   options.method = "GET";
   var res = http.request(options);
   // send response to HA system
   options.url = "http://192.168.10.xxx:8181";
   options.method = "POST";
   options.data = JSON.stringify(res);
   res = http.request(options);
 } catch(err) {
   debugPrint("Failed to upload device state changes to HA system: " + err);
 }
};

for (var dv in zway.devices) {
 var dv = zway.devices[dv];
 dv.data.bind(callback, null, true);
}

Now back to the sensor which started all of this – the Fibaro FGMS-001.

In a 2nd post, because it’s quite a story … soon!