
Organizing a remote collection of readings from electricity meters is not a difficult task, the meters are getting smarter and smarter every year and we have to send everything ourselves, but no, of course there is information, but it is fragmented. Equipment manufacturers apparently also want to make money selling their software. I am writing this article to save time for everyone who has similar tasks.
Start
The company needed to automate the collection of readings from electricity meters, about twenty pieces. Make it required quickly and as cheaply as possible. Therefore, it was decided to collect data using the already deployed Zabbix, but to connect to the counter, it was necessary to write a small script, more on that below. It turned out that the collection of readings is only one of the parameters that need to be collected, the rest are responsible for a PC with Debian on board, so it was not difficult to connect to the meter via the COM port. Of course, for most, it will be more convenient to use a local network and get information from an industrial switchboard or interface converter.
Of the connection options, you can also consider an opto-port, though you will need to purchase an additional device, on the other hand, you do not need to remove the seal.
')

Terminals for connection to the meter are located under a sealed cover.
Therefore, we had to negotiate with the network company about what, you need to remove the seals, do the work, and re-seal the meters. But in the end, the agreements were reached and it was possible to safely deal with the solution of the main task.

The solution of the problem
As follows from the
official documentation.The counter accepts a string of bytes in the format ADDR-CMD-CRC, and gives ADDR-CMD-DATA-CRC, where:
- ADDR - counter name (for mercury 203.2 - same as the serial number)
- CMD - Team Code
- DATA - Data dependent on the request.
- CRC - 2x byte cyclic redundancy code, calculated over all previous bytes of this packet. From this explanation it is not clear what to write in the checksum field.
The hyphen in the sequence is not used; here it is used to separate logical blocks.
First of all,
let's connect to the counter using the standard
konfigurator program and, with the help of a sniffer, look at the transmitted packets, find out what checksum needs to be added to the end. Below, the string received from the counter.

Using the
online calculator CRC find out what you need to calculate the CRC-16 (Modbus) with the polynomial 0xA001.
Little python
There are enough links to the calculation algorithm, so I will not dwell on it. For development I used Python 3
def crc16(data): crc = 0xFFFF l = len(data) i = 0 while i < l: j = 0 crc = crc ^ data[i] while j < 8: if (crc & 0x1): mask = 0xA001 else: mask = 0x00 crc = ((crc >> 1) & 0x7FFF) ^ mask j += 1 i += 1 if crc < 0: crc -= 256 result = data + chr(crc % 256).encode() + chr(crc // 256).encode('latin-1') return result
Now we will try to get its serial number from the meter and check the CRC. You will
need to install the
pyserial module
. import serial import struct import time sn = 26222790
Fine! Now we will get the values ​​for the consumed energy according to the first and second tariffs, in fact, we only need to change the command field and parse the result.
chunk += b'\x27' t1 = ''.join('{:02x}'.format(c) for c in out[5:9]) t2 = ''.join('{:02x}'.format(c) for c in out[9:13]) print ('T1 =', float(t1)*0.01, '(*)', 'T2 =', float(t2)*0.01, '(*)')
Everything is working. The final version of the script posted on
git . In the future, I plan to add support for work on the local network.
A USB -> COM “Mercury-221” Adapter was used for development, but you can directly connect the meter to the COM port.
References:
Useful information on connecting the meter
is here.Documentation on the official websiteTechnical Support SiteAbout CRC on
Wikipedia