Sunday, September 18, 2016

Dipping a toe into Z-Wave with the UZB controller hardware

Quite some time ago, I laid down some things I'm looking for in a home automation solution. I've recently come to the conclusion that Z-wave is probably mature enough to begin experimenting with. It's a closed protocol owned by a single company, but the company has been around long enough and has affiliated with enough consumer partners that it's unlikely to vanish tomorrow. It may not be secure (it looks like there are security features in the protocol, but I don't know yet if all devices support them), but it should support the debugging and status features I'm looking for that I was never able to get working with INSTEON. To that end, I purchased a UZB stick from Z-Wave.Me and a GE Dimmable Lamp Module and started experimenting. This will be an ongoing trip; we'll see where we end up.



Experiment 1: The Z-Way Server

Hardware installation was trivial; the UZB is a Z-Wave radio glued to a USB serial interface. I chose my Raspberry Pi as the lucky recipient hardware and plugged it in.

Software is where things would get interesting: Z-Wave is proprietary, and the options for authorized controller software are limited. On Z-Wave.Me's website, they recommend the Z-Way control software, which is certified by the Z-Wave Alliance. I decided that just this once, going in through the front door would be easiest, and set about installing it. 

Getting the software proved to be more difficult than I had anticipated. I initially went the road of cloning the git repository for the service core and the UI, and found myself off in the weeds of trying to get a working nodejs installation on my Raspberry Pi (I'm still running wheezy; apparently, Jessie is the new hotness, and I don't know if the version of nodejs in that distro is sufficiently up-to-date for Z-Way's needs). In any event, I hit multiple problems trying to get these files npm'd, configured, and installed; I got stuck.

Eventually, I perused the documentation for UZB's sister project, a Raspberry Pi preconfigured with a Z-Wave daughter card attached, thinking I may solve this problem by throwing more money at it. It turns out that in that documentation, there was a much simpler way: there is a script hosted by z-wave.me that installs the Z-Way stack and a mongoose webserver ready-to-go.

wget -q -O - http://razberry.z-wave.me/install | sudo bash
(Mandatory security disclaimer: looping anything you pull down over HTTP via wget directly into sudo bash is an opportunity for a man-in-the-middle to compromise the script on its way to you, and should be considered very, very unsafe.)

(Mandatory reality disclaimer: You're not a nation-state or a bank and nobody is out to get you; this attack vector would be so specific that if someone is trying to hit you with it, they could easily try simpler means to wreck up your day, like throwing a brick through your window. But if you're feeling paranoid, here is the script's code as I saw it. Compare that with what you get from the link, or just eye-read it to confirm you're happy with the commands it runs and let 'er rip).   

Having installed that, I was now in a position to control my network. With one small problem.

The Z-Way License

Z-Way isn't actually free-to-use; Z-Wave.Me requires you to purchase a license (for the relevant world region you'll be running in, since Z-Wave runs in multiple regions with different frequencies open). The process for doing this is spelled out on their site---and by "spelled out," I mean "Not spelled out at all." 

Fig. 1: Where your online store should go if you sell digital goods.


Their web page offering the License directs you to their resellers, of which there are three for North America: www.z-wave.us, www.zwaveproducts.com, and www.vesternet.com. Of the three,
  • None have a convenient link to purchase the license.
  • All three have "Contact Us" webforms
  • Of the three, only Vesternet returned my request for information. They directed me to an internal link on their site that doesn't show up in their search results.
  • The link only allows me to purchase European licenses. I emailed back about this, and they confirmed that they're a European vendor (then why are they listed in "North American Version", Z-wave.me?), but since they resell the licenses, all they have to do is email to get me a North American one and they could price-quote me directly---in British Pounds, which I'd then have to PayPal over using American-dollery-doos-to-British-conversion.
At this point, I decided it was time to pull the plug on this part of the experiment. ;)

Experiment 2: OpenZWave

OpenZWave is an attempt to reverse-engineer the Z-Wave serial protocol clean-room style, without buying a license from Sigma Designs (and signing the corresponding NDA). To their credit, Sigma Designs seems off-the-record cool with this; as long as OpenZWave doesn't go trying to create nodes (i.e. "The things that receive commands and control the house") and confines itself to network controllers, there doesn't seem to be any issues. Joining into this ecosystem does mean I'm on not-necessarily-legally-protected ground, but since Z-Wave itself is now old enough (and has enough varied vendors using it) that a backwards-incompatible protocol change seems unlikely, this may be stable enough sand to build a house on. Metaphorically speaking.

Relative to the long walk to nowhere with Z-Way, installation of OpenZWave was a breeze.
  1. Take a sandblaster to the dependencies injected by Z-Way to reclaim 3% of my Raspberry Pi's storage space, since it's limited (yes, of course the sketchy install-via-sudo-bash script doesn't include an uninstaller). You can probably skip this step if you aren't a fool like me. ;)
  2. Clone the OpenZWave C++ library from the GitHub repo. make; sudo make install. This part only tripped me up because in the long walk to get a working node I seem to have futzed up something in my apt-get configuration so that it can't find some libraries (notably libudev-dev), so I had to fetch them manually from Debian's website and use dpkg -i to install them. But once the C++ lib was installed, there's a demo at /usr/local/bin/MinOZW that you can call passing in the /dev name of the UZB serial device (mine is /dev/ttyACM1); it'll dump a log of what it's seeing in your Z-Wave network; if things look generally healthy (lots of "Info" and "Detail", not too many errors), you're off to the races.
  3. Clone the OpenZWave Control Panel from the GitHub repo (needs to be a peer directory to the OpenZWave C++ library, and that repo's directory needs to be named  "open-zwave", as per the Makefile for the control panel). Hand-edit the Makefile to let it know I'm on Linux, not MacOSX (see pull request for clarification as to what edit to make). My Raspberry Pi is still having trouble with apt-get, so hand-install libmicrohttpd-dev and libmicrohttpd10 by downloading from Debian and using dpkg -i. Run ozwcp -p <port number>
Success! I connected to the relevant port and saw...

... What I should have expected for an open-source project. ;)

Fig. 2: 2016, the year of Linux on the desktop

Okay, okay it's not as bad as it looks. Here's what I did next.
  1. In the "Device name" field, enter the serial device for your UZB pluggable (/dev/ttyACM1 for me).
  2. Leave "USB" unchecked. No, I don't know what it does either; I'll read the source code later. ;)
  3. Hit "Initialize". A bunch of stuff will scroll in the logs (both at the bottom of the web page, and stdout on the server process).
  4. Under the "Controller" category, select "Add Device."
  5. Tap the one button on the GE light controller. The device synchronizes to the controller and joins the network.
  6. Top-right ("Backup Controller"), hit "Save..." Don't know if it's necessary; seemed like a good idea at the time. Go ahead, cut the ends off of that roast, like grandma did! ;)
  7. Refresh the page.
  8. Re-enter the device ID into "Device name" and hit "Initialize" again.
  9. Scroll down to the "Devices" panel; you should see "Multilevel Power Switch", product "GE Unknown: Type=5044, id=3031
  10. When you click on that row, several options show up that are specific to that device. You can submit a light level (0 to 99), brighten or dim the light, or Refresh to fetch the current state of the light from the light module itself. Congratulations! You have one controllable light!
Fig. 3: Specific controls for a Multilevel Powe Switch
Clearly not the prettiest interface, but it's a start. Next on the agenda is to learn to make my own client that interfaces to the OpenZWave library (unless I want to screen-scrape the HTTP this client's buttons send and use the web server as the receiver of commands from Belphanior... Probably should swallow the whole frog and do things the lower-level way. ;) ).

Takeaways

  1. The front-door path---trying to work with the vendor to run the software they designed to work with the hardware---was not convenient at all. Unclear directions and a too-long path toward exchanging money for goods and services greatly complicated the process.
  2. The back-door path---working with software built by hobbyists who are trying to make an end-run around purchasing a closed-source license under NDA---was more convenient than I'd guessed. No points for prettiness of the UI, but it has the distinct advantage of "Actually works," which I can't say I arrived at with the Z-Way software.
I should note that there's an easier way to go---if I'd known there would be an issue, I could have purchased the Razberry hardware and gotten a Raspberry Pi already configured with Z-Way and a Z-Wave daugher-card installed. But I have things set up on my current RasPi the way I like them; not thrilled about getting an entirely new kit for one use-case.