EnergyCount 3000, part 2
A few months ago I was writing about my attempts to reverse engineer radio transmissions from Voltcraft EnergyCount 3000 devices. Since then a lot of the things I was speculating about got much clearer, mostly thanks to reverse engineering efforts on the jeelabs.net forum. Yesterday there was an Open Data Hackday in Kiberpipa and, while this wasn't strictly on topic, I finally managed to integrate all of the little pieces of the puzzle together into one working, simple to use Python module.
So today, I'm pleased to announce the first release of ec3k, a software receiver for EnergyCount 3000 devices. It's built around GNU Radio and currently works with cheap, RTL2833-based receivers. You can fetch it from Cheese shop or directly from GitHub. It's licensed under GPL version 3 or later.
The biggest obstacle you need to cross before using it is installing GNU Radio, rtl-sdr and gr-osmosdr. A good starting point is the Osmocom Wiki which has a quick overview and links to other relevant documents. When GNU Radio is working for you, only the standard Python distutils dance remains:
$ python setup.py install $ python setup.py test
The package includes a simple command utility which prints out all received packets to the standard output:
$ ec3k_recv linux; GNU C++ version 4.4.5; Boost_104200; UHD_003.004.002-128-g12f7a5c9 gr-osmosdr supported device types: file fcd rtl rtl_tcp uhd Using 16 buffers of size 262144. Using device #0: ezcap USB 2.0 DVB-T/DAB/FM dongle Found Elonics E4000 tuner >>> gr_fir_ccf: using SSE Using Volk machine: avx_64 Noise level: -27.3 dB Noise level: -27.4 dB Noise level: -27.5 dB id : f100 uptime : 4004 seconds since last reset: 37809 seconds energy : 385300 Ws current power : 1.3 W max power : 2.3 W energy : 4579600 Ws Noise level: -26.7 dB Noise level: -26.8 dB
Here is how you can use the ec3k module from your own Python code:
import ec3k
def callback(state):
print state
my_ec3k = ec3k.EnergyCount3K(callback=callback)
my_ec3k.start()
while not want_stop:
time.sleep(2)
print "Noise level: %.1f dB" % (my_ec3k.noise_level,)
my_ec3k.stop()
As shipped, the receiver uses around 20% of one CPU core on a 2.7 GHz Intel i5 CPU. You can improve that by using my C implementation of the base-band decoder from the am433 project. Just compile the capture binary (version 0.0.4 or later) and drop it somewhere in your PATH. ec3k should find it automatically and use it instead of the built-in pure Python implementation.
For details on the API, please check the included README and docstrings. README also lists a couple of known problems that are still present in the code. Any help regarding those, or otherwise, is most welcome as always.
Again, thanks goes to the people on jeelabs.net forum for figuring out how to descramble the packets and Gašper for providing the hardware, Python base-band decoding code and testing.


