I live in the Arizona Desert, Southwestern USA. It gets hot here, and my power bills got out of hand. This is a journal of my various efforts to bring this problem under control using the cheapest technology I could find. Saving money shouldn't cost a fortune.

Pages

Thursday, January 16, 2014

Arduino and the Iris Zigbee switch

A friend of mine is looking for a way to control a light remotely. His problem, and mine also, is that these darn things are expensive and require a controller. He specifically wanted something that used the Zigbee protocol because they are capable of being controlled by an XBee device. He pointed me to the Iris line at Lowe's. Being eaten up with curiosity, I went to Lowe's and looked at the devices.They have an entire line of devices for lights, doors, garage, etc. The problem I saw was that, once again, you're stuck with their controller that you can't change, their website that will probably go down at the least useful time (and has a number of times), and a monthly charge that they can raise any time they want to. I even prowled through their terms of service (yuck) and it looks to me like they can use the data for anything they want to. Also, they can change their terms of service at any time, leaving your data to their use. I hate that crap. Here we go, buy their stuff and then are subject to whatever they want to do over the years. Why don't they just sell us the darn switches, publish a reasonable API that we can use, and let us live our lives outside their monthly charges and control?What's needed here is for someone to figure out their switches, make them work with a little computer of some kind, and put how they did it on the web for the entire world to play with. That'll show them.Welcome to my work hooking an Arduino to an XBee and controlling an Iris light switch remotely.Edit: But before you go and implement this, take a look at my second post on this experiment, there are some things to avoid <link>.First, I chose their Iris Smart Plug <link> because it looks cool, can be tested without installing it into the wall, and measures the power going through it. Does this sound like my perfect device or what? I can use one of these to measure power anywhere in the house and have it report to my Raspberry Pi where I can forward it to a cloud server (or three, or four) for examination over time. This little device is right down my alley. Now, all I have to do is make it work ... right ?

I could have bought their controller and decoded the interaction with a sniffer and proceeded to duplicate it on my Pi, but there were some problems with this idea: I don't have a spare Pi right now, the interaction is encrypted, I don't have a sniffer; what the heck am I going to do with this $30 paperweight? Off to the web I go.I only found one, yes one, place where anyone had any sort of success hacking this device. Over at Jeelabs a contributor, CapnBry, had managed to make it work using code on a Windows PC <link>, but his description of how it worked read like classic Greek; totally out of my league. Try as I might, there just wasn't anyplace else that turned up with something more comprehensible to me. I had to just bite the bullet and start trying to talk to the switch. After all, I've worked with XBees for years; how hard can it be?At this point, you're probably thinking that this is just another post about how I tried to make it work and gave up because I just couldn't get enough information, didn't have the time, or the hardware didn't live up to expectations. Well, not so; I have the working switch being remotely controlled by an Arduino setting right over there. And yes, I'm going to tell you how I did it, and provide the code so you can repeat the experiment. Hopefully, you'll expand on my efforts and let me know about it so we can all benefit and move along.Like I said earlier, I wanted to put this on a Raspberry Pi, but I didn't have a spare one to experiment with, so I got an Arduino and XBee out of my parts bin, slapped them together, and programmed the XBee as a controller. This is where I ran into my first obstacle. How to set up the XBee? First, you have to use a Series 2 XBee or better; none of this will work on a Series 1 XBee (now do you understand why I chose series 2)? The notable items in the setup of the XBee are:ZigBee Stack Profile 2Encryption Enable 1Encryption Options 1API Enable 2API Output Mode 3XBee Modem XB24-ZB, ZIGBEE Coordinator API, Version 21A7 (or better)And, Encryption Key set to something that you can remember. You cannot read this register after you set it, so put in something you can't forget if you need it later. Once set, I haven't needed it since, but you never know.All the parameters can be set using XCTU and it is relatively easy to set up for this once you know what you're doing. The other parameters can be matched to whatever you're used to using. Don't think this came easily! It took me almost a full day of messing around to get it working at all, so if you have trouble, double check everything.Next, I wanted to use Andrew Rapp's XBee library for the Arduino, but he didn't put in support for the special messages needed to communicate with a ZigBee device. Specifically there are two messages that are used (almost) exclusively for ZigBee communications: Explicit Addressing ZigBee Command Frame 0x11 and ZigBee Explicit Rx Indicator 0x91; these are not supported by Andrew's library. However, the library is too nice to allow something like that to stop me, so I extended the library to support these two messages and added support to the ZBTxStatusResponse to be able to get the frame ID back (he missed that little thing). These changes allowed me to use the library and all its features to speed up the hack.OK, armed with a library specially modified to work with ZigBee devices and an XBee that should be able to talk to them, I put some code together to monitor traffic. I immediately got traffic from the switch. There was a series of messages that I couldn't understand and a lot of bytes to figure out what they meant. Back to the link above where the guy stated that he had made it work. The problem was with language. He said things like, "You: (Endpoint=0x02, Profile=0xc216, Cluster=0x00f0) FrameControl=0x19 ClusterCmd=0xfa data=0x00 0x01" What is an Endpoint? A Profile? These things were totally foreign and strange. So I hunted down the ZigBee specification <link> and it was HUGE and filled with jargon specific to the protocol that made reading it an exercise in learning to speak ancient Sanskrit. I also found an Endpoint document that talked about the interaction of devices during a process called 'Joining' <link>. After reading a significant portion of these I started to understand. None of the web sites I visited actually described what most of this stuff was, but it boils down to this:There's a device that supports ZigBee as an end point. It's things like light switches, door locks, devices that actually do something; these are called ZigBee Device Objects. There's things that control these devices, they're called servers. Each device has profiles, these profiles are code that are specific to the device. Each profile has clusters; these clusters are where the code to do something is hooked. So, you'll send a message to a device, profile something, cluster something, with some data about what you want to do. Add to this the fact that each device has a 64 bit address, a 16 bit address, and needs special formatting to the message and the task becomes a bit daunting ... a whole lot daunting.After prowling around documentation for hours I started to get a glimmer of what was going on and I finally found a key to these things that was way down in the XBee user's guide. Round about page 122 the Digi folk talk about how to send and receive messages to a ZigBee device. That was the key that got me going. Now that I understood a little more than half of what the guy CapnBry was talking about, I started deconstructing the messages from the switch and looking at what was going on.The switch sends a message announcing that it exists, then it sends another message that tells some stuff about what it can do. These messages come after the hardware itself gets set up. There are messages (we don't have to worry about) that take place just to get the XBee coordinator to recognize it. Then the little device sends another message specifically from the hardware. See, the ZigBee protocol is general purpose and has support for devices that haven't been invented yet, but the manufacturers ignore that and roll their own stuff under the 'Manufacturer Specific' provisions of the specification. That means that even if you support the Zigbee protocol, it won't work with the various devices because they hide everything under the special provisions ... jerks. So, you have to fiddle with things to get them to work. The manufacturer AlertMe is notable for this tactic, and AlertMe manufactures the devices that Lowe's sells. So, these three messages come out of the switch and it's your responsibility to respond correctly to them and get the device to recognize your code as a valid controller; that's what meant by 'Joining'. What happens is that the switch has a hardware 64 bit address and randomly chooses a 16 bit address to send the messages with. If it doesn't get a proper response, it steps to another channel and tries the same thing again. It does this for quite a while before it give up and just shuts down. So you watch the messages, it stops a while and the messages start again. Eventually it just give up all together. Each time you see the set of three messages, it will have a different 16 bit address, so you have to save this address to respond to so that it will listen. If you're too slow, it won't pay attention because it has already changed the address it pays attention to.
The sequence is documented in the code below, but basically, you wait for the first two messages to come in then respond to both of them. Then, you interact with the device and it will join with your homemade controller. From that point on, it will report the power usage every three seconds with a summary every minute. There's other stuff that is sent by the switch, but I wasn't interested enough in it to bother decoding it; consider those items an exercise for the student.
Once you get it working, you'll find out how nice this switch is. It monitors the power and reports it every three seconds or so. It latches the state of the switch such that if the power fails, it comes back in the same state it was in when the power failed. The little light on it doesn't follow properly, but that can be controlled with software. It reports a state change back. That means that if I walk over and push the button, it will send a message that the light has been changed. You can ask the switch the state of the light and it will answer back to you. So you can check to see if the outside lights were left on. This switch is actually pretty nice.
But enough of the bragging. Here's the code, but remember, this is an example of how to do it. It isn't an example of coding style, proper formatting, or even the right way to do it. It's the actual code I used to figure out how the switch works. It will compile using the Arduino IDE 1.0.5 and needs the special modifications to the XBee library I added to support the Zigbee specific messages. Just let me know if you need the changes and I'll put them somewhere you can grab them. It also needs the latest SoftwareSerial library because I use software pins to connect to the XBee and the console to monitor and send commands.

Once you get it running you can turn the switch on by typing a 1 in the input line of the Arduino IDE terminal and clicking send. A zero will turn the switch off. That's all I really supported in this version, future work will obviously expand the capabilities. Also, if you kill the sketch, wait until at least one message has been sent by the switch. The code above needs the 16 and 64 bit address of the switch to work and I didn't put any provisions in to save it; it has to come from the switch. Every message from the switch carries the addresses, so just wait for one to come in before trying to send something. Since this is the very first version of this effort, the switch can sometimes fail to 'join'. This isn't a problem, just let the two devices interact for about 20 seconds or so, unplug the switch and plug it back in. It'll take off and work.

Edit: About an hour after I posted this I got a brainstorm and figured out how to get the switch to 'join' reliably. Now, you can reset the switch by unplugging it, press the button to discharge any caps, plug it in, and then press the switch 8 times within about 8 seconds. The switch will start all over in its interaction, and then start sending power readings. When (notice I didn't say 'if') I get another one, I'll have to modify this code to support two devices, but one works fine. The code box above has been updated to hold the latest.

Here's the output from the Arduino from first start up after joining. I turn the switch on and off during the session. Notice that the power usage is 83 (two little bulbs in a lamp) and that the switch is constantly sending its status over the network. There's an extra piece of debugging in this; I print all the bytes sent to the XBee, so the lines that begin with the 7E are lines that are actually being sent to the switch.

31 comments:

I am developing a solution to replace wall switches for light control. It's designed to have a Moteino dropped in for wireless control, perhaps could be adapted for xbee. Thought I'd mention it here for reference or just as an idea, more here: http://lowpowerlab.com/blog/2013/12/24/switchmote-one-step-closer-to-reality/

Nice little device you have there. If it had an XBee on it it would be an incredible remote control for around the house. Since XBee has the protocol built in, it could be used for everything a home controller wants. I have a number of other things I could mention, but I'm not sure you'll get back here anytime soon.

My device has a fully capable arduino (the Moteino) so it can make decisions and even be autonomous of any central controller. The idea is to independently sync multiple lights together and create scenes (ie turn more lights on/off at the same time from remote locations). I believe that would be a challenge with XBee but I could be wrong. A Xbee version would probably be popular as well so that's something I might consider but need to test the waters with the current version.

I understand the problems you're looking at. I use a central controller that receives from various XBees and then makes decisions for the house in general. Each remote device (an XBee equipped arduino) has certain functions that it handles autonomously like temperature control, default timing for a water heater, etc. The overall override capability is under the house controller.

Using a switch like yours, I would simply send "Scene 1" to the controller and it would turn on whatever is appropriate: stereo to quiet romantic music, lights low, hot tub on, etc.

My controller is a raspberry pi with an XBee hanging off the serial port which, so far, has handled things really well. This makes your idea of the switch compelling.

As you progress, think about the various advantages. The XBee can interface to Zigbee devices (I'm slowly proving that), it handles store-forward for extending the network, has a well documented interface, various language interfaces so it can talk to a variety of machines, ... I could go on and on.

I absolutely hate the idea of being trapped into some corporations idea of a controller and end devices hooked to some cloud server that they control. So, keep at the switch, it could become a very important item in future DIY home automation.

Dave's central house controller has proven to be quite a powerful little program. I began incorporating his controller into my home automation project back in early December and the more I work with his code the more powerful I find the system to be. All it took was for me to read through his work with the XBee radios and I was sold on them. I had read quite a bit on them from different places and they all seemed to be a bit too vague on the actual operation of the devices. One site kinda told you how to set them up, another kinda told you how to use them. Dave wrapped it all up in one place and made me them seem simple enough to make the plunge. So much easier that pulling CAT5 cable everywhere and hoping the Ethernet Shield doesn't crash on me.

Congrats Dave, you made short work of that device. Trick now will be do you integrate it into the house controller or leave it out on the Arduino and control it from there using the house controller? Either way works depending on how many of them you can control form the Arduino....

Welllll, I tried to integrate it into my house controller using the same XBee network that is already controlling the house. It not only didn't work, the attempt wiped out my network.

Insert a really, really heavy sigh right here

It wasn't a total waste of time though. I discovered something new about the XBees that had slipped by me and I also found out why I blew up the network. But, there doesn't seem to be a way to share a network with non-ZigBee specific messages and messages targeted for a ZigBee device. I'll be checking this out further and I'll post a synopsis of what's going on.

If I'm right, it can't be combined, I'll be creating a second device to handle the ZigBee switches. These switches are really cool and do everything I want in something like this. Imagine putting one on a refrigerator, you can tell how much power it is using and graph usage over a few days. The device probably won't be an Arduino though, since I need to save the addresses and the network could get extensive over time, it looks like a Raspberry Pi would be a good solution.

Thanks for all your hard work! After reading this yesterday I ran to Lowes last night to look for an Iris light switch and -almost- all of the Iris products I saw (light switches, outlets, etc) said zwave specifically and are GE brand. I did notice the same outlet you are using here and it doesn't specifically specify protocol. So is Iris switching to zwave or what are the chances these GE Iris "zwave" light switches and outlets will work using your method? Thanks alot!

Zwave and ZigBee are different things and one won't work with the other. The way they do it is to have a Zwave controller as well as a ZigBee controller in the same box. So, NO, I can't control a Zwave switch with my code.

It does appear that Iris is switching to Zwave though. I seem to remember several devices in their line being ZigBee and I can't find them on their web page anymore. Their little window sensors and a couple of other items seem to be ZigBee, but not the cool wall switches and outlets.

I just wanted to say I got the Iris switch on and off a light with your code. I must of missed the software serial at first, so that through me for a loop. But once I noticed that obvious detail, boom! working perfectly. Thanks for the hard work. I have been reading this blog for some time and waiting for the day to have a house and start automating it. Also look into MQTT :)

Have you had success with any manufactures other than Alertme? I was thinking of the orbit irrigation timer as a project. It seems to be different in that it only sends a device announce (13) and no others.

Actually, no. My experience with ZigBee in general has been a real turn off for the protocol. What started off as a really good idea has seemed to flounder with all the manufacturers opting for 'special provisions' to try and capture some portion of the marketplace. When I start working with sprinklers, I'll go the old fashioned route. I'll set up an arduino with an XBee hooked to it and a set of relays controlling regular ol' sprinkler valves.

I can buy all the parts ready made from web suppliers without having to worry about protocols, and my house controller can easily send commands to the sprinklers and even sample moisture sensors if I want to go that far with it.

But, if you want to experiment, just grab the code above and play with it a while. Several folk have used the code to examine devices.

I understand your irritation with the protocol. Like all good things that could be great, it is monetized and hijacked for profit. I appreciate your response and hope you have fun with your next project.

The ZWave devices are actually very easy to use. I added a Razberry board to my RPi and have been having a blast with the ZWave stuff. Rebuilding my RPi at the moment due to (I believe) data corruption due to using a microSD in an adapter...

Remember up above in the narrative I mentioned a guy named CapnBry? He made it work first, but it took me days to understand what he was saying. That's where I got the idea for the two messages, and from there I poked around until I got it working. I asked CapnBry the same thing and he said he used a special sniffer and a complete system to map out the messages. He saved me having to do that part.

Somewhere on this blog I have a picture of the switch when I opened one up to look inside. There you will see a relay. The relay is rated for 15A at 240V, so it should be able to handle the current. The problem is that whether or not the electronics can handle multiple voltage levels is unknown.

You can always get a power adapter and run it at 120, then close a relay with the switch that controls the A/C.

Maybe if you take a close look at the power supply in the switch you can tell if it handles multiple voltages, a lot of them do.

Dear Desert Home,I have read your blog with interest. As I did use E-inzicht which resembles your Iris Zigbee switch closely. But in ocotober last year the utility firm decided to terminate the project ( http://members.ziggo.nl/olav.buunen/energie/einzicht.htm ) so now I am left with 4 E-inzicht plugs with the only functionality the physical switch. Although I asked the firm for alternative support they could not give any information about that. My question is could I use your setup to get data and get the long distance switching functionality back.Thank you for your efforts, Frank

Hi, I'm a beginner to play zigbee, I have a zigbee smart-plug and a Digi Xbee connect to my adurino uno, I find some example code in this book "Building_Wireless_Sensor_Networks_Using_Arduino" and successful to control on/off of the smart-plug, but I don't know how to get the state of smart-plug, and the meter of smart-plug. I try your code with the latest XBee.h from "andrewrapp" but got some error "'ZBExpRxResponse' does not name a type" and "ZBExpCommand does not name a type".Can you update the code or point me how to fix these error?

Same issue: I'm getting the same compiling error "ZBExpRxResponse' does not name a type". I started looking at the code. Looks like there are several class name changes and possible some architecture changes. I plan to see if I can get it working, but it will take looking at the old and new code to figure it out.

Wow, got it. The issue is that if you install the library via Arduino, you are getting the code from andrewrapp: https://github.com/andrewrapp/xbee-arduino. But the examples from Desert Home are using the XBEE library from https://github.com/draythomp/Desert-Home-Arduino/tree/master/libraries/XBee. They are similar, but quite different.

If you want to install the DH library instead of the one "built in"to the Arduino libraries tool, you can follow this guide https://www.arduino.cc/en/Guide/Libraries to download the compressed zip from github and put the library folder in the right place.

You will want to either remove the one you installed or install another copy of the Arduino software.

I tested this theory and was able to compile https://gist.github.com/bgentry/6e4f7840b22c9743640ca38ade6a844a with only the expected changes related to Serial ports and only having 1 on the Uno. I haven't actually run the code yet.

You are very gifted in your abilities to crack these Iris products from Lowes. I see code published on gethub and was curious if it was possible to get any of it to work with Smartthings ? I think all of this is completely fantastic what you have been able to accomplish with these Iris devices.