A Dreamer's Lair

eQ-3 Max Cube message protocol decrypted (Part 1)

In my quest to write a gateway for the eQ-3 Max Cube I came across several sources of information. For those who are interested and for myself to keep a future reference at one place, I will try to write the info for as many messages as I can find on this blog. Perhaps needless to say that the messages also apply to the ELV version of the Cube (since the devices are equal, besides the accompanying software).

I shall start with how we get to know which Cube devices are available on the network and at what IP-Address (or addresses since there can be more than one Cube present).

When a certain UDP broadcast ‘Hello’ message is sent on port 23272, any cube in the network will respond to this message with an answer. On receiving this answer, we can check the originators IP-Address and thus know at what IP-Address the Cube is available. In the received message we can find the Cube’s serial number and firmware version. The latter of which is of importance because the TCP port at which to communicate with the Cube differs depending on the firmware version.

To send the broadcast message we can use the following code.


private const int CubeBroadcastPort = 23272;
private static byte[] _helloMessage = new byte[] { 0x65, 0x51, 0x33, 0x4d, 0x61, 0x78, 0x2a, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x49 };

// Broadcast hello message to find available cubes.
UdpClient sender = new UdpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, CubeBroadcastPort);
sender.Send(_helloMessage, _helloMessage.Length, ip);

ip = new IPEndPoint(IPAddress.Parse("224.0.0.1"), CubeBroadcastPort);
sender.Send(_helloMessage, _helloMessage.Length, ip);

This will broadcast the ‘Hello’ message on the network. The Hello message looks like this:


00: 65 51 33 4d 61 78 2a 00    eQ3Max..
08: 2a 2a 2a 2a 2a 2a 2a 2a    ........
10: 2a 2a 49                   ..I

I don’t know the meaning of all bytes in the message. Suffice it to say that it works 🙂

When the above message is broadcasted, the Max! Cube device will respond with the following answer (of 26 bytes):


00: 65 51 33 4d 61 78 41 70    eQ3MaxAp
08: 4a 45 51 30 35 34 34 39    JEQ05449
10: 32 33 3e 49 00 03 f2 5d    23.I....
18: 01 13                      ..

Important in this are the following fields:


Description        Startpos    Length      Example Value
========================================================
Response           00          8           eQ3MaxAp
Serial Number      08          10          JEQ0544923
Unknown            12          3           3e 49 00
Address            15          3           03 f2 5d
Firmware Version   18          2           01 13

The response is always eQ3MaxAp. You can check for the presence of this code to validate that it is indeed a hello broadcast response message.

The Serial number is a string of 10 characters containing the serial number of the Cube (which in this case would be JEQ0544923).

The address field is the 3 byte address of the Cube. In the Cube software itself all addresses seem to be displayed in decimal notation so the address for this cube would be 258653.

The last bit of info is the firmware version. This info is BCD encoded. So the firmware in this case, in decimal, would be 113. The firmware version is important for us to know at which port the Cube device listens. Prior to firmware version 109, the Cube listens at TCP port 80. Starting from firmware version 109, the TCP port will be 62910.

Next time, we will connect to the Cube device and deal with the hello message to and from the device (the so called h: and H: messages).

Compile Mono on a Raspberry PI (for hard float support)

You could say I am a .NET man. So the first thing I investigated after deciding to develop software on the Raspberry PI for my Home Automation, was how to develop in .NET on Linux 🙂

Fortunately there is Mono. A multi platform implementation of the Microsoft .NET runtime and C# compiler. Yeah 🙂

However unfortunate, the default Raspbian distribution (I installed Debian Wheezy through the NOOBS image) still ships with the more or less ancient 2.10 version of Mono which doesn’t support the so called hard float operating systems. And guess what… the Raspberry PI uses a coprocessor so it’s hard float alright 🙁

After some searching on the internet I read that I wasn’t the only developer who wanted .NET on the Raspberry 🙂 There were some branches of the main Mono branch (in GitHub) that supported the hard float Raspberry.

I searched the internet some more to find packages which I could use to install this modified version of Mono. To no avail I must confess.

Ah well, why not compile Mono myself then? That turned out to be easier said than done. Most posts concerning making Mono were a bit too steep on my Linux learning curve. Being a Windows man myself, Linux is quite a different cup of tea where almost everything is handled in obscure command line scripts.

But after more searching, and some asking around in forums, I finally compiled together what to do build Mono on the Raspberry PI.

And for those of you, who as I struggle with the same challenge, here is what I did to build the latest Master branch of Mono (as present on Github). I performed this build on a fairly fresh Raspberry PI (with debian wheezy) so it could be that some components are already installed on your Raspberry. Well here comes.

First I needed to install some components:

sudo apt-get install autoconf
sudo apt-get install libtool
sudo apt-get install gettext

Also, because Mono itself is build with Mono (a bit of a paradox..) you need to have some sort of Mono compiler installed. I used monolite-fast for this. So

sudo make get-monolite-latest

Because we are building Mono from the master branch we have to clone this on the PI (to get a local version of it).

sudo git clone https://github.com/mono/mono.git

After this has been done the following command take care of initialisation and building.

