Analyzing the Efergy HM01 Air Data Format

Isn’t it funny how having the Efergy HM01 power meter sitting on my desk, looking all “sad” from not being used makes me suddenly want to make an effort to try and reverse engineer the air interface?

I suppose part of it was the determination of the packet format looked rather simple compared to the Efergy Elite (which I didn’t do any reverse engineering or analysis of). But because my switchboard was already filled with clamps, I’d have to improvise and get a controllable load. The first thing I did was grab an unused powerboard, and very carefully score the outer sheathing of the wire. Removing about 15cm of it, without damaging the inside PVC insulation, I separated the wires and clipped the current transformer over the active line.


The other part of the equation was a controllable load – the largest thing I had easily available was a 150w linear halogen floodlamp, and I combined this with an Ikea Dimma 300w power-lead type TRIAC dimmer to adjust the apparent load. While I know TRIAC dimmers are very electrically “noisy”, I’m sure the power meter will happily smooth it out. Ultimately, we just want to see what the response of the transmitter is under load, now that I think about it, plugging a regulated DC voltage supply with an opamp to generate voltages might work just as well as long as it doesn’t expect to see sinusoidal variations in the CT voltage. Maybe I could try that next time.

Anyhow, the challenge was to capture the demodulated FM waveform of the PSK data at various indicated loads by the receiver. My fruit is presented graphically here – click for larger (Note: Line Voltage set at 240v):


I’ve highlighted my best guesses at the deconstruction of the “parts” of the waveform. Much of it is fixed and non-variable. As I can’t really try out the complete range of the transmitter, I don’t have all the codes covered, only a small fraction of it. Some of the data part may actually be “fixed” as well, I can’t know for sure unless I somehow get a synthetic input into the transmitter that works (and doesn’t fry it!)

What seems interesting is the length of the fixed field. It’s so long, it’s practically a good half of the transmission when combined with the pre and post-ambles. The separator field may actually be longer and extend into the data field – I have a sneaking suspicion that most things should be in multiples of 8 (for bytes) or 10 or something like that (assuming this is a serial stream, accounting for start and stop bits), although I can conceive that they could have chosen something arbitrary as well.

As for the coding, I’m a bit out of my depth. I’m guessing it’s NRZI (non-return-to-zero-inverted), but until I get out a ruler and draw out the binary bits, I have no idea. But I hope this does help somebody develop something?

Collateral Discovery

In some senses, I was glad I undertook the challenge to try and discover the air interface because I discovered something else. It seems rtl_fm for Windows might have some USB buffering problems! I say this because all of the above analysis was made with rtl_fm dumping to file by providing a filename, and I spotted some unusual results (infrequently).


Notice the yellow highlighted regions where the FSK appears anomalous – it appears there may be buffer overrun somewhere, and bits are “shuffled” to the wrong place. In the bottom trace, we might have missed a whole segment of time because the frame starts from noise, sans preamble!

It was running under Windows 7 on my main workstation, a (at the time) lightly loaded AMD Phenom II x6 1090BE from a little while back – you would assume, plenty of grunt for rtl_fm to get a 200khz FM decode resampled to 96khz.

So maybe the anomalous decode rate results under Windows I reported earlier are as a consequence of random buffer overflows in rtl_fm when communicating with the dongle (over the Zadig driver) causing packets to be mangled when the corruption just so happens to align with the transmission (due to low duty cycle, not easily evident).

Of course, more needs to be done to confirm this, however, I find it a fairly plausible explanation.

Update: I’ve asked Nathaniel for a little help in reverse engineering it, and it became apparent that I didn’t upload any raw samples. I’ve spent part of today taking raw samples, you can download the ~ 16.4Mb archive here. The files are named hm01-<indicated power>.raw (there are three packets for zero, every other one only has one packet), and are output from rtl_fm demodulating a 200khz bandwidth resampled at 96khz sample rate. The indicated power is with the efergy HM01 at the default 240v (as this is an Australian model).

To ensure signal quality, the receiver was <2m from the transmitter, resulting in a fairly clean FSK signal. Due to a limited selection of loads, I couldn’t really explore much higher than 1.472kW as I had to remain within the limits of the 7.5A “rated” cheap China powerboard. I don’t have enough room on my distribution board for another clamp either.

I did preview the captures, and verified there were no runt frames (this time, I didn’t get any). I hope this will be good enough to come up with a good understanding of the signal.

