[Из песочницы] Пишем протоколы счетчиков Меркурий 230 и Меркурий 200 для OpenSCADA

Для кого
 — Для тех кто использует OpenSCADA, но не может реализовать больше чем решения «из коробки»
 — Для тех кто ищет СКАДу для себя, но так и не может определится
 — Для тех кто забросил этот проект, так и не разобравшись как он работает

Зачем
 — Данное решение позволяет считывать показания счетчиков меркурий 230 и меркурий 200 без каких либо лимитов
 — Это бесплатно

0a4e49280b46438e8d59e48697dec11f.jpg

Проекту openscada (oscada.org) уделяют не заслужено мало внимания, о нем написана всего одна статья на хабре. Большинство инженеров боятся трогать и трехметровой палкой этот продукт, черт его знает какой этот ваш линукс. Разрабатывает его уже не первый десяток лет фактически один человек, Роман Савоченко.

Не имея раньше опыта со СКАДА вообще (а с линуксом немного дружил) выбрал именно его для реализации мониторинга объектов на предприятии. Так как сравнить мне было не с чем, интерфейс и все связи данных с друг другом я воспринял как должное. Очень помог видеоурок «быстрый старт», лично я считаю таких уроков можно было сделать и побольше. Документацию тоже пришлось перечитывать не раз, но оно того стоило. Подключив первый модуль сбора данных Невод+ долго не мог понять почему он не работает. Ведь как совместимый с протоколом DCON он в списке проекта числился (точнее его аналог). Полез в исходник протокола и… оказалось что совсем он с ним не совместим, как и многие другие модули сбора из списка. Первое обращение на форум проблему мою исправило и еще несколько ошибок довольно оперативно. Рассказывать обо всех тонкостях системы я не буду, лучше прочтите вышеупомянутую статью на хабре или посмотрите «быстрый старт».

Спустя какое то время мне понадобилось снимать показания с электросчетчиков Меркурий 230. Поддержки этих счетчиков в openscada нет. Попробовал утилиту taskgroup от создателя всем известного konfiguratorа, опрашивать счетчики по CSD ей оказалось дохлым номером. Но все не так плохо как могло быть, openscada система предельно модульная и написать свой модуль можно хоть на С++, хоть на языке высокого уровня прямо в ней. Описание протокола обмена для меркурия 230 без проблем можно найти в сети, производитель «Инкотекс» конечно может предоставить вам описание по запросу, но мне не хотелось связываться с этой волокитой.

Итак, подключаем шину со счетчиками, для наглядности и лучшей ориентации в протоколе ставим konfigurator и сниффер последовательно порта, открываем документацию. Пытаемся прочитать данные со счетчика с адресом 75.

все скриншоты кликабельны

8ab975a8f92a436e8d99f1837f57c7cc.png

Видим как побежали наши данные.

4d3597a530634827a6765502f6c5a2b8.png

Протокол обмена для меркурий 230 очень похож на протокол modbus.

Запрос на открытие канала связи предназначен для разрешения доступа к данным с указанием уровня доступа. В счетчике реализован двухуровневый доступ к данным: первый (низший) — уровень потребителя, и второй (высший) — уровень хозяина

bae987d0de854a0c825dc3a4ef9bf9e9.png

Попытаемся с помощью конфигуратора опросить наш счетчик и видим что первый запрос это и есть пароль, а ответ счетчика это 4 байта. включающие в себя

c627f96de10a4c559df886c2ee38a4a9.png

Теперь попытаемся это реализовать на openscada. В С++ я не силен, поэтому решил реализовать на языке, встроенном в саму СКАДу, который там зовется JavaLikeCalc.Javascript. Сам код опроса реализуется в двух модулях UserProtocol и DevLib. Создадим устройство в библиотеке устройств и назовем m230. Добавим атрибуты netaddr (сетевой адрес), password (пароль), transport (последовательный порт) и answer (ответ на запрос пароля). И напишем запрос.

88b04a243aa044c5ac439044d2639b69.png

Теперь перейдем к протокольной части и создадим в UserProtocol наш пользовательский протокол и назовем его так же m230. Начнем с преобразования сетевого адреса. Код расчета контрольной суммы modbus CRC16 уже был написан давно, мне осталось его только вставить в свой код.

8c051446daf64502aec07d7c0539b27d.png

Создадим и транспорт, прописав в нем нужный порт, скорость и тайминги.

cb717776c18d490795eb860acf475974.png

Теперь создадим устройства в LogivLev, в нем создадим контроллер, а так же параметры (они же и есть счетчики). Выбираем наш шаблон, в конфигурации прописываем сетевой адрес, пароль и транспорт.

cc1d9596f51949779fc4c32525a94d48.png

