SharpGIS

#GIS from a .NET developer's perspective

Using OpenZWave in UWP apps

In my recent IoTivity hacking, I wanted to create a bridge between ZWave and IoTivity, and run it as a StartUp task on my Raspberry.

Something similar already exists in Windows IoT Core, as a bridge between ZWave and AllJoyn. Actually all you have to do is get a Generation 2 Aeotec ZWave ZStick, plug it into your device running IoT COre and you got yourself a ZWave-to-AllJoyn bridge. Unfortunately those aren’t being sold any longer, only the Generation 5, which isn’t compatible with the bridge. AllJoyn isn’t doing too well either.

Anyway, back to IoTivity: To build a bridge, I needed a ZWave library that supports UWP. After all, most of my devices are ZWave devices. I have my SmartThings hub as a primary controller, but you can add any number of ZWave USB Sticks as secondary controllers to the ZWave network. So I can continue to rely on SmartThings (for now), while I start hacking with the USB controller against the same devices.

Luckily Donald Hanson has an awesome pull-request for OpenZWave that adds a native UWP wrapper around OpenZWave, based on the .NET CLI wrapper. However the OpenZWave people were a little reluctant to merge it, as they already have a hard time maintaining the .NET CLI one, and suggested someone taking it over. I offered to do this but haven’t heard anything back from them. So while waiting, I just started a new repo to get going with Donalds blessing. I’ve spent a lot of time cleaning up the code, as there was a lot of odd patterns in the old .NET library that created an odd .NET API to work with (for example there was Get* methods instead of properties, delegates instead of events, static types that aren’t static etc). I’m also working on bringing the .NET and WinRT core in sync, so the two could share the same source-code. I’m not there yet, but it is getting close. If you have some C++ experience, I could really use some help with the abstraction bits to make this simpler.

Bottom-line is I now have a functioning wrapper for OpenZWave that can be used for .NET and UWP, and it works with the new Gen5 ZStick! (and many others) There are many breaking changes though, so I don’t know if OpenZWave wants to bring this into their fold. If not, I’ll keep hacking away at it myself. I do expect to continue making a lot of breaking changes to simplify its use and make it more intuitive. Due to the nature of ZWave devices, you can’t always rely on an instant response from a device when it is trying to save battery, so it could be several minutes before you get a response (or never), so a simple async/await model doesn’t work that well.

Anyway go grab the source-code (make sure you get the submodule too), and try it out: https://github.com/dotMorten/openzwave-dotnet-uwp

Here’s how you start it up:

//Initialize
ZWMOptions.Instance.Initialize(); //Configure default options
ZWMOptions.Instance.Lock();       //Options must be locked before using
ZWManager.Instance.Initialize();  //Start up the manager
ZWManager.Instance.OnNotification += OnNodeNotification; //Start listening for node events

//Hook up the serial port
var serialPortSelector = Windows.Devices.SerialCommunication.SerialDevice.GetDeviceSelector();
var devices = await DeviceInformation.FindAllAsync(serialPortSelector);
var serialPort = devices.First().Id; //Adjust to pick the right port for your usb stick
ZWManager.Instance.AddDriver(serialPort); //Add the serial port (you can have multiple!)

 

The rest is in the Notification handler. Every time a node is found, changed, remove etc. an event is reported here, including responses to commands you send. Nodes are identified by the HomeID (one per usb controller), and by the NodeID. You use these two values to uniquely identify a node on your network, and can then oerform operations like changing properties via the ZWManager instance.

There’s a generic sample app you can use to find, interrogate and interact with the devices, or just learn from. Longer-term I’d like to build a simpler API on top of this to work with the devices. The Main ViewModel in the sample-app is in a way the beginnings of this.

And by all means, submit some pull requests!