Getting your CurrentCost (433MHz) data into OpenHAB using an RTL-SDR dongle and MQTT

CurrentCost?

CurrentCost is a UK company founded in 2010 which provides home power measuring hardware. Their main product is a transmitter which uses an inductive clamp to measure power usage of your household. On top of that, they also provide Individual Appliance Monitors (IAMs) which sit between your device and the outlet, and measure its power usage.

The transmitters broadcast their findings wirelessly. To display the data, a number of different displays are sold, which can indicate total usage, per-IAM data, trending and even cost if you care to set that up. I myself have the EnviR, which has USB connectivity (with an optional cable) so you can process the CurrentCost data on your computer. Up to 9 IAMs can be connected to the EnviR.

I bought my CurrentCost products over 5 years ago, it does look like they are still on sale. CurrentCosts operates an eBay store where you can buy their hardware, if you’re not in the UK.

Important note: Should you decide to acquire any of their IAM hardware, do note that their “EU” IAM plugs are in fact “Schuko” type F type, which is used in Germany and The Netherlands, with side ground contacts instead of a grounding pin. That wouldn’t be so much of an issue, except that they don’t have an accommodating hole for the pin, so they won’t fit standard EU (non-German, non-Dutch, type E) outlets without a converter! The device-side is usually fine, as most if not all plugs also support side ground contacts, and if they don’t, at least the lack of a pin does not impede plugging it in.

OpenHAB?

OpenHAB is an open source, Java-powered Home Automation Bus; what this basically means is it’s a centralized hub that can connect to many systems that have found their way into your house, such as your smart TV, your ethernet-capable Audio Receiver, Hue lighting, Z-Wave- or Zigbee-powered accessories, HVAC systems, Kodi, CUPS, and even anything that speaks SNMP or MQTT or Amazon’s Alexa. It’s pretty much fully able to integrate into anything you can throw at it.

If you’re not already using OpenHAB, this post may not be very useful to you… Yet.

MQTT?

MQTT (short for Message Queue Telemetry Transport) is publish-subscribe-based “lightweight” messaging protocol. In short, you run a (or multiple) MQTT broker, and then clients can “subscribe” to certain topics (topics being freehand names, pretty much), and other clients, or the same ones even, can “publish” data in those same topics.

MQTT is a quick and elegant solution to have data circulate between different services, over the network or on the local machine – the fact that that data is broadcast over certain topics means multiple listeners (“subscribers”) can all act on that same data being published.

OpenHAB supports MQTT in both directions – it can listen to incoming topics, or broadcast certain things over MQTT as well.

The configuration below assumes you already have an MQTT broker to publish the radio messages to; setting up Mosquitto or similar is out of scope for this article.

Getting data out of CurrentCost

The EnviR outputs the following string regularly (every 6 seconds) over its USB serial port:

<msg><src>CC128-v1.48</src><dsb>00012</dsb><time>22:18:34</time><tmpr>24.9</tmpr><sensor>0</sensor><id>02015</id><type>1</type><ch1><watts>00876</watts></ch1></msg>

This is a line of data reporting power data sent by sensor ID 2015 (every sensor has their own 12-bit ID), of type 1 (this is either the main unit, or an IAM) reporting 876W on the first channel. The <tmpr> field is indeed a temperature reading, this is powered by a temperature sensor inside the EnviR and it simply measures the temperature where your display is located.

Back in 2012, I wrote a set of PHP scripts parsing this data and putting it into separate files in /tmp, with a separate script then throwing this data into RRD files every minute to be visualised in graphs. I never published it because to be frank it was a bit of an ugly hack. However it did work, and I had perfect visibility into when my 3 monitors went into standby, when the TV/Home theater amplifier was on, etc.

After getting a taste of this, spurred on by JP, I dived into Home Automation and ended up using OpenHAB. For years I’ve “planned” to write a CurrentCost binding for OpenHAB, so it would natively support the XML serial protocol, and just read out everything automatically. I never got around to figuring out how to create an OpenHAB binding though, so my stats were separate in those RRD files for years. When I moved, I didn’t even reinstall the CurrentCost sensors, as I was already using Z-Wave based power sensors for most things I wanted to measure.

In the meanwhile I also encountered current-cost-forwarder which listens for the XML data and sends it over to an MQTT broker. That did alleviate the need for a dedicated binding, but I never got around to trying this out, so I can’t tell you how well it works.

The magic of RTLSDR

RTLSDR is a great software defined radio (SDR) based on very cheap Realtek RTL28xx chips, originally meant to receive DVB-T broadcast. This means you can pretty much listen in on any frequency between ~22MHz and ~1100MHz, including FM radio, ADS-B aircraft data, and many others. And by cheap, I do mean cheap, you can find RTLSDR-compatible USB dongles on eBay for 5€ or less!

CurrentCost transmitters use the 433MHz frequency, like many other home devices (car keys, wireless headphones, garage openers, weather stations, …). As I was playing around with the rtl_433 tool, which uses RTLSDR to sniff 433MHz communications, I noticed my CurrentCost sensor data passing by as well. That gave me the idea for this system, and the setup in use that led to this blog post.

