Имеется 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.
Выборка из БД.
Выборка из БД.

Комментарии (20)


  1. happy-cat
    10.11.2021 01:58
    +1

    А как вы физически подключаетесь к счетчикам?

    Там же наверное есть некий протокол связи с диспетчерской и какая то авторизация?


    1. Kreastr
      10.11.2021 10:52
      +2

      Судя по мануалу https://www.incotexcom.ru/files/em/docs/merkuriy-236-avlg-411152-034-re-izm-2-2021-04-07.pdf там используется CAN с физической связью по RS485.

      В старых протоколах FieldBUS к которым относится и CAN не подразумевался свободный доступ посторонних лиц к физическому каналу связи и все данные передаются в открытом виде и обычно без авторизации пользователя.


      1. artirm Автор
        10.11.2021 11:22

        Счетчик обеспечивает разграничение уровней доступа на программном уровне с помощью системы паролей. (п 3.2.5 приведенного вами руководства)

        Более подробно об уровнях доступа в п. 2.2.2: https://www.incotexcom.ru/files/em/docs/merkuriy-sistema-komand-ver-1-2021-11-11.pdf

        В используемой утилите mercury236 используется первый уровень доступа с паролем по умолчанию.


        1. Kreastr
          23.11.2021 21:58

          Счетчик обеспечивает разграничение уровней доступа на программном уровне с помощью системы паролей. (п 3.2.5 приведенного вами руководства)

          Пароль сам по себе никого не ограничивает. Если злоумышленник может подключиться к каналу передачи данных и слушать все сообщения достаточно долго, то рано или поздно персонал, обслуживающий счётчик, введёт этот пароль и он будет в открытом виде передан по каналу и злоумышленником записан. Это уж не говоря о том, что самое ценное в этих данных это показатели потребления из которых можно легко установить паттерны поведения жителей помещения и использовать их в своих целях. Ну и конечно можно "врезаться" в физический канал и подделывать данные о потреблении параллельно потребляя разницу через незаконную точку потребления. Если жертва не эксперт и не имеет средств для независимого мониторинга показаний счётчика, то обнаружить это будет просто некому.


          1. artirm Автор
            25.11.2021 10:29

            Существует масса задач, для решения которых имеющихся возможностей достаточно, а существующие недостатки технологии не являются такими уж принципиальными.

            Возможно есть применения, где действительно важно защитить "паттерны поведения жителей помещения". Но более реалистичным сценарием мне кажется изменение самим пользователем, например, тарифного расписания, времени счетчика, коэффициентов трансформации и т.д. Как мне видится, именно по этой причине производитель счетчика предусмотрел два уровня доступа - пользователь и администратор. Правда я думаю, что подбор пароля от второго уровня доступа вполне посильная задача) Тем не менее лучше иметь такое разграничение прав, чем никакого. Кроме того, в случае "разбора полетов" всегда можно заглянуть в журнал счетчика.


            1. Kreastr
              26.11.2021 10:54

              Существует масса задач, для решения которых имеющихся возможностей достаточно, а существующие недостатки технологии не являются такими уж принципиальными.

              Вполне вероятно.

              Возможно есть применения, где действительно важно защитить "паттерны поведения жителей помещения".

              Если серьёзно относится к исполнению законов о защите персональных данных, то это приблизительно 100% случаев, в которых кто-либо устанавливает счётчики частным потребителям.

              Но более реалистичным сценарием мне кажется изменение самим пользователем, например, тарифного расписания, времени счетчика, коэффициентов трансформации и т.д.

              Разве просто подключиться к сети в обход счётчика не более простое и доступное обывателю решение?

              Как мне видится, именно по этой причине производитель счетчика предусмотрел два уровня доступа - пользователь и администратор. Правда я думаю, что подбор пароля от второго уровня доступа вполне посильная задача) Тем не менее лучше иметь такое разграничение прав, чем никакого.

              Обычно такие пароли это защита "от дурака" и больше никакой ценности не имеют. Достаточно квалифицированный и мотивированный пользователь найдёт способ подобрать или подслушать пароль. Но все это к моему исходному комментарию не относится. Он был не про права доступа в самом устройстве, а про то, что используемая полевая шина не предусматривает никакой защиты данных ни с точки зрения приватности, ни с точки зрения целостности.

              Кроме того, в случае "разбора полетов" всегда можно заглянуть в журнал счетчика.

              Это, кстати, хорошая идея, если журналы пишутся в неперезаписываемую память и по её переполнению полностью блокируют работу устройства. Правда, есть риск того, что 3-я сторона будет использовать эту фичу, чтобы перманентно отключать устройства, вызывая ошибки искусственно. Плюс нет способа доказать, что изменения внесены конечным пользователем, а не посторонним лицом на линии или злоумышленником в компании-операторе электросетей. Опять же - шина открыта. Подключайся и рули кто хочет.


              1. artirm Автор
                26.11.2021 17:57

                Если серьёзно относится к исполнению законов о защите персональных данных, то это приблизительно 100% случаев, в которых кто-либо устанавливает счётчики частным потребителям.

                Не являюсь экспертом в этой области, но сдается мне, что данные приборов учета сами по себе не являются персональными данными.

                Разве просто подключиться к сети в обход счётчика не более простое и доступное обывателю решение?

                Нет. Могут быть проблемы как при организации такого подключения, так и в оперативном восстановлении схемы.

                Он был не про права доступа в самом устройстве, а про то, что используемая полевая шина не предусматривает никакой защиты данных ни с точки зрения приватности, ни с точки зрения целостности.

                Данные передаются в открытом виде по линии RS485, целостность обеспечивается контрольной суммой. Достаточно ли защиты от несанкционированного доступа, реализованной производителем счетчика - зависит от решаемой задачи.


                1. Kreastr
                  26.11.2021 19:00

                  Не являюсь экспертом в этой области, но сдается мне, что данные приборов учета сами по себе не являются персональными данными.

                  Ну вот в Финляндии во всяком случае местные сетевые операторы к ним так относятся. И при передаче этой информации требуют следить, чтобы она не попала третьим лицам.

                  Но даже безотносительно "персональности" этих данных. Вы же не оставляете в открытом доступе календарь того, когда Вы находитесь или не находитесь дома? Вы же понимаете, какая это кладезь информации для потенциальных воров-домушников?

                  Нет. Могут быть проблемы как при организации такого подключения, так и в оперативном восстановлении схемы.

                  Ну тут Вам виднее я думаю. Это в целом, конечно, делает ситуацию с возможным брутфорсом или сниффингом пароля администратора только хуже.

                  Данные передаются в открытом виде по линии RS485, целостность обеспечивается контрольной суммой.

                  Целостность данных контрольная сумма обеспечивает только в части защиты от помех. В определение целостности данных входит ещё и защита от умышленных изменений третьими лицами. И тут никакие контрольные суммы не помогут, потому что алгоритм расчёта контрольной суммы вполне даже публичный.


      1. happy-cat
        10.11.2021 11:37

        В любом случае подключение будет незаконным с вытекающими последствиями :(
        а так да, идея неплоха и принцип простой.


  1. shushu
    10.11.2021 02:50

    Я понимаю что на вкус и цвет...

    Но в Zabbix удобство так себе... (если заббикс не используется, я бы не стал его внедрять)

    Связка grafan + influxdb намного вкуснее, на мой взгляд.

    Ну и хранить timeseries в mysql несколько затратно по обьёмам и скорости.


    1. unsignedchar
      10.11.2021 08:25


      Я понимаю что на вкус и цвет...

      Скорее если в руках молоток - всё вокруг похоже на гвозди ;)

      затратно по обьёмам и скорости

      Если измерения не каждые 5 сек - думаю, можно пренебречь.


      1. Kreastr
        10.11.2021 10:54

        Нашей исследовательской группе не так давно предоставляли данные со счётчиков электроэнергии конечных пользователей. Так оказывается, что и серьёзные электросетевые компании хранят бд потребления пользователей в SQL.


        1. unsignedchar
          10.11.2021 11:55

          и серьёзные электросетевые компании хранят бд потребления пользователей в SQL.

          А в чем ещё хранить?


          1. Kreastr
            23.11.2021 22:01

            InfluxDB? Собственно выше про него и написано. Других хороших решений для хранения временных рядов я лично не знаю.


  1. 0xC0CAC01A
    10.11.2021 04:29

    Вопрос в тему. У водосчётчиков есть проводочек, который... просто висит. Есть способ несложно и недорого сделать так, чтобы данные из этого шнурочка автоматически передавались по API mos.ru (или куда там положено передавать)?


    1. Z2K
      10.11.2021 05:06

      способ несложно и недорого сделать

      Тогда Вам сюда -> t.me@waterius_forum Чат для пользователей и разработчиков устройства Ватериус GitHub: https://github.com/dontsovcmc/waterius Народная инструкция по сборке: https://bit.ly/waterius-manual


      1. 0xC0CAC01A
        11.11.2021 02:10
        +1

        На передачу показаний счётчиков тратится ну максимум 10 минут в месяц. А тут же трудозатраты за всю жизнь не отобьются.



  1. AndreyUA
    10.11.2021 11:22
    +1

    Мне как-то пришлось написать windows службу, которая собирает данные со счетчиков меркурий и Satec в MSSQL. Настройки хранятся в базе.

    https://github.com/AndreyVys/EnergyCollectorService/blob/master/EnergyCollectorService/EnergyCollectorService.vb


  1. Basyuk93
    16.11.2021 22:06

    Могу порекомендовать посмотреть в сторону библиотеки protobix в python. Можно сразу в zabbix отправлять данные.