Мониторинг электросчетчиков за один вечер

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Имеется 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 и пример выборки накопленных показаний из БД.

Dashboard и карта сети в web интерфейсe.
Dashboard и карта сети в web интерфейсe.
Выборка из БД.
Выборка из БД.
Источник: https://habr.com/ru/post/588218/


Интересные статьи

Интересные статьи

07:00 Слышу звуки будильника. Вот и добрейшее утро повисло расходящимися тучами. 08:50Прохожу турникеты в офис, машу рукой девочкам с Reception, здороваюсь с ангелами из охраны.Захожу в наш открытый o...
Эта статья является конспектом материала Effective Aggregate Design Part I: Modeling a Single Aggregate.Объединение сущностей (entities) и объектов значений (value objects) в агрегат с тщ...
Сервис Sentry позволяет удаленно мониторить баги в фронтенд-приложениях, написанных на JavaScript. Попытка устранить проблемы в фронтенд-приложениях на JavaScript может оказаться н...
Среди советов по улучшению юзабилити интернет-магазина, которые можно встретить в инете, один из явных лидеров — совет «сообщайте посетителю стоимость доставки как можно раньше».
Эта публикация написана после неоднократных обращений как клиентов, так и (к горести моей) партнеров. Темы обращений были разные, но причиной в итоге оказывался один и тот же сценарий, реализу...