Не лишним будет и включить архивацию в соответствующей вкладке.

1b86cce594ab4ea0b1028f01bce2e95c.png

Переходим ко вкладке Атрибуты и видим наши 4 байта ответа от счетчика. Пароль принят, отлично!!!

426d9fec888541828aa1b86a6813ccda.png

Что же попробуем считать показания электроэнергии. Добавляем в в атрибуты шаблона несколько записей еще несколько строк кода для каждого тарифа и для их суммы.

bdd044aa04ca4a0cbcd0c13746e47a48.png

Далее добавим в наш протокол еще строки. Не лишнем будет проверить ответ на тот ли запрос пришел и проверить длину пакета. Каждый 4 байта полезной информации ответа интерпретируется своей последовательностью байт, для чтения энергии она видна на скриншоте. В конце из 16ричной системы данные переводим в десятичную, к тому же это число надо разделить на 1000.

1f8540a00fc84242a755559046be95d3.png

Заходим опять в конфигурацию шаблона, ставим галку «Считывать энергию от сброса» и в атрибутах у нас уже видны данные о тарифах.

95edd7826de44760a9362a327c6d62b9.png

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

6f1ec63439584908bddce83fa4db7071.png

4fdac5d7ad14497fb69c932ec5554a9b.png

Немного изменений добавим и на стороне протокола.Проверяем ответ на байты из чего строим предположение о его длине и проверяем ее, добавляем свою последовательность байт, переводим в десятичную систему и делим на 100 для ответа о напряжении и мощности и на 1000 для ответа о токе.

883fdbd760ac47f58426948f9c5e05e2.png

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

c8a55a1971354542ba211341096248df.png

Добавим для наглядности еще несколько счетчиков. Но это не все, данные надо не просто считывать, но и представить их в удобном виде. Для этого в openscada существует Vision (рабочий пользовательский интерфейс) в котором данные можно представить в любом удобном для вас виде, хоть в виде мнемосхемы, в виде графиков, в виде документов итд. Возьмем стандартный документ из шаблона и отредактируем его чтобы получилось так.

9401fc018d3b49b790c6af9d54d2bb18.png

А в обработку документа добавим строку, чтобы можно было легко читать архивы данных по дням.

8c52f1a545cc41859968871a2cee186f.png

В итоге запускаем проект и открываем наш документ.

6b15a1e35fca4290b3ffa70c65f27588.png

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

f17d46d2bfc949b4a896db911715164f.png

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

Сетевой адрес тут и есть пароль счетчика. По умолчанию он равен последним 6 цифрам серийного номера. Попробуем написать шаблон.

Вот схема пакета запроса и ответа

345d3537037745c39680a9ff6ead9399.png

Серийный номер счетчика слишком длинный чтоб уместить его в 32-битное целое число, поэтому поделим его на две части.

Код запроса тарифа 0×27, пишем структуру запроса и выделяем какие байты за какой тариф у нас отвечают. И делим это значение на 100. И проверяем наш ответ на объем символов.

Чтобы считывать мгновенные значения используем код запроса 0×63. Также проверим наш ответ на количество байтов. Нюансы по каждому из этих значений тоже учитываем.

Но что делать если счетчик закодирован программой наладчик+? К счастью как кодирует наладчик+ всем уже давно известно, поэтому добавляем строку в начало нашего кода.

7cf9bb67daa748cc9c635d0ba1fc0945.png

Перейдем к протокольной стороне. Преобразовываем наш адрес в шестнадцатеричную систему. Расчет контрольной суммы и запрос как и в предыдущем протоколе.

264f4f043502434299886befebeb17d7.png

Добавим несколько счетчиков и в конфигурации шаблона пропишем наши настройки.

a5f9b2a0a8374654bfc13ff37e10c8d1.png

И во вкладке Атрибуты видим как счетчик отдает нужные нам значения.

faf6df8f05ee4771b7f5c797a270f8c5.png

Создадим документ чтобы просматривать эти значения в более удобном виде. Отредактируем наш шаблон документа. Запустим наш проект.

1404bbf5fd57479f9d2e7b1881a76713.png

Все оказалось совсем несложно. Данный протокол можно скачать на форуме oscada.org/ru/forum в разделе «Разработка OpenSCADA». И на данный момент, насколько мне известно это единственное бесплатное решение для меркуриев на неограниченное количество счетчиков.

P.S. Написал я это дело еще 3 года назад, только недавно решил этим поделится.
P.P. S. В статье скорей всего есть неточности, которыми Роман явно был бы недоволен.

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

  • 16 ноября 2016 в 16:45

    0

    Спасибо за полезную информацию! Счетчики массовые и так подключать и считывать данные с них правда легче

© Habrahabr.ru