Update 2: It seems the product says its capable of measuring up to 90A per phase, which is 21.6kW. Because of my limited “loads” and my use of a general-purpose outlet as my source, I thought I couldn’t generate higher loads. And then, last night, just before I fell asleep, it hit me.

It’s a current transformer! You know what this means …


Yep. Wrap the wires around a few times, and you can multiply the field strength. Voila. Instant 10x multiplier. Took a lot of careful de-sheathing without cutting the inner insulation to achieve, and now the core clearance is entirely taken up with copper.

As a result, I now have a second bag of samples here (9.43Mb) which cover up to 15.27kW indicated load. This should be much more useful.

About lui_gough

I'm a bit of a nut for electronics, computing, photography, radio, satellite and other technical hobbies. Click for more about me!
This entry was posted in Computing, Electronics, Radio and tagged , , , . Bookmark the permalink.

3 Responses to Analyzing the Efergy HM01 Air Data Format

  1. Mike Sumbler says:

    Hi Gough,

    Inspired by your post and a HM01 gathering dust I decided to try and continue where you started off. Suffice to say I managed to get a way into it but ended up hitting a wall and now need some help from more experienced folk out there.

    Here’s what I’ve learn’t…

    The hardware:

    – Manual:
    – 90A to 60mA range
    – 110V to 440V range
    – Transmits 6, 12, 18s. Allows for three sensors
    – Uses a NEC D78F0512 8 bit single chip microcontroller:

    The transmission:

    – Command used to retrieve samples

    rtl_fm -M wbfm -f 433969000 -l 57.8 -g 27.8 -s 200k -r 96k -A fast > sample.raw


    rtl_fm -M wbfm -f 433969000 -g 27.9 -s 200k -r 96k -A fast > sample.raw

    – I processed each file in audacity and exported to .txt (normalised decibel) and reviewed in excel

    Results here:

    – Looks like the transmission is some form of PSK not FSK unlike E2 / Elite units.
    – Encoded as Non-Return-Zero (NRZ). Low =0, High =1
    – Prior to the transmission the signal drops low for three bits, 2700uS
    – The following transmission is 12 bytes long
    – Each signal element is 900uS in length.
    – Bytes 1 – 3 are a preamble (12x 0 and 12x 1)
    – Bytes 4 – 6 are probably manufacturer / device ids as you suggest
    – Byte 7 marks the start of the pay load (00001000)
    – Byte 8 contains the none decimal fraction of the recorded ampage
    – byte 9 contains looks like it is the decimal fraction of the recorded ampage
    – Byte 10 looks like a exponent used for calculating the decimal fraction
    – Byte 11 contains some sort of checksum
    – Byte 12 is a trailing post able of 4x 1 4x 0
    – Doesn’t appear to have any parity bits and is MSB.
    – Device calculates W using A*V, with the voltage set on the unit

    The problem:

    What ever I try (and have looked at alot of different methods) I can’t calculate the decimal fraction of the ampage….. its not the same calculation made in the E2.Its not straight BCP. Byte 10 must be used for bit shifting but again whatever combination I do I can’t represent what I am seeing on the receiver.

    Can someone help……

    Many Thanks

  2. John says:

    Hi, I appreciate this is late in the day, but I’ve had some success with my old HM01.
    Using rtl_433 I used:

    rtl_433 -F csv -R 0 -X ‘n=efergy_hm01,m=OOK_PCM,s=416,l=416,r=425984,invert,preamble=A2DD4793C’
    (the preamble is just to cause the correct bit alignment to extract the data we need
    This gives me a string like this:
    2019-01-11 00:12:21,,{119}026c0528abfffffffffffffffffffe,efergy_hm01,1,1,

    Take the first 8 hex digits and we get 026c0528, which is 40,633,640 decimal, divide that by 2^24 we get 2.42 Amps which is 557W (at 230V) This nearly agreed with the display, so crudely I hacked the divisor to 16377216 which makes the numbers agree with the display pretty spot on (+/- 1). Tested from 0-4KW all works well, although I admit this is a hack rather than an analysis of the protocol!

    Hope it helps!


    • lui_gough says:

      Dear John,

      Thanks for letting me know – I haven’t kept pace with the capabilities of rtl_433, but it seems like it has more analysis features than it might have in the past. Good to know the “fudge factors” needed – this will probably differ depending on voltage and any errors in the ADC/clamp combination, but still a good starting point for anyone still using these units who might not have any way to obtain the data.

      Great work!

      – Gough

Error: Comment is Missing!