cd mono
sudo git submodule init
sudo git submodule update
sudo ./autogen.sh --prefix=/usr/local
sudo make
sudo make install

After the last command has finished, and be advised that the whole build process takes a couple of hours(!) on the small Raspberry PI, the latest master branch of Mono is available on your system.

You can test the version which is now available on your system

mono --version

which should result in something like this

Mono Runtime Engine version 3.2.7 (master/bb44c68 Sat Dec  7 20:08:30 CET 2013)
Copyright (C) 2002-2013 Novell, Inc, Xamarin Inc and Contributors. <a href="http://www.mono-project.com">www.mono-project.com</a>
TLS:           __thread
SIGSEGV:       normal
Notifications: epoll
Architecture:  armel,vfp+hard
Disabled:      none
Misc:          softdebug
LLVM:          supported, not enabled.
GC:            sgen

Now we can finally develop .NET on the Raspberry!

New Home Automation System

When I started to automate my home late 2009, I foremost wanted to be able to control my city heating in a comfortable and scheduled manner on a room by room basis.

Budget was (and still is) an important concern and after some investigation I stumbled upon a system made by the German manufacturer ELV (based of the FS20 system). With this system each room has its own thermostat which subsequently controls the radiators in that room. The system was wireless and inexpensive so I decided to invest in it to set a first step on the (never ending as it seems) home automation path.

I wrote some windows services (in .NET) to control the system, and used google calendar to schedule the temperature in each room. There was need for a google calendar, opposed to the standard schedule present in the system, because I needed a schedule that lasted more than a week because every other week I stayed at my girlfriend’s place and the heating in my house could  be turned off (well set to 15 degrees Celsius) then.

The system operated reasonably well for several years but had its quirks. Because it was wireless and not entirely bidirectional, one could never be sure if temperatures were actually set at the correct level. My software (obviously) took care of that through some sort of polling mechanism. But once in a while the system decided that is was overflowed and went dead for hours or sometimes even more than a day.

I could live with it reasonably well, but more recently the quirks seemed to increase in frequency and exceeded my irritation threshold.

So I decided to look for a new system. But this time it should definitely be bidirectional and still wireless (did not want to put wires to all my radiators and thermostats).

And since it is a new system I also decided to redesign the architecture of my home automation software to a more modern and flexible one. With the new system I wanted

  • Wireless operation
  • Full bidirectional support
  • The ability to control it through (custom) software
  • Communication through  UTP instead of USB so the device could run independent of other hardware/servers.

Based on this list, and again the budget as a primary concern, I decided to try the Max! system from manufacturer eQ-3. One could say it is sort of the successor of my current system and this time bidirectional controlled and still inexpensive.

Because I already used some ZWave devices with an Aeon Labs USB stick, I decided to give that an upgrade too. Mainly because I wanted to get rid of the USB device in my server (which prohibits me from installing Windows 2012 Hyper-V Server because that does not support USB devices, well not easily anyway) and also wanted a chance (and excuse :P) to play around with a Raspberry PI, I bought a Raspberry PI type B (with 512MB RAM) computer together with the Razberry daughter board which enables ZWave on the Raspberry.

Since I am a .NET man myself, I wanted to use .NET on the Raspberry to control the Razberry. So there is where the MONO runtime comes into the picture. But installing that on a Raspberry is an entirely different kind of challenge on which I probably will post in a separate post.

On the architectural side of things, I wanted more flexibility in my system to glue different components or even systems together. I found some interesting posts about using the MQTT message protocol for Home Automation and decided to use that in the new system. I also looked on the net for existing systems which I could use or partly reuse, but they either seem to be written in ‘unwanted’ languages like python, perl, basic, java, jscript or they do not use a flexible communication protocol like MQTT.

With MQTT, and Mosquito as the message broker, I could write gateways for the Razberry and Max! which would translate the functions on the devices to a device and hardware independent communication protocol.

This would give me separation of concerns and the ability to write multiple small components who would communicate with each other through the MQTT protocol and therefore be agnostic of each other including the hardware on which the component runs. Some of the components could be (and probably will be)

  • A gateway to the Max! system. This gateway would receive and send MQTT messages and translate them to functions on the Max! system.
  • A gateway to the Razberry. This gateway would receive and send MQTT messages and translate them to ZWave functions on the Razberry.
  • A calendar publisher component, which reads a google calendar and publishes scheduled events as MQTT messages.
  • A Heating/Thermostat controller component, who receives MQTT calendar messages and send corresponding MQTT messages to the thermostats.
  • Etc.

This system would be flexible and easy to enhance. The plan is to use .NET on the Raspberry to create all of the above components so the entire Home Automation system can run on the Raspberry. This will include Mosquito as an MQTT message broker and probably MySQL for the storage of data.

At the moment I have bought some hardware (both Max! and Razberry) and investigating the further possibilities. I intend to publish my software as open source so others can use (part of) it if they want to. Since the communication protocol will be based on MQTT messages, it is easy to expand the system with gateways for other hardware and modules to control other things. Like for instance a module which would publish dawn/dusk events as MQTT messages so they can be used (in another controller) to turn on/off some lights in the house.

I guess this will be a work in progress for the oncoming months and I hope to reflect the progress of my new Home Automation System in posts to come!