Создание Загружаемых Модулей Zabbix На Примере Добавления Протокола Modbus

Еще в версии Zabbix 2.2 были добавлены загружаемые модули, которые позволили расширить возможности системы на новом уровне.

«Зачем это нужноЭ» спросите вы, ведь из Zabbix всегда можно было запускать внешние скрипты и программы.

Конечно, в первую очередь это скорость — модули, как и сам Zabbix, написаны на C и при правильном подходе работают максимально быстро, в отличие от внешних программ, которые нужно запускать при каждом опросе.

Многих людей может пугать необходимость писать код, но сегодня я хочу показать вам, что это не так уж и сложно.

Для примера напишем модуль, который позволит Zabbix собирать информацию с устройств, работающих по широко распространённому в мире протоколу промышленной автоматизации — Modbus и использовать его для снятия показаний с датчиков температуры, а также получать параметры электроэнергии со счётчика Меркурий 230. .

В конце мы разместим наш модуль на портале.

Share.zabbix.com , где пользователи могут поделиться своим опытом работы с Zabbix.

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Несколько слов о Modbus Modbus – очень распространенный протокол, используемый в сетях промышленной автоматизации (заводы, цеха, другие промышленные объекты, различные инженерные системы – Modbus можно встретить повсюду).

Протокол был разработан еще в 1979 году компанией Modicon, и в течение следующих десятилетий благодаря своим преимуществам Modbus был реализован на огромном количестве различных устройств: Простота Modbus очень прост. Это позволяет запустить и реализовать его на самом простом и дешевом оборудовании.

Это также не мешает разработчикам использовать его в своих решениях.

Поддержка Ethernet Modbus подготовился к широкому проникновению сетей Ethernet, в том числе на промышленных объектах, и теперь работает не только по последовательным линиям RS-232, RS-485 (Modbus RTU/ASCII), но и по протоколу TCP/IP (Modbus TCP).

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

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

В первых двух данные представлены в виде одиночных битов, в последних двух — в виде 16-битных слов:

Стол Тип данных Доступ
Дискретный вход 1 бит только чтение
Катушки 1 бит Прочитайте и напишите
Входные регистры 16 бит только чтение
Регистры хранения 16 бит Прочитайте и напишите
Первые две таблицы можно использовать для работы с простыми дискретными величинами: «открыто-закрыто», «неисправность-нет неисправности» и т.д. Регистры ввода и хранения можно использовать для всего остального.

Более того, проблему, когда данные не умещаются в 16 бит, можно легко решить, используя два соседних регистра.

Таким образом, вы можете работать с 32-битными числами с плавающей запятой или длинными числами.

Доступ к элементам данных в Modbus возможен посредством адресации от 0 до 65535 во всех таблицах.

Доступ к данным не может перекрываться, и каждая таблица ведет к отдельному блоку памяти:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Аналогично, для доступа к одним и тем же данным можно использовать несколько таблиц:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

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

Если устройства Modbus находятся на последовательной линии (RS-485), то каждое устройство в Modbus имеет свой уникальный адрес (slave id, от 1 до 247), опрашивающее устройство всегда одно и то же и называется ведущим.

В случае устройства Modbus TCP достаточно IP-адреса.

Где мы здесь разместим Zabbix с нашим будущим модулем? Мы можем разместить его как ведущее устройство Modbus, подключив к сети RS-485 с контроллерами через преобразователь, или напрямую работать с устройствами, поддерживающими Modbus TCP:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus



Настройка среды

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

Овен , устройства ввода/вывода которого позволят контролировать температуру, различные дискретные датчики и параметры электропитания.

В качестве бонуса мы будем снимать показания с обычного трехфазного счетчика электроэнергии Меркурий 230Р с помощью преобразователя ДУ-1М МАКС-Логика, умеющего конвертировать встроенный протокол Меркурий в Modbus. Все эти устройства подключены к шине RS-485, к которой Zabbix будет иметь доступ как к ведущему через преобразователь RS232/RS485. Настройка модулей Овен для работы через Modbus описано в документации устройства.

В общем, вот что вам нужно сделать: Через конфигуратор Овен, подключаясь ко всем модулям поочередно через преобразователь RS232/RS485:

  • Изменить адреса подчиненный чтобы они были уникальными
  • Установите протокол обмена Модбус РТУ
  • Для МК110.224.2А: выберите тип подключаемых датчиков температуры.

