SharpGIS

#GIS from a .NET developer's perspective

Announcing the first official OpenZWave library for UWP

As a follow-up to my recent OpenZWave blogpost ( http://www.sharpgis.net/post/2017/01/20/Using-OpenZWave-in-UWP-apps ), a few things has happened since.

First of all I’ve worked closely with the OpenZWave team, and we agreed to consolidate efforts. My library is now the official OpenZWave library for .NET and UWP, and has been moved out under the OpenZWave organization on GitHub:

       https://github.com/OpenZWave/openzwave-dotnet-uwp

At the same time the older .NET library has been removed from the main OpenZWave repository, so they can focus on the native parts of the library, and I’ve taken over the .NET effort.

To successfully support UWP and .NET, I wanted to achieve as close code compatibility as possible, and for maintainability also reuse as much C++ code as possible (both libraries are written in C++ – C++/CX for UWP and C++/CLI for .NET). The APIs for the two binaries should however be completely identical and the code you write against them the same. This meant a lot of refactoring, and breaking the original .NET a little. At the same time, I did a full API review, and cleaned it up to better follow the .NET naming guidelines. The overall API design hasn’t changed too much, and moving from the older .NET API shouldn’t be too much work (the original WinForms sample app was ported over with relatively little effort and is available in the repo as a reference as well).

However because of the many small breaking changes, the nuget package needs a major version increase.  I’ve just released the v2.0.0-beta1 package for you to start using. The API is release quality though, and should be very close to a final release. If you’ve done any OpenZWave dev, I encourage you to try it out and provide feedback.

Read the WIKI to see how to get started: https://github.com/OpenZWave/openzwave-dotnet-uwp/wiki

Or try out the sample applications included in the repository. So go grab the nuget package today and start Z-Waving!

                https://www.nuget.org/packages/OpenZWave/2.0.0-beta1

Note: If you are using IoTCore, beware that Microsoft pre-installs an OpenZWave to AllJoyn bridge. This bridge will grab your Serial Port, so make sure you disable this app prior to using the library. Second: The built in AllJoyn-ZWave service by Microsoft only supports the older Gen2 AeoTec adapter, whereas this library also works great with the Gen5 models.

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!