Additional advantages for this are that you can now use as many IAMs as you want and are no longer limited to 9, and there is no need to have the EnviR connected to one of your server’s USB ports. In fact, you don’t even need the EnviR display at all, and can even drop the base transmitter if you only want to read out IAM data.

As an extra, any other communication picked up by rtl_433 on 433MHz will also be automatically piped into MQTT for consumption by anything else you want to run. If you (or your neighbours!) have a weather station, anemometer or anything else transmitting on 433MHz (and supported by rtl_433), you can consume this data in OpenHAB just as well!

Sniffing the 433MHz band

First off, let’s install rtl_433:

~# apt-get install rtl-sdr librtlsdr-dev cmake build-essential
~# git clone https://github.com/merbanan/rtl_433.git
Cloning into 'rtl_433'...
remote: Counting objects: 5722, done.
(...)
Checking connectivity... done.
~# cd rtl_433/
~/rtl_433# mkdir build
~/rtl_433# cd build
~/rtl_433/build# cmake ..
-- The C compiler identification is GNU 4.9.2
(...)
-- Build files have been written to: /root/rtl_433/build
~/rtl_433/build# make
~/rtl_433/build# make install

Once it’s been installed, let’s do a test run. If you have CurrentCost transmitters plugged in, you should see their data flash by. Unfortunately, nobody in my neighbourhood seems to have any weather stations or outdoor temperature sensors, so only CurrentCost output for me:

~# rtl_433 -G
Using device 0: Generic RTL2832U
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
Sample rate set to 250000.
Bit detection level set to 0 (Auto).
Tuner gain set to Auto.
Reading samples in async mode...
Tuned to 433920000 Hz.
2017-02-27 17:53:12 : CurrentCost TX
Device Id: 2015
Power 0: 26 W
Power 1: 0 W
Power 2: 0 W

To end the program, press ctrl-C.

What we can see in the output here:
Device Id: the same device ID as was reported by the EnviR’s XML protocol. It likely changes when you press the pair button.
Power 0: This is the only power entry you’ll see for IAM modules, the base device may also report data for the second and third clamp.

It is possible you see the following error when running rtl_433:

Kernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.

This means your OS has autoloaded the DVB drivers when you plugged in your USB stick, before you installed the rtl-sdr package. You can unload them manually:

rmmod dvb_usb_rtl28xxu rtl2832

The rtl-sdr package contains a blacklist entry for this driver, so it shouldn’t be a problem anymore from now on. Then, try running the command again.

Relaying 433MHz data to MQTT

Install mosquitto-clients, which provides mosquitto_pub which will be used to publish data to the broker:

~# apt-get install mosquitto-clients

Next, install the systemd service file which will run the relay for us:

~# cat <<EOF >/etc/systemd/system/rtl_433-mqtt.service
[Unit]
Description=rtl_433 to MQTT publisher
After=network.target
[Service]
ExecStart=/bin/bash -c "/usr/local/bin/rtl_433 -q -F json |/usr/bin/mosquitto_pub -h <your.broker.hostname> -i RTL_433 -l -t RTL_433/JSON"
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
~# systemctl daemon-reload
~# systemctl enable rtl_433-mqtt

This will publish JSON-formatted messages containing the 433MHz data to your MQTT broker on the RTL_433/JSON topic.

Don’t forget to replace your broker’s hostname on the correct line. I tried to make it use an Environment file first, but unfortunately ran into a few issues using those variables, due to needing to run the command in an actual shell because of the pipe. If you figure out a way to make that work, please do let me know.

See if it works

We can subscribe to the MQTT topic using the mosquitto_sub tool from the mosquitto-clients package:

mosquitto_sub -h <your.broker.hostname> -t RTL_433/JSON

Doing this should yield a number of output lines such as this:

{"time" : "2017-03-19 21:26:25", "model" : "CurrentCost TX", "dev_id" : 2015, "power0" : 0, "power1" : 0, "power2" : 0}

Press Ctrl-C to exit the utility. If this didn’t yield any useful JSON output, check the status of the service with systemctl status rtl_433-mqtt and correct any issues.

Add items to OpenHAB

The following instructions were written for OpenHAB 1.x. Even though OpenHAB 2.x has a new way of adding “things” and “channels”, they work on that version as well – there is no automatic web-based configuration for MQTT items anyway.

Create items such as these in the OpenHAB items file of your choice (where this is exactly depends on your OpenHAB major version and whether you installed using debian packages or from the zip file).

Number Kitchen_Boiler_Power "Kitchen Boiler [%.1f W]" (GF_Kitchen) { mqtt="<[your.broker.hostname:RTL_433/JSON:state:JSONPATH($.power0):.*\"dev_id\" \\: 2015,.*]"}

Replace the dev_id being matched (2015 in the example above) with the ID of your CurrentCost transmitter. As all rtl_433 broadcasts come in on the same topic, a regular expression is used to match a single Device Id. If you want to read another phase, replace power0 by power1 or power2.

If you want to receive other 433MHz broadcasts, you may need to change the regex to make sure it’s only catching CurrentCost sensors – although the dev_id match alone might be enough. Let me know!

Writing informative technical how-to documentation takes time, dedication and knowledge. Should my blog series have helped you in getting things working the way you want them to, or configure certain software step by step, feel free to tip me via PayPal (paypal@powersource.cx) or the Flattr button. Thanks!