Для ДУ-1М МАКС-Логика (Меркурий230) все немного сложнее: Сначала внимательно следуем инструкции на ДУ-1М по подключению к счетчику Меркурий 230, затем вместо уютного графического конфигуратора как в Овне воспользуемся консольной утилитой модопрол , отправляя команды в регистры конфигурации для настройки интерфейса счетчика (уф!).

Вот что у вас получится:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

А вот как это выглядит в реальной жизни:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Собрав стенд, проверим его работоспособность с помощью модопрол , например, подключив датчик температуры к МВ110-2А, опрашиваем его через регистр 10, как указано в документации к устройству:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Или возьмем энергопотребление счетчика Меркурий на тарифе Т1:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Как мы видим, связь есть и данные собираются.

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

  
  
  
  
  
  
  
  
  
  
   

modbus_read_registers[ <connection>, <slave_id>, <reg_to_read>, <modbus_function>, [<datatype>],[<endiannes>],[<first_reg>] ]

Внутри этого ключа мы передадим четыре обязательных и три дополнительных параметра:
  • связь — IP-адрес или последовательный порт с параметрами подключения
  • подчиненный_ид — Идентификатор устройства Modbus
  • reg_to_read - заветный реестр с данными
  • modbus_function - одна из функций чтения таблиц Modbus, 1 - для чтения КАТУШКИ
  • 2 - для ДИСКРЕТНЫЙ ВХОД , 3 - для РЕГИСТРЫ ХРАНЕНИЯ и 4 для ВХОДНЫЕ РЕГИСТРЫ
  • тип данных — тип данных, возвращаемых из реестра.

    бит, 16-битное целое, 32-битное целое или 32-битное с плавающей запятой.

  • порядок байтов , first_reg — нужны для правильной установки порядка бит для 32-битных значений, а также для указания того, какая адресация используется — модель данных Modbus (элементы таблицы, где первый элемент имеет адрес 1, а последний n) или адресация PDU (адресация от от 0 до 65535).

Итак, придумали, отлично, теперь перейдем непосредственно к модулю.

По сути, нам нужно написать функцию сбора данных из регистров Modbus и добавить к ней специальный Zabbix-интерфейс из следующих функций: две обязательные функции:

int zbx_module_api_version(void); int zbx_module_init(void);

А также три дополнительных:

ZBX_METRIC *zbx_module_item_list(void); void zbx_module_item_timeout(int timeout); int zbx_module_uninit(void);

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

И тогда вопрос, как написать саму функцию сбора? Кстати, назовем это так:

int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result)

И здесь работа сведена к минимуму, ведь чтобы не облажаться с реализацией протокола Modbus и не изобретать велосипед, возьмем библиотеку C, которая все это уже неплохо делает: libmodbus .

Используя интерфейс libmodbus, все, что нам нужно сделать, это Проверка входящие данные от Zabbix, затем запустите функции опроса из libmodbus , а потом конвертировать полученные значения в типы данных Zabbix и возвращаться их.

так или возвращаться ошибка.

Остальные детали, которые я пропустил, можно найти здесь .

И я еще раз подчеркну пару ключевых моментов: 1) Если функция выполняется успешно, результат помещается в *результат через макросы:

  • SET_UI64_RESULT — если результат целое число
  • SET_DBL_RESULT — если результатом является число с плавающей запятой
  • SET_STR_RESULT — если результат — Char
  • SET_TEXT_RESULT — если результат текстовый
  • SET_LOG_RESULT — если результат лог
Например:

SET_DBL_RESULT(result, modbus_get_float(temp_arr));

И сама функция должна вернуть СИСИНФО_RET_ОК.

2) Если что-то пойдет не так, вам нужно это вернуть.

SYSINFO_RET_FAIL , И в *результат поместите сообщение об ошибке, которое мы можем увидеть в веб-интерфейсе Zabbix:

SET_MSG_RESULT(result, strdup("Check datatype provided."))



Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

3) Очень важно не забыть подтвердить все входящие входящие параметры.

В противном случае сбой модуля приведет к сбою самого Zabbix сервера или агента.

4) Помните, что Zabbix запускает множество процессов опроса параллельно.

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

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

