Home automation: reading my IZAR WMBus PRIOS hot water smart meter

Exploration, trial and error, reverse engineering, and key cracking

April 2020.


My current condo in Lyon has two separate water sources:

Both these streams are metered separately and individually for each condo. It’s now required by law in France that collective HVAC systems have to be billed independently for each consumer, to prevent abuse from a minority of people (reference: Copropriété : individualisation des frais de chauffage et de refroidissement 30 octobre 2019 - Direction de l'information légale et administrative.)

So how is my hot water metered?

Part 1: Discovering the setup

Following the pipes I managed to find this meter in one of my utility closets:

The hot meter at my condo

The contraption is made of two parts:

The water meter

The water meter, i.e. the actual device counting how many liters go through the pipe, was made from SAPPEL, a century old French company that was merged with other German companies over time to create DIEHL Metering, the actual company making the part now.

The closest one I could find on their product catalog is the “ARIES DN15/20”:

DIEHL Metering ARIES DN15-20

As we’ll see later, knowing the precise actual model is not important.

This thing is counting the water volume, and then an additional module is clipped on top of it to transmit the measurements someplace else.

The IZAR module

Clipped on top of the water meter is an IZAR module. Those modules read and count the ticks generated by the ARIES meter, and allows the values to be stored into or broadcasted to other systems.

The model my counter has is an IZAR RC 868 I RA LIGHT, which is coincidently also made by SAPPEL/DIEHL Metering.

The closest I could find on their catalog is the IZAR RC I R4. Those modules store the measurements of the meter and broadcast them wirelessly over the 868MHz license free radio range. This is consistent with the fact that ever since I’ve been living in that condo, no one has even come to my place to read the meter, and I’ve never input the values anywhere. Still, I was billed correctly at the end of each fiscal year. The values have been transmitted wirelessly to a receiving device owned by the company handling the collective hot water furnace of my building.

There are two usual ways this is done:

Great. Now, let’s find out what system my meter is using, and collect the values myself.

Part 2: Finding how the data is transmitted

The name of the device (RC 868 something) and the datasheet indicates 868MHz radio waves are used, which makes sense since that radio range is typically used for these kind of devices (along with the 433MHz ISM range).

Since I worked on this project during the covid-19 lockdown in spring 2020, I didn’t have access to any spectrum analyzer. So it’s time for some good old fashioned internet research.

First, let’s have a look at the datasheet of the IZAR RC I R4. It’s not exactly the model I have, but browsing the entire product catalog of DIEHL Metering, it seems that their receiving technology didn’t change in the last years. So I’ll assume this newer model has the same technology.


Frequency of operation

The description of the module explain that the measurements are made to be read by a passing-by receiver. This means that we should see radio waves periodically, which has great advantages:

The device has an internal battery which is supposed to last 15 years.


The datasheet says the communication protocol is named "PRIOS". Unfortunately, this is a private internal protocol of DIEHL Metering, and no documentation is provided anywhere.

Let’s read more:

“Reading through M-Bus application with an IZAR CENTER associated to an IZAR RECEIVER M-BUS is also possible”.

“ZAR RECEIVER M-BUS is used for fixed network reading of meters equipped with an IZAR radio. It converts the data into M-Bus format and transmits them to an IZAR CENTER M-Bus master.”

Could this be Wireless M-Bus? That’d be great. This thing is a standard protocol and documentation exists about it.

Let’s look at the standards the device is compliant with:

Quoting the description of the norm:

“It consists of 9 documents. M-Bus (Meter-Bus) is a European standard (EN 13757-2 physical and link layer, EN 13757-3 application layer) for the remote reading of gas or electricity meters. M-Bus is also usable for other types of consumption meters. The M-Bus interface is made for communication on two wire, making it very cost effective. A radio variant of M-Bus (Wireless M-Bus) is also specified in EN 13757-4. The DLMS/COSEM standard suite (IEC 62056 / EN 13757-1) is the most widely accepted international standard for utility meter data exchange.”

Ok, if the datasheet doesn’t lie, we’re definitely dealing with Wireless M-Bus here. What a relief. My guess now is that everything in the protocol stack up to the application level is WMBus, and PRIOS is the business payload transmitted on top (i.e. the device’s measurements).

During my research I also found the specifications of a protocol named “Open Metering System Specification”, which is a European Union normalization club for smart meter companies. Its goal, among others, is that companies providing utilities such as gas or water can use measuring and receiving equipment in a nice interoperable fashion. I have a very good opinion of this initiative. Standards are good. Normalization is good.

Looking at the member list of this club indicates that DIEHL Metering is a part of it. If the manufacturer of my smart meter is part of the EU normalization club for smart meters, then I should be able to use the documents provided by the club (specifications, protocols, etc.)

Let’s sum up what we should see going up the stack:



Reference document

Application layer

PRIOS protocol


Data Link

Wireless M-Bus DLL (format of the frames).
OMS specs (values of the different fields).

EN 13757-4:2019
Open Metering System Specification

Physical Link

Wireless M-Bus PHY

EN 13757-4:2019


In order to test everything here and start doing measurements, I bought a STEVAL-FKI868V2 kit from ST-Micro (a NUCLEO-L053R8 board with a S2-LP 868MHz transceiver). I should be able to program those two boards to experiment with the different layers, and hopefully get my data.

Part 3: Going up the stack – Physical Link Layer

Gathering information

Let me rant for a bit first. I don’t care if private companies invent their own norms and license them for money. Your money, your norms, your price.

But here we’re talking about European Union standards. This was funded with public money and is supposed to apply to all EU countries. So why the f*ck am I supposed to pay 500€ per document?!? (6 of them). And I can’t get a PDF? This thing is made for the people by the people. Why the hell would I need to pay 1000s of euros to get a f*cking ton of paper delivered to my place. Come on EU! You can do much better than that!

So now we know we can’t read the actual standard. What do we do? We browse the internet and collect data from multiple places.

I’ve sourced the following data from 3 types of places:

In the end this is what I found:

The physical layer of WMBus can work in a lot of different modes, each one for a specific type of business usage.

The OMS specs helps us filtering the list:

My meter is unidirectional (according to its datasheet, and according to the fact it’s going to use the same battery charge for 15 years), so we know it’s only going to be mode S1, T1 or C1.

C1 is made for stationary operation, and we know my meter is drive-by, so it’s either S1 or T1.

Layer format

Here is the information I gathered for those two modes:


Mode S1

Mode T1







Data rate





3 out of 6

Sync mechanism

Preamble + Sync word

Preamble + Sync word


“01b” times 279

“01b” times 19

Sync word



I’m going to dig into details about the modulation and encoding part of the layer here. Information about FSK modulation and Manchester/3-out-of-6 encoding is available easily on the internet and in books.

So, here’s what the binary data received is supposed to look like:

S1 mode:

Whatever happens before the start of the frame

“01” times 279

Sync word






T1 mode:

Whatever happens before the start of the frame

“01” times 19

Sync word






Alright, that’s all we need to know. Let’s move up the stack.

Part 3: Going up the stack – Data Link Layer

The WMBus standard tells us which fields are present in the DDL, and the OMS specs tells us what to expect in each field.

The WMBus Data Link Layer (DLL) format

There are two possible formats allowed by the protocol. Frame format A and Frame format B.

Here what they look like:

Frame format A:

WMBus DLL Frame format A

Frame format B:

Frame format B is very similar to Frame format A, but since I didn’t actually see any of them in the wild, I’m not going to risk documenting them here (spoiler alert: my meter is using format A).

Here are the different fields of the DLL:

Field name



L: Length

1 byte

Length of the entire frame except 1 byte (the L field)

C: Control

1 byte

Type of the frame

M: Manufacturer

2 bytes

ISO 646 code of the sender

A: Address

6 bytes

Identifier of the sender


2 bytes

CRC code of the preceding data

CI: Control Information

1 byte

Type of protocol used by the data


N bytes

Upper layer data

Fields in the context of the OMS

The Open Metering System specs contains a list of allowed values for the C-field. Most of them describe how meters should communicate bidirectionaly with a collector. Since my meter doesn’t have a receiving antenna, this limits the communications to only one frame type:


So field C should only be 0x44.

The address field format is not up to manufacturers as well. It’s composed of 3 fields:

OMS DLL address field

Allowed device types are listed in the OMS standard document (Water meter = 0x07, Hot water meter = 0x15, etc.)

Part 4: Collecting frames from the meter

Collecting frames

Before digging into the application layer of the stack, it’s time to capture some frames.

I won't go into into much details about the 2 full days I spent trying to configure the microcontroller and the transceiver of my ST kit until I was able to properly capture frames. Part of the reason it took so long includes:

After a super long time fiddling around, I managed to capture some frames that look like proper WMBus frames. I got them in T1 mode (868.95MHz, 80kHz deviation, 350kHz filter bandwidth, -100dbm RSSI threshold).

Here are a couple examples:



Let’s decode their link layers:


First frame

Second frame

L field



C field



M field



A field



Let’s decode the M fields:


First frame

Second frame

Data (little endian)



The represented number in binary

01000 11001 00100

10011 00001 10000

Each 5 bits block in decimal

8 25 4

19 1 16

Letters corresponding to each number (A=1, B=2, Z=26)



It’s easy to guess what HYD and SAP stand for, but let’s look them up in the flag database of the Device Language Message Specification consortium:



Since my meter was manufactured by Sappel, it’s quite obvious which frames I should investigate further.

Decoding a Sappel frame

Let’s look at a full frame received by the antenna of my circuit:

01010101010101010101010101010101010101 0000111101b + 1944304CC697D720D401E2E6A213120013184587BD6EB979401E8B407096h




01010101010101010101010101010101010101 0000111101 (binary)

T1 preamble + sync word



L-field, length of the frame



C-field, SND-NR: periodical data broadcast



M-field, SAP = Sappel



A-field Id, identifier of the meter



A-field version



A-field type, 01=non-standard application specific



CRC of 1944304CC697D720D401



CI-field, application specific



Application data



CRC of the application data


Right now I’m capturing the frames or a dozen Sappel meters, each of them sending its data about every minute. This is great. This means I should be able to plot my hot water consumption with a 1 minute interval. This is going to be great data!

Now, the problem is the application data is encrypted, and the actual protocol is not known. It’s time to move to the next step.

Part 5: the PRIOS protocol

How do we decrypt and decode the application payload?

First way: we look around and see if some has done it before

So it turns out one guy named Jacek Tomasiak already decoded the protocol and added the logic into an application called wmbusmeters:


I’ve copied his logic into my code, and I confirm it works great.

But let’s imagine this work hasn’t been done before and see if we can achieve it ourselves.

Second way: check if we can extract data from the receiver products

Looking for receiver solutions

DIEHL Metering provides a number of devices we can use to collect the radio waves from the meters. But since those are probably expensive (they’re not on the shelf products), I’m not going to buy one to check what’s inside.

What about software?



DIEHL provided a software solution to manage a fleet of meters in a city.

“Offers all the functionalities of MBUS reading solutions such as IZAR CENTER, either in direct connection (via RS232, USB, LAN) or in remote connection (modem) as well as the management and analysis of the data coming from MBUS meters.”

So, if this sentence is right, the logic to decode the WMBus frames should be somewhere in there. How do we get it?

Well, I didn’t see any download button anywhere, and I didn’t really wanted to waste the time of their salesman to schedule a trial (we’re in a pandemic right now), but fortunately, DIEHL provides an AMI on Azure with the whole thing already installed:



Let’s fire one and see what we can find inside.

I’m not going to go into great details about the exploration of the image since the application and its files are the property of DIEHL Metering and I don’t technically have a license for them. What I can say is that the whole system contains code to collect data via MQTT, multiple databases (Elasticsearch, Derby) and web apps for management.

Disassembling a dozen application packages lead me to discover the logic to decrypt and decode the PRIOS payloads.

Extracting the logic and protocol

Here is the logic to detect the payload type and check for errors (only following the path for my specific meter):


Decrypting the data is done using XORs and a https://en.wikipedia.org/wiki/Linear-feedback_shift_register

I’m not going into details here. You can find my C implementation based on Jacek’s here:


Here’s the content of each part of the payload, with payload 13120013184587BD6EB979401E8B40 as an example:



Example value

Example details

Status field 1

Bit 8: general alarm.
Bits 7-5: random generator.
Bits 4-1: radio interval (value = 1 << v + 2) in seconds.


No general alarm.
Random = 1.
Radio interval = 32s.

Status field 2

Bit 8: leakage currently.
Bit 7: leakage previously.
Bit 6: meter blocked.
Bits 5-1: remaining battery life in half years


No leakage detected, meter is not blocked.
Battery life remaining = 9 years.

Status field 3

Bit 8: back flow.
Bit 7: underflow.
Bit 6: overflow.
Bit 5: submarine.
Bit 4: sensor fraud currently.
Bit 3: sensor fraud previously.
Bit 2: mechanical fraud currently.
Bit 1: mechanical fraud previously.


No alarm set here


Identifies the unit of the measurement.
Bits 8-4: unit type.
Bits 3-1: multiplier exponent + 6.


00010b = volume in cubic meters.
011b = 3. 3-6 = -3. Volume is expressed in m3*10^-3, so in liters.


Always set to 4B, called “old IZAR specific config field”


Set correctly

Current reading

4 bytes, current value measured by the meter


47730200h = 160583d.
160583 * 10^-3 = 106.583m3

H0 reading

4 bytes, historical value measured by the meter


8A6D0200h = 159114d.
159114 * 10^-3 = 159.114m3

H0 date

2 bytes, contains the date of the H0 reading.
year = ((byte1 & 0xF0) >> 1) + ((byte0 & 0xE0) >> 5).
month = byte1 & 0xF.
date = byte0 & 0x1F.


2020-04-01, the beginning of the month when this frame was captured.

Only the 4B field and the readings and the H0 date are encrypted. The 4 first bytes, called the header, are plain text.

But wait? How did I decrypt the data if I only knew the encryption algorithm? Shouldn’t there be a key?

Yes there is. But embedded into the code of the IZAL collector was the two “PRIOS default keys”. And turns out all the meters in my building are using the first one! Talk about security!

Cracking the key

Let’s imagine for a second that the people who installed my meter did their job correctly and actually set a different key than the default one (if they could, maybe the device doesn’t support that, which would be even worse).

How do we find the key?

Easy: we gather a bunch of frames and we brute-force it.

We know the first byte is always 0x4B, the next 4 bytes and the next 4 bytes represent a monotonically increasing value (the second being lower or equal than the first), and the next 2 bytes encode a proper date.

But how long is this cracking going to be, you ask?

Well, if you look at the code, the first thing the key is used for is to create another key, with half the length of the original one:

uint32_t preparePRIOSKey(uint8_t *bytes) {
    uint32_t key1 = read_uint32_be(bytes, 0);
    uint32_t key2 = read_uint32_be(bytes, 4);
    uint32_t key = key1 ^ key2;
    return key;

Since the final key is only the first part of the 64 bit original key, XORed with the second part, we should be able to find a working 32 bit key out of the first 32 bits of our choice.

Here is a quick and dirty bunch of C for loops than can be used to find a key:

Here is the key originally used by my meter:

{0x39, 0xBC, 0x8A, 0x10, 0xE6, 0x6D, 0x83, 0xF8}

Here are a bunch of keys that work just as well, that I cracked from a list of captured frames:

{0xdf, 0xd1, 0x09, 0xe8, 0x00, 0x00, 0x00,0x00}
{0x01, 0x7c, 0xb7, 0x47, 0xde, 0xad, 0xbe, 0xaf}
{0x20, 0x2e, 0xf6, 0x17, 0xff, 0xff, 0xff, 0xff}

Each of them took a few minutes to find on modern PC computer.


So that’s it, we’re done identifying everything received by the antenna, from the physical synchronization to actual application data.

Here is the hot water consumption of a dozen random meters within my antenna's range:

Water consumption of the building

Fewer people shower on Sunday morning than on Monday morning.

This nice adventure can come to an end.

You can find my complete implementation for the ST kit here:


If you have a different PRIOS device than mine, or if you have the time and motivation to write a complete PRIOS decoding library, feel free to contact me for help.

Here are a couple pull requests I submitted to wmbusmeter: