Getting started with z-wave and python

I started playing around with my new z-wave kit. I ordered an Aeon-Labs Z-stick (series 2) and a Duwi dimmer module to start with.
Here are some images of both devices:



After playing around a bit with a demo Homeseer license to test whether the stick and module worked (setup was really easy), I quickly switched over to my ‘bits and bytes view’..
Here’s a log of the Aeon-Labs stick initializing:

The yellow text is the command that get’s transmitted from the PC to the controller. This article will focus just on the sending command (my first starting point with python and z-wave)
So let’s have a look at the basics, these are the 5 bytes that get send to the controller: #01#03#00#02#FE
Let’s translate these bytes to bits (a lot of people still seem to have trouble to distinct between the two of them):

01 = 0000 0001
03 = 0000 0011
00 = 0000 0000
02 = 0000 0010
FE = 1111 1110

From some z-wave documentation publicly available, I figured out that the checksum is the last byte of the command. In most documents they referred to the checksum as a CRC checksum, I actually think it’s an LRC (Longitudinal Redundancy Check). A LRC is computed by XOR all the byte values of the packet together. XOR stands for a bitwise eXclusive OR. A bitwise exclusive or takes two bit patterns of equal length and performs the logical XOR operation on each pair of corresponding bits. The result in each position is 1 if the two bits are different, and 0 if they are the same. For example:

    0101
XOR 0011
  = 0110

So how does our calculation look at bit level? (remember that we skip the first byte):

00000011 (03) XOR 00000000 (00) = 00000011 (03) (Nothing happens on this operation)
00000011 (03) XOR 00000010 (02) = 00000001 (01) (See how one + one is 0 here?)

So the outcome is 01.. hmm, not quite the LRC value we’d expected. We expected ‘FE’ (last byte in our command). This is because the LRC calculation z-wave uses starts with a starter value, which is “FF” or 1111 1111. So let’s try our calculation again, now with three steps:

11111111 (FF) XOR 00000011 (03) = 11111100 (FC) (Note the last two bits as a result of our XOR operation)
11111100 (FC) XOR 00000000 (00) = 11111100 (FC) (Nothing happens on this operation)
11111100 (FC) XOR 00000010 (02) = 11111110 (FE) (Aha! There’s our value!)

So, there we go.. through some calculations we figured out the checksum algorithm that z-wave uses. This is an important first step in understanding the protocol.
Now for the python part, here’s the code I used to test the checksum:

def generateChecksum(message):    
    lrc = 0xFF
    for b in message:
        lrc ^= ord(b)
    message += chr(lrc)
    return message
    
testmessage = "\x03\x00\x02"
generateChecksum(testmessage)

And this is me, testing the code :-)

You can leave a response, or trackback from your own site.

2 Responses to “Getting started with z-wave and python”

  1. Jan Penninkhof says:

    Hi Maarten,

    Couldn’t help noticing that you’ve moved from Plugwise to Z-wave devices. I’m very curious on your reasons, as pricing and feature-set is quite similar. Was it the openness of the protocol or perhaps reach of the built-in radio (which is not very great in Plugwise devices).

    Cheers,
    Jan

  2. Will says:

    Great article, I was having real trouble working out the CRC/LRC issue, you have saved me a lot of time!
    Thanks

Leave a Reply