5) Так как используется внешняя библиотека libmodbus, то ее необходимо установить в систему, где будет использоваться модуль Zabbix, для этого:

wget http://libmodbus.org/releases/libmodbus-3.1.2.tar.gz tar zxvpf libmodbus-3.1.2.tar.gz cd libmodbus-3.1.2 .

/configure make make install ldconfig

В итоге у нас получилось что-то вроде этого код в модуле: Компилируем его и добавляем полученный файл .

so на Zabbix Server или Zabbix Agent. Просто важно помнить, что модуль зависит от некоторых заголовков самого Zabbix. Поэтому, если вы хотите собрать все отдельно из Zabbix, то скопируйте к себе как минимум zbxtypes.h, Module.h, sysinc.h из исходников Zabbix. Ну вот, готово.

Стендовые испытания Например, скомпилированный файл libzbxmodbus.so Давайте загрузим его на Zabbix Server; для этого добавьте в файл конфигурации Zabbix следующее:

LoadModulePath = /usr/local/lib LoadModule = libzbxmodbus.so

Давайте добавим пользователя Заббикс в группу дозвон для доступа к последовательному порту:

usermod -a -G dialout zabbix

.

и перезапустите Zabbix:

/etc/init.d/zabbix-server restart

Если все успешно перезапустилось, то заходим в Zabbix и создаем образец для наших устройств Modbus.

Создать шаблон

Начать давайте создадим элементы данных для МВ110-224.2А для считывания показаний датчика температуры:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Где ключ( ключ ):

modbus_read_registers[{$MODBUS_PORT},{$MODBUS_SLAVE},10,3,f,1,0]

  • {$MODBUS_PORT} Макрос , который будет перезаписан параметрами подключения к нашему устройству.

    Например, на уровне хоста мы определим наш {$MODBUS_PORT} как /dev/ttyUSB0 9600 Нет 1

  • {$MODBUS_SLAVE} — еще один пользовательский макрос, который означает «slave_id», и мы перепишем его как 32
  • 10 — регистр, содержащий значение температуры
  • 3 - Функция Modbus, используемая для чтения, в данном случае 0x03 ЧТЕНИЕ РЕГИСТРОВ ХРАНЕНИЯ
  • ж — тип данных, с плавающей запятой
  • 1 - поскольку контроллеры Aries используют Big endian для кодирования значений, не помещающихся в один регистр
  • 0 — используется адресация PDU
Подробнее о том, как выбрать параметры здесь .

Кроме того, необходимо указать: Тип ( тип ) Простая проверка — если модуль загружен на Zabbix Server и Zabbix Proxy, Забфикс-агент — если модуль загружен в Zabbix Agent Тип данных ( Тип информации ): в нашем случае это Числовой (с плавающей запятой) .



Создание хоста

Мы создаем сетевой узел , определяем макросы по договоренности:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

И прикрепите только что созданный шаблон:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus



Данные

Перейдем в раздел «Последние данные» и начнем наблюдать за данными, которые нам удалось собрать с датчика:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

И создав шаблоны для остальных регистров устройства, получаем такую картину:

Создание загружаемых модулей Zabbix на примере добавления протокола Modbus

Что ж, тогда мы можем создать триггеры , графика , экраны в шаблонах по желанию.

Заключение С помощью загружаемых модулей разработчики Zabbix предоставили нам интерфейс для создания по-настоящему быстрых и хорошо интегрированных расширений с Zabbix. Да, возможности на данный момент ограничены созданием новых типов элементов данных и, например, добавить новую триггерную функцию будет невозможно ( ZBXNEXT-2650 ), но мы подождем и посмотрим.

Чтобы модули не разбрасывались по всему интернету, был сделан и второй важный шаг в сторону организации индивидуальных решений — Share.zabbix.com — создан единый репозиторий для обмена шаблонами, модулями и другими расширениями для Zabbix. Вы ищете шаблон для сложной аппаратной части? Или вы написали шаблон для сложной железки и готовы поделиться им с другими? Мы искали такое решение мониторить PostgreSQL ? Или Докер ? Приходите и присоединяйтесь! Ну а теперь и наш модуль там .

Теги: #Modbus #zabbix #ОВЕН #мониторинг #открытый исходный код #scada

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.