
Имеется 25 счетчиков электроэнергии Меркурий 236 ART, объединенных сетью RS485 для дистанционного получения данных. Появилась задача - как можно скорее организовать мониторинг состояния приборов учета и в автоматическом режиме сохранять значения накопленной ими энергии.
Получение данных от счетчиков
После небольших доработок утилиты mercury236 я получил возможность обращаться к счетчикам по индивидуальным адресам и получать от них данные в формате JSON. Процесс установки утилиты и демонстрация ее работы ниже.
[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}}
Настраиваем мониторинг
В качестве системы мониторинга будет использоваться Zabbix 5.4. Каждый прибор учета я рассматриваю как хост, поэтому был создан шаблон. Он содержит элемент типа "Zabbix траппер" и несколько зависимых от него элементов.

При создании хоста подключаем шаблон и выбираем название, придерживаясь следующего правила: "Mercury [0-255]", где [0-255] - сетевой адрес счетчика.

Хранение "показаний"
Подготовим таблицы для хранения значений накопленной счетчиками энергии (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;
Отправляем и сохраняем данные
Для отправки данных Zabbix серверу и сохранения информации в БД потребуется утилита zabbix_sender и shell-скрипт следующего содержания.
#!/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
После запуска скрипта в консоли траппер-элементы должны получать JSON, а БД - пополняться данными о накопленной энергии.
Создаем сервис в systemd
Для того чтобы регулярно запрашивать данные от приборов учета, создадим сервис на основе скрипта mercury236polling.sh.
[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
Результат
В дальнейшем, вероятно, потребуется настройка оповещений, пока же на достигнутом можно остановиться. Ниже скриншоты дашбордов с графиками фазного напряжения, мгновенной мощности в web-интерфейсе Zabbix и пример выборки накопленных показаний из БД.


