У нас в организации развёрнут сервер Zabbix для мониторинга работоспособности серверов и АРМов. Из-за особенностей техпроцесса оборудование «размазано» по нескольким помещениям и разнесено по территории предприятия. Естественно, вместе с основными параметрами компьютеров (работает/не работает) хочется контролировать и микроклимат в серверных. При этом, как обычно, возможности весьма ограничены, и «выбить» значительные средства на сложные системы мониторинга температуры (к ним я отношу и платы управления с термодатчиками для стоечных ИБП APC) — это отдельный квест.
В основной серверной всё просто — установлена одна такая плата (закуплена давным-давно предшественником вместе с основным оборудованием), воткнут APC-шный термодатчик, заведён агент в Заббиксе, всё работает по SNMP. Скучно :) На мониторинг удалённой аппаратной оборудования нет, средств тоже — см. выше. Поэтому было решено проявить смекалку, сэкономить бюджет и заодно прокачать новый навык путём конструирования простого и дешёвого «наколенного» решения, вписывающегося, тем не менее, в существующую инфраструктуру мониторинга Zabbix.
Необходимые компоненты:
Общая стоимость компонентов — $10 с доставкой.
Сборка устройства не составляет труда. Сетевой модуль надевается на основную плату «бутербродом», термодатчик припаивается к его пинам. Подключение датчика: красный +5 В, чёрный — земля, жёлтый — данные; между +5V и Data припаиваем подтягивающий резистор 4,7 кОм.
Пин для данных выбирается с учётом пинов, используемых сетевым модулем (D10 – SS; D11 – MOSI; D12 – MISO; D13 – SCK; D2 – IRQ).
Грабли: в прототипе устройства столкнулся с конфликтом — данные о температуре выдавались случайным образом, «через два на третий». Причиной оказалось то, что я прицепил термодатчик на пин 2, который, как потом нашёл на просторах интернета, используется сетевым модулем для генерации прерывания при поступлении пакета. Переставил на 4-й — заработало как часы.
После сборки аппаратной части переходим к программной.
Устройство будет работать в сети и притворяться заббикс-агентом, для этого ему нужен MAC и IP-адрес. Решаем, как удобнее — жёстко зашить при программировании, генерировать MAC из адреса температурного датчика и получать IP по DHCP, и т.д. Я пошёл по простейшему пути и захардкодил оба параметра.
Протокол обмена с заббикс-сервером описан в документации. Наше устройство будет откликаться на две команды — agent.ping и env.temp (здесь оставлен простор для дальнейшего творчества, можно привязать любой из модулей расширения, доступных для ардуино — хоть датчик влажности, хоть освещённости — да что душе угодно). На все остальные команды оно будетругаться отвечать стандартным ответом, понятным заббикс-серверу.
Для тех, кто начинает с нуля (как я) — программирование Arduino выполняется с помощью Arduino IDE, установка и настройка которой элементарны. Для работы компонентов необходимы библиотеки UIPEthernet и OneWire, которые устанавливаются и подключаются к проекту через меню Скетч — Подключить библиотеку — Управлять библиотеками…
Если у вас будут другие компоненты (например, сетевой модуль не на enc28j60, а на другом чипе) — понадобятся и другие библиотеки!
Код работы с сетевым модулем и с датчиком температуры — типовой, из интернета, с некоторыми допущениями и упрощениями.
После заливки кода в контроллер и подключения ethernet-кабеля проверяем из консоли:
Грабли: выложенная на zabbix.com скомпилированная версия zabbix_get для Windows устарела и использует другой протокол (с заголовком ZBXD\x01 в запросе сервера). Линуксовая версия актуальна и протокол соответствует приведенному коду.
Всё работает, как и задумано. В админке заббикса создаём новый хост с выбранным IP, в нём — два ключа, Numeric (unsigned) agent.ping и Numeric (float) env.temp, наслаждаемся работой. Графики, триггеры — всё как обычно.
Питание устройства — через родной USB. Корпус — по желанию: подходящая пластиковая коробочка, термоусадка, синяя изолента.
Разрешение датчика — примерно 0.06 (точнее, 1/16) °С, точность — при погружении в таящий снег показал 0.19 °С (может, опустился бы и ниже, но снега было мало и он весь быстро растаял). Считаю, для устройства стоимостью 10 долларов и описанных целей — более чем достаточно.
UPD: В связи с незначительными изменениями протокола Zabbix, данный скетч не работает. Исправленная версия на Google Drive (поддерживает новый протокол, получает IP-адрес по DHCP).
В основной серверной всё просто — установлена одна такая плата (закуплена давным-давно предшественником вместе с основным оборудованием), воткнут APC-шный термодатчик, заведён агент в Заббиксе, всё работает по SNMP. Скучно :) На мониторинг удалённой аппаратной оборудования нет, средств тоже — см. выше. Поэтому было решено проявить смекалку, сэкономить бюджет и заодно прокачать новый навык путём конструирования простого и дешёвого «наколенного» решения, вписывающегося, тем не менее, в существующую инфраструктуру мониторинга Zabbix.
Необходимые компоненты:
- Основа системы — Arduino Nano V3
- Модуль локальной сети (ethernet-shield)
- И, собственно, цифровой датчик температуры на базе DS18B20
Общая стоимость компонентов — $10 с доставкой.
Сборка устройства не составляет труда. Сетевой модуль надевается на основную плату «бутербродом», термодатчик припаивается к его пинам. Подключение датчика: красный +5 В, чёрный — земля, жёлтый — данные; между +5V и Data припаиваем подтягивающий резистор 4,7 кОм.
Пин для данных выбирается с учётом пинов, используемых сетевым модулем (D10 – SS; D11 – MOSI; D12 – MISO; D13 – SCK; D2 – IRQ).
Грабли: в прототипе устройства столкнулся с конфликтом — данные о температуре выдавались случайным образом, «через два на третий». Причиной оказалось то, что я прицепил термодатчик на пин 2, который, как потом нашёл на просторах интернета, используется сетевым модулем для генерации прерывания при поступлении пакета. Переставил на 4-й — заработало как часы.
После сборки аппаратной части переходим к программной.
Устройство будет работать в сети и притворяться заббикс-агентом, для этого ему нужен MAC и IP-адрес. Решаем, как удобнее — жёстко зашить при программировании, генерировать MAC из адреса температурного датчика и получать IP по DHCP, и т.д. Я пошёл по простейшему пути и захардкодил оба параметра.
Протокол обмена с заббикс-сервером описан в документации. Наше устройство будет откликаться на две команды — agent.ping и env.temp (здесь оставлен простор для дальнейшего творчества, можно привязать любой из модулей расширения, доступных для ардуино — хоть датчик влажности, хоть освещённости — да что душе угодно). На все остальные команды оно будет
Для тех, кто начинает с нуля (как я) — программирование Arduino выполняется с помощью Arduino IDE, установка и настройка которой элементарны. Для работы компонентов необходимы библиотеки UIPEthernet и OneWire, которые устанавливаются и подключаются к проекту через меню Скетч — Подключить библиотеку — Управлять библиотеками…
Если у вас будут другие компоненты (например, сетевой модуль не на enc28j60, а на другом чипе) — понадобятся и другие библиотеки!
Код работы с сетевым модулем и с датчиком температуры — типовой, из интернета, с некоторыми допущениями и упрощениями.
После заливки кода в контроллер и подключения ethernet-кабеля проверяем из консоли:
$ zabbix_get -s 192.168.4.5 -k agent.ping 1 $ zabbix_get -s 192.168.4.5 -k env.temp 23.12 $ zabbix_get -s 192.168.4.5 -k bla-blah ZBX_NOTSUPPORTED
Грабли: выложенная на zabbix.com скомпилированная версия zabbix_get для Windows устарела и использует другой протокол (с заголовком ZBXD\x01 в запросе сервера). Линуксовая версия актуальна и протокол соответствует приведенному коду.
Всё работает, как и задумано. В админке заббикса создаём новый хост с выбранным IP, в нём — два ключа, Numeric (unsigned) agent.ping и Numeric (float) env.temp, наслаждаемся работой. Графики, триггеры — всё как обычно.
Питание устройства — через родной USB. Корпус — по желанию: подходящая пластиковая коробочка, термоусадка, синяя изолента.
Разрешение датчика — примерно 0.06 (точнее, 1/16) °С, точность — при погружении в таящий снег показал 0.19 °С (может, опустился бы и ниже, но снега было мало и он весь быстро растаял). Считаю, для устройства стоимостью 10 долларов и описанных целей — более чем достаточно.
Скетч
#include <OneWire.h> #include <UIPEthernet.h> byte mac[] = { 0xDE, 0x05, 0xB6, 0x27, 0x39, 0x19 }; // random MAC byte ip[] = { 192, 168, 4, 5 }; // IP address in local network String readString = String(20); byte addr[8]; OneWire ds(4); // DS18B20 at pin 4 EthernetServer server(10050); // Zabbix port void setup() { Ethernet.begin(mac, ip); server.begin(); ds.search(addr); } void loop() { byte data[2]; float celsius; readString = ""; if (EthernetClient client = server.available()) { while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n') // end of query from zabbix server { client.print("ZBXD\x01"); // response header if (readString == "agent.ping") { byte responseBytes [] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '1'}; client.write(responseBytes, 9); } else if (readString == "env.temp") { ds.reset(); ds.select(addr); ds.write(0x44); // start conversion with regular (non-parasite!) power delay(1000); ds.reset(); ds.select(addr); ds.write(0xBE); // read Scratchpad data[0] = ds.read(); data[1] = ds.read(); int16_t raw = (data[1] << 8) | data[0]; celsius = (float)raw / 16.0; byte responseBytes [] = {(byte) String(celsius).length(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; client.write(responseBytes, 8); client.print(celsius); } else { byte responseBytes [] = {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; client.write(responseBytes, 8); client.print("ZBX_NOTSUPPORTED"); } break; } else if (readString.length() < 20) { readString = readString + c; } } } delay(10); client.stop(); } }
UPD: В связи с незначительными изменениями протокола Zabbix, данный скетч не работает. Исправленная версия на Google Drive (поддерживает новый протокол, получает IP-адрес по DHCP).
