Like some other Belgians, unfortunately, my analog electricity meter was replaced by a digital one since a few months. Initially, I was quite happy with the change as it allows a much easier look into your consumption and solar panel injection to the net. But exactly that last turned out to be a bummer as the government decided to not keep their word regarding reversing consumption with solar panel injection. Nevertheless, I have the thing so I might as well take advantage of it. This post describes how to connect to and use the data from the P1 port on a digital electricity meter in Belgium.
If you are interested, I also created a YouTube video from this blogpost. If you prefer classic text, you can just follow the rest of this article:
Digital electricity meters are used in a variety of countries. While exploring this, I noticed that each country/region and even device model works in a slightly different way and standard (more about this further in the post). As this post mainly would be interesting for people living in Belgium, for the first time, I decided to also create a Dutch version. You can find this one over here: https://jensd.be/1205/linux/data-lezen-van-de-belgische-digitale-meter-met-de-p1-poort
The electricity meter is communicating back it’s reading, additional data and natural gas meter’s readings back to the distributor, using cellular, on regular times. This allows you to check that data on the site of the distributor itself:
So if your goal is just to see the consumption in a nice graph there is no need to make use of the data coming from the P1 port. If you want to do something with the data on the other hand, like triggering automation or have the ability to use the near real-time information, you are at the right place.
The digital meter
In Belgium, distributor Fluvius has started distribution and installation of the digital meters. They are currently using only three types of digital meters for consumers. One for single phase installations, another for three-phase and a natural gas meter that uses the digital electricity meter to send it’s data as well to the distributor:
- Sagecom S211: Single phase
- Sagecom T211-D : Three-phase
- Flonidan – G4SRTV: Natural gas
The P1 and S1 ports
The electricity meters mentioned above, are having two serial ports on the front of the device, behind the yellow cover. Both these ports can be used to read data from. S1 is sending raw data around 2600-4000 times/second. P1 on the other hand is a bit calmer and provides information around once/second in a more formatted form.
The P1 port, which I will use through the rest of the article, is the most interesting for most users and automation integration.
Both the P1 and S1 ports are following the serial RS422 standard and are using a RJ12 connector. (RJ11 works as well with the correct pinout). Important to know is that these ports are disabled by default. Fortunately, they can easily be enabled using the Fluvius webinterface through https://mijn.fluvius.be/poortbeheer/.
To connect to the ports, you can create a cable yourself with the following pinout:
|1||+5V||Power supply for reading equipment (optional)|
|6||Power GND||Power supply for reading equipment (optional)|
Another option, if you can’t make a cable or are lazy as me, is to buy one of the readily available cables with a serial to usb convertor integrated, like the following:
The data format of the P1 port, as well as the above discussed physical format, is using the DSMR 5.0.2 P1 standard. DSMR stands for Dutch Smart Meter Requirements. And as the name suggests, this was developed and is maintained by our northern neighbors. Unfortunately, while looking up information and seeing the various scripts that are available, I noticed that each model of meter seems to use the standard in slightly different ways. So most of what I will discuss in this post applies to other countries that use DSMR but it might needs some tweaks here and there.
You can find all details of the standard over here: https://www.netbeheernederland.nl/_upload/Files/Slimme_meter_15_a727fce1f1.pdf
To not go to deep but still make things understandable, I’ll try to go through the things you need to know from this in order to start using the data.
The whole message (called telegram or COSEM object), coming from the P1 port in DSMR like the following:
And the data itself, inside the telegram, looks like the following:
This gives us the following info:
- Each block of info (telegram) starts with a /
- After the start, there is a fixed, model specific identification, followed with a fixed device-unique identification
- The data lines start with an OBIS code, including identification from which meter (electricity or natural gas) the data comes and which type of info is next
- The values are inside parentheses and if a unit is preset, it’s separated by a *
- The block of info (telegram) ends with a !
- The CRC field contains a CRC16 calculated value of the rest of the block
In practice: reading and interpreting the data
So far I’ve only covered things from a theoretical angle. Next, let me explain how you can read the data and parse it to do something useful with it.
For this, I’ll start with a minimal install of Debian but another Linux distribution, like Ubuntu, CentOS, or even Windows/OS X should work in the same way.
First, I’ll install pyserial and crcmod using the package manager as I will use Python to parse the data coming from the P1 port.
jensd@deb10:~$ sudo apt install python3-serial python3-crcmod python3-tabulate Reading package lists… Done Building dependency tree ... Setting up python3-serial (3.4-4) ...
Next, just to get started, we can try and read out the serial port. In my case, as I mentioned above, I use the P1 cable with integrated serial to USB convertor so my serial port is /dev/ttyUSB0. Port settings for P1 are 115200 baud, 8N1, Xon/Xoff.
In order for a non-root user to access the serial port, we need to set the right permissions:
jensd@deb10:~$ sudo chmod o+rw /dev/ttyUSB0
And to, finally, test the data coming in:
jensd@deb10:~$ python3 -m serial.tools.miniterm /dev/ttyUSB0 115200 --xonxoff --- Miniterm on /dev/ttyUSB0 115200,8,N,1 --- --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- 925*m3) !CE4E /FLU5\253xxxxxx_A 0-0:96.1.4(xxxxx) 0-0:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-0:1.0.0(210204163628W) 1-0:1.8.1(000439.094kWh) 1-0:1.8.2(000435.292kWh) 1-0:2.8.1(000035.805kWh) 1-0:2.8.2(000012.156kWh) 0-0:96.14.0(0001) 1-0:1.7.0(00.233kW) 1-0:2.7.0(00.000kW) 1-0:21.7.0(00.233kW) 1-0:22.7.0(00.000kW) 1-0:32.7.0(236.2V) 1-0:31.7.0(002.04A) 0-0:96.3.10(1) 0-0:17.0.0(999.9kW) 1-0:31.4.0(999A) 0-0:96.13.0() 0-1:24.1.0(003) 0-1:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-1:24.4.0(1) 0-1:24.2.3(210204163500W)(00343.925*m3) !1374 /FLU5\253xxxxxx_A 0-0:96.1.4(xxxxx) 0-0:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-0:1.0.0(210204163629W) 1-0:1.8.1(000439.094kWh) 1-0:1.8.2(000435.292kWh) 1-0:2.8.1(000035.805kWh) 1-0:2.8.2(000012.156kWh) 0-0:96.14.0(0001) 1-0:1.7.0(00.228kW) 1-0:2.7.0(00.000kW) 1-0:21.7.0(00.228kW) 1-0:22.7.0(00.000kW) 1-0:32.7.0(236.3V) 1-0:31.7.0(002.01A) 0-0:96.3.10(1) 0-0:17.0.0(999.9kW) 1-0:31.4.0(999A) 0-0:96.13.0() 0-1:24.1.0(003) 0-1:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-1:24.4.0(1) 0-1:24.2.3(210204163500W)(00343.925*m3) !4BE6 --- exit ---
As you can see, this matches with the message format for DSMR that I described above. Looking in the documentation, we can find the meaning of these values. This is not always easy as the codes are not an exact match and can contain channel or meter ID. For the examples above, the following applies. I added some other useful ones as well for completeness. More info, specifically for the Belgian meters can be found here as well: https://www.fluvius.be/sites/fluvius/files/2020-02/technische-info-displays-digitale-elektriciteitsmeter.pdf
|0-0:96.1.1||Serial number of electricity meter (in ASCII hex)|
|0-0:1.0.0||Timestamp of the telegram|
|1-0:1.8.1||Rate 1 (day) – total consumption|
|1-0:1.8.2||Rate 2 (night) – total consumption|
|1-0:2.8.1||Rate 1 (day) – total production|
|1-0:2.8.2||Rate 2 (night) – total production|
|0-0:96.14.0||Current rate (1=day,2=night)|
|1-0:1.7.0||All phases consumption|
|1-0:2.7.0||All phases production|
|0-0:96.3.10||Switch position electricity|
|0-0:17.0.0||Max. allowed power/phase|
|1-0:31.4.0||Max. allowed current/plase|
|0-1:24.1.0||Other devices on bus|
|0-1:96.1.1||Serial number of natural gas meter (in ASCII hex)|
|0-1:24.4.0||Switch position natural gas|
|0-1:24.2.3||Reading from natural gas meter (timestamp) (value)|
Running this through a Python script to parse the data, results in the following:
jensd@deb10:~$ python3 test.py Description Value Unit ---------------------------------- -------------- ------ Meter serial electricity XXXXXXXXXXXXXX Timestamp 210204172711.0 Rate 1 (day) - total consumption 439.33 kWh Rate 2 (night) - total consumption 435.292 kWh Rate 1 (day) - total production 35.805 kWh Rate 2 (night) - total production 12.156 kWh Current rate (1=day,2=night) 1.0 All phases consumption 0.329 kW All phases production 0.0 kW L1 consumption 0.329 kW L1 production 0.0 kW L1 voltage 238.3 V L1 current 2.18 A Switch electricity 1.0 Meter serial gas XXXXXXXXXXXXXX Switch gas 1.0 Gas consumption 343.925 m3 ...
In case you are interested in this script, I uploaded it to GitHub: https://github.com/jensdepuydt/belgian_digitalmeter_p1
The script definitely needs more attention but I guess it can serve well as a source for someone that wants to set up his/her small project by using the data coming from the P1 port.
Let me know your thoughts in the comment section!