Monitoring of electricity meters in one evening

There are 25 Mercury 236 ART electricity meters connected by RS485 network for remote data acquisition. There was a task – to organize monitoring of the state of metering devices as soon as possible and automatically save the values ​​of the energy accumulated by them.

Receiving data from counters

After minor modifications to the utility mercury236 I was able to access counters by individual addresses and receive data from them in JSON format. The installation process of the utility and a demonstration of its operation is below.

[root@localhost ~]# git clone https://github.com/ensoelectric/mercury236
[root@localhost ~]# cd mercury236
[root@localhost mercury236]# make
-std=c99 -lpthread -lrt
cc mercury-cli.c mercury236.c -std=c99 -lpthread -lrt -o mercury236
cc mercury-mon.c mercury236.c -std=c99 -lpthread -lrt -o mercury-mon
[root@localhost mercury236]# cp mercury236/mercury236 /usr/bin/
[root@localhost mercury236]# mercury236 /dev/ttyr00 115
  Mains status:                               On
  Voltage (V):                            228.38   227.51   226.93
  Current (A):                              9.06     8.09    11.87
  Cos(f):                                   0.58     0.43     0.74 (    0.60)
  Frequency (Hz):                          49.97
  Phase angles (deg):                     119.83   240.15   120.32
  Active power (W):                      1208.21   792.42  1991.39 ( 3992.02)
  Reactive power (VA):                   2070.08  1839.36  2695.36 ( 6604.80)
  Total consumed, all tariffs (KWh):     766174.88
    including day tariff (KWh):          500278.53
    including night tariff (KWh):        265896.28
  Yesterday consumed (KWh):                 90.32
  Today consumed (KWh):                     40.33
[root@localhost mercury236]# mercury236 /dev/ttyr00 115 --json
{"mainsStatus":1,"U":{"p1":228.14,"p2":227.41,"p3":226.68},"I":{"p1":9.11,"p2":8.13,"p3":12.39},"CosF":{"p1":0.58,"p2":0.43,"p3":0.75,"sum":0.61},"F":49.97,"A":{"p1":119.90,"p2":240.01,"p3":120.11},"P":{"p1":1207.87,"p2":794.27,"p3":2094.69,"sum":4096.83},"S":{"p1":2078.40,"p2":1848.64,"p3":2809.92,"sum":6736.96},"PR":{"ap":766174.88},"PR-day":{"ap":500278.53},"PR-night":{"ap":265896.28},"PY":{"ap":90.32},"PT":{"ap":40.33}}

Setting up monitoring

Zabbix 5.4 will be used as a monitoring system. I consider each metering device as a host, therefore sample… It contains an item of type “Zabbix trapper” and several dependent items.

When creating a host, connect the template and choose a name, adhering to the following rule: “Mercury [0-255]”, where [0-255] – the network address of the meter.

Storing “readings”

Let’s prepare tables for storing the values ​​of the energy accumulated by the meters (A +).

-- Версия сервера: 10.3.22-MariaDB

DROP DATABASE IF EXISTS Mercury236Reports;

CREATE DATABASE Mercury236Reports; 

USE Mercury236Reports;

--
-- Таблица `daily_consumed` содержит значения 
-- накопленной активной энергии (A+) за сутки.
--

CREATE TABLE `daily_consumed` (
  `addr` tinyint(4) UNSIGNED NOT NULL,
  `report` date NOT NULL,
  `ap` float NOT NULL,
  `created_at` datetime NOT NULL DEFAULT current_timestamp(),
  `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  PRIMARY KEY (`addr`,`report`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

--
-- Таблица `total_consumed` содержит значения накопленной от сброса 
-- активной энергии (A+) по сумме тарифов. Сохраняем последнее значение,
-- полученное в текущем часе.
--

CREATE TABLE `total_consumed` (
  `addr` tinyint(4) UNSIGNED NOT NULL,
  `report` datetime NOT NULL,
  `ap` float NOT NULL,
  `created_at` datetime NOT NULL DEFAULT current_timestamp(),
  `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  PRIMARY KEY (`addr`,`report`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Sending and saving data

To send data to Zabbix server and save information to the database, you will need the zabbix_sender utility and a shell script of the following content.

#!/bin/bash

# mercury236polling.sh

#Power meters address
pm_address=(7 34 43 48 50 54 67 70 73 76 80 81 82 84 89 93 97 115 125 142 144 146 158 199 234)

#ZBX Server
zbx_host="127.0.0.1"

#DB credential
db_host="127.0.0.1"
db_name="Mercury236Reports"
db_user="user"
db_passwd="passwd"

while [ 1 = 1 ]
do
    for i in ${!pm_address[@]}
    do  
        data=$(mercury236 /dev/ttyr00 ${pm_address[$i]} --json)
        zabbix_sender -z $zbx_host -s "Mercury ${pm_address[$i]}" -k data -o "$data"
        
        #Save A+ values
        py=$(echo "$data" | jq '.PY.ap')
        pr=$(echo "$data" | jq '.PR.ap')
        mysql --host=$db_host --user=$db_user --password=$db_passwd $db_name -e "INSERT INTO daily_consumed (addr, report, ap) VALUES (${pm_address[$i]}, SUBDATE(CURRENT_DATE, 1), $py) ON DUPLICATE KEY UPDATE ap=$py;"
        mysql --host=$db_host --user=$db_user --password=$db_passwd $db_name -e "INSERT INTO total_consumed (addr, report, ap) VALUES (${pm_address[$i]}, DATE_FORMAT(NOW(), "%Y-%m-%d %H:59:59"), $pr) ON DUPLICATE KEY UPDATE ap=$pr;"

        sleep 1
    done
done

After running the script in the console, trapper elements should receive JSON, and the database should be replenished with data on the accumulated energy.

Create a service in systemd

In order to regularly request data from metering devices, we will create a service based on the mercury236polling.sh script.

[root@localhost ~]# cp mercury236polling.sh /usr/bin/
[root@localhost ~]# cat /etc/systemd/system/mercury236polling.service
[Unit]
Description=Monitoring of electricity meters "Incotex Mercury 236"
After=network.target

[Service]
Type=simple
ExecStart=mercury236polling.sh

[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl enable mercury236polling.service
[root@localhost ~]# systemctl start mercury236polling.service
[root@localhost ~]# systemctl -l status mercury236polling.service
● mercury236polling.service - Monitoring of electricity meters "Incotex Mercury 236"
   Loaded: loaded (/etc/systemd/system/mercury236polling.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2021-11-09 17:26:48 +03; 10min ago
 Main PID: 3458296 (mercury236polli)
    Tasks: 2 (limit: 23669)
   Memory: 672.0K
   CGroup: /system.slice/mercury236polling.service
           ├─3458296 /bin/bash /usr/bin/mercury236polling.sh
           └─3462352 sleep 1

Result

In the future, you will probably need to configure alerts, but for now you can stop there. Below are screenshots of dashboards with graphs of phase voltage, instantaneous power in the Zabbix web interface and an example of sampling accumulated readings from the database.

Dashboard and the network card in the web interfeyse.
Dashboard and the network card in the web interfeyse.
Sample from the database.
Sample from the database.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *