Не бывает плохой погоды, бывает только плохая одежда (шведская пословица) Эта статья посвящена Zabbix-мониторингу устройств IoT простой метеостанции, подключенных через порт GPIO к микрокомпьютеру отечественной сборки Repka Pi 3 производства НПО Рэйнбовсофт (Rainbowsoft). Здесь будут представлены скрипты мониторинга, измеряющие температуру, давление, влажность, освещенность, а также контролирующие наличие воды (затопление). Метеостанция оборудована контроллером BME280, измерителем освещенности BH1750, а также сенсором наличия воды YL-38. Результаты измерений периодически отправляются в Zabbix с помощью агента zabbix-agent2 и шаблона, работающего в активном режиме. Помимо этого, в статье будет описан скрипт Python, который можно запускать периодически через crontab. Этот скрипт выводит результаты измерений на OLED-монитор SSD1306. На время проведения измерений зажигается светодиод, подключенный к GPIO. Мониторинг самого микрокомпьютера был описан ранее в статье Zabbix-мониторинг российского микрокомпьютера Repka Pi. Как и во многих микрокомпьютерах, в Repka Pi имеются контакты интерфейса общего назначения GPIO (General Purpose Input/Output). К контактам GPIO можно подключать различные устройства, например, погодную станцию, сенсоры наличия воды, измерители освещенности, OLED-мониторы, драйверы управления двигателями и серводвигателями, ультразвуковые измерители расстояния и так далее. Порт GPIO в Repka Pi 3 содержит 40 контактов. Из них 28 контактов GPIO, контакты UART, I2C, SPI, а также PWM (рис. 1.) Подключая внешние устройства к порту GPIO, учтите, что ни при каких условиях вы не должны подавать на выводы сигналы с напряжением, превышающим 3,6 В, иначе микроконтроллер может быть поврежден.  Также ток потребления контактов GPIO не должен превышать 40 мА (на один контакт). Рекомендуемое входное напряжение, подаваемое на входы GPIO, составляет 3,3 В, а рекомендуемый потребляемый ток — 20 мА. Еще важный момент: если вы подключаете периферию большой мощности (моторы, например), используйте для нее отдельный источник питания. При этом большой ток не должен проходить через землю микрокомпьютера. Электрическую спецификацию на GPIO можно уточнить в даташите на процессор Allwinner H5, который нетрудно найти в интернете по запросу «Allwinner H5 Datasheet». На сайте Repka Pi в разделе «Подключение периферии» указано, что всего предусмотрено пять вариантов прошивки с различной распиновкой (pinout): GPIO-26, UART-1 (по умолчанию) GPIO-15, UART-1, SPI-2, I2C-1  GPIO-11, UART-3, SPI-2, I2C-1  GPIO-13, UART-1, SPI-2, I2C-2 GPIO-14, UART-1, SPI-2, I2C-1, PWM-1 Обозначение контактов для этих вариантов я взял с сайта разработчика и привел на рис. 2. Как видите, здесь предусмотрены контакты питания 5 В и 3,3 В, которые можно использовать для питания периферийных модулей, подключенных к GPIO, а также контакты земли GND. Также есть контакты ввода/вывода IO, контакты интерфейсов UART, SPI, I2C, а также PWM. По умолчанию установлен первый вариант, в котором нет нужного для погодной станции интерфейса I2C. Давайте сконфигурируем GPIO, выбрав второй вариант прошивки. Для конфигурирования запустите из командного приглашения Repka OS утилиту repka-config. В консоли будет показано текущее значение максимальной частоты процессора (рис. 3). Нажмите клавишу Enter. На экране появится меню конфигурирования (рис. 4). С помощью клавиш перемещения курсора выберите здесь пункт 3 Frequency / Pinout Options, а затем нажмите клавишу Enter. Далее вам будет предложено выбрать максимальную частоту процессора (рис. 5). Для метеостанции не нужна высокая частота процессора, так что можете оставить значение по умолчанию или снизить частоту до 1 ГГц. Снова нажмите клавишу Enter. Появится меню выбора варианта прошивки (рис. 6). Здесь нам нужна строка 2 Вариант – GPIO-15, UART-1, SPI-2, I2C-1. Выберите ее и снова нажмите Enter. Далее подтвердите перезагрузку ОС (рис. 7). После перезагрузки будет установлен нужный вам вариант использования контактов GPIO. Если вы откажетесь от перезагрузки, то для завершения работы утилиты repka-config нужно будет закрыть консольное окно, а затем открыть его заново. Для тестирования линий GPIO подключим через резистор 300 Ом светодиод к физическим линиям 11 (сигнал) и 14 (земля), как это показано на рис. 8. При подключении соблюдайте полярность — плюс светодиода нужно подключить к физическому контакту 11, а минус – к земле, к контакту 14. В качестве земли можно также использовать контакты 6, 9, 14, 20, 25, 30, 34  и 39 (в соответствии с рис. 2). Для работы с линиями GPIO можно использовать несколько интерфейсов. Один из вариантов — интерфейс sysfs.  При использовании этого интерфейса нужно зарезервировать нужную вам линию GPIO и указать режим ее работы — ввод или вывод с помощью команды echo. Чтобы прочитать состояние линии, воспользуйтесь командой cat. Изменить состояние линии можно с помощью команды echo. Напишем простейший скрипт на Bash, который зажигает светодиод, а потом через некоторое время гасит его (листинг 1). Листинг 1. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/led.sh Вначале скрипт создает новую линию GPIO с номером 8, записывая этот номер в системный файл sys/class/gpio/export. На рис. 2 этой линии соответствует обозначение PA8. Далее скрипт ожидает выполнения операции в течение 0.1 секунды. Аналогичная задержка добавлена и после других команд. Когда порт GPIO добавлен, скрипт переключает его в режим вывода, записывая строку «out» в системный файл /sys/class/gpio/gpio8/direction. После этого скрипт переводит линию 8 порта GPIO в состояние 1, записывая значение 1 в системный файл /sys/class/gpio/gpio8/value. В результате на соответствующем физическом контакте с номером 11 появляется напряжение +3.3 В, и светодиод зажигается. Далее скрипт гасит светодиод, записывая в вышеупомянутый системный файл значение 0. И, наконец, перед завершением своей работы скрипт освобождает линию, записывая значение 8 в системный файл /sys/class/gpio/unexport. Чтобы запустить скрипт, введите в консоли команду: Светодиод загорится, а через пять секунд погаснет. Интерфейс доступа sysfs вполне пригоден и работает, однако отмечен как устаревший. Вместо него рекомендуется использовать интерфейс chardev, особенно для асинхронной работы. Для обмена данными при этом нужно использовать специальные утилиты. Сначала нужно вызвать утилиту gpiodetect, которая покажет на консоли список доступных чипов и количество подключенных к ним линий gpio: Вызвав утилиту gpioinfo, можно получить детальную информацию по каждой линии. Для того чтобы установить значение 1 на линии PA8, используйте следующую команду: Вернуть нулевое состояние линии можно так: Подробнее об этом можно почитать в упомянутой выше статье. Также есть интерфейс, основанный на работе со специальным устройством /dev/mem. Однако проще работать с этим интерфейсом не напрямую, а с использованием библиотек. Хотя Repka Pi 3 создана для замены Raspberry Pi 3, полной совместимости нет, так как применяется другой процессор. Как результат, в скриптах Python вместо RPi.GPIO нужно подключать библиотеку RepkaPi.GPIO, доступную на GitHub. Установка библиотеки выполняется следующим образом: В листинге 2 вы найдете скрипт, который мигает светодиодом, подключенном к физическому выводу с номером 11. Этот скрипт сделан на базе примеров, которые есть в упомянутом выше репозитории. Листинг 2. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/blink_led.py Программа импортирует библиотеки RepkaPi.GPIO и time. Первая из них нужна для работы с GPIO Repka Pi, а вторая — для задержки выполнения скрипта на заданное время. Перед началом работы устанавливается тип платы микрокомпьютера: В данном случае это Repka Pi 3. Вслед за этим программа устанавливает режим GPIO как SUNXI, после чего задает номер контакта с подключенным светодиодом: В режиме SUNXI используется обозначение контактов GPIO в соответствии с рис. 2, поэтому физический контакт 11 указан как PA8. Этот режим используется на платформах, основанных на системе с чипом (SoC) Allwinner SoC. В программе предусмотрено использование двух других режимов — GPIO.BOARD и GPIO.BCM: В режиме GPIO.BOARD нужно указать физический номер контакта на плате микрокомпьютера. В нашем случае это контакт 11 (рис. 8). Если нужно адаптировать программу Python, созданную для Raspberry Pi, вам пригодится режим GPIO.BCM. В этом режиме линии GPIO нумеруются в соответствии с схемой Broadcom SOC channel (BCM). При этом нужно указывать такие же номера линий, как и для Raspberry Pi . Описание GPIO Raspberry Pi можно найти здесь. Конечно, вы можете использовать только один из перечисленных выше режимов. На следующем этапе программа переключает линию в режим вывода: После этого с помощью вызова GPIO.output в цикле выполняется попеременный вывод значений 1 и 0 с задержкой в 1 секунду: Обратите внимание, что в программе также предусмотрена задержка на 0,1 секунду после операции вывода. Она нужна для ожидания завершения операции. Наша погодная станция оснащена сенсором наличия воды на базе контроллера YL-38 (рис. 9). Этот контроллер, созданный на базе компаратора LM393, поставляется вместе с сенсором MH-RD  (рис. 10). Сенсор нужно разместить в контролируемой зоне, где возможны затопления. На плате контроллера YL-38 есть регулятор для калибровки, два контакта для подключения датчика, а также четыре контакта для подключения питания и микрокомпьютера. Назначение контактов: Vcc – питание датчика от 3.3 до 5 В; GND – земля; D0 – цифровое значение наличия влажности (1 или 0) A0 – переключение режима (аналоговый или цифровой); Подключите вывод Vcc контроллера к контакту с физическим номером 17, где выведено напряжение 3,3 В. Также для питания YL-38 можно использовать и контакт с физическим номером 1. Вывод GND нужно подключить к земле микрокомпьютера, например, к физическому контакту 9 или другому контакту земли, согласно рис. 2. Вывод D0 подключите к контакту 13 (PA9), а вывод A0 оставьте свободным. И, наконец, подключите сенсор наличия воды MH-RD к двум контактам на плате YL-38 (рис. 11). Чтобы не повредить микрокомпьютер и контроллер, дважды проверьте все соединения перед включением питания. Далее запустите программу, представленную в листинге 3. Листинг 3. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/yl38.py Эта программа использует режим GPIO.SUNXI и контакт PA9. Контакт переводится в режим чтения, а затем программа читает полученные данные и выводит их на консоль. Если сенсор сухой, программа выводит значение единицы, а если влажный — нулевое значение. Если это необходимо, откалибруйте порог срабатывания при помощи регулятора. Если к микрокомпьютеру нужно подключить много устройств, удобен последовательный ассиметричный интерфейс I2C, разработанный в начале 80-х годов компанией Philips. На шине I2C может использоваться одно или несколько ведущих устройств и до 127 ведомых. При этом ведущие устройства управляют процессом передачи данных ведомых устройств. Для передачи данных по шине I2C используются линии SLC и SDA. Линия SLC служит для передачи сигналов синхронизации, а линия SDA —для передачи данных.  Для метеостанции в качестве ведущего устройства будет использован микрокомпьютер Repka Pi 3, а в качестве ведомых — измеритель освещенности BH1750, погодная станция BME280, а также дисплей OLED SSD1306. Для измерения освещенности в люксах установим контроллер BH1750 (рис. 12). Выводы GND и VCC контроллера нужно подключить к земле и выводам питания +3,3 В. Используйте для питания контакт Repka Pi 3 с физическим номером 17. Контакт ADD оставьте свободным. Он задает адрес люксметра на шине I2C. Если подключить этот контакт к земле, адрес будет 0x23, а если оставить свободным — 0x5C. Задавая разные адреса, вы можете подключить к шине I2C два измерителя освещенности. Что касается выводов SDA и SLC, то их нужно подключить к контактам 3 и 5 (рис. 2). Напомним, что мы установили второй вариант прошивки (распиновки), где эти контакты используются для I2C. Остановите ОС и выключите питание микрокомпьютера. Затем подключите BH1750 и проверьте, что его видно на шине I2C. Для этого обновите ОС и установите пакет i2c-tools: Затем посмотрите список шин I2C: Наше устройство подключено к шине с номером 1, в чем можно убедиться, выполнив следующую команду: Как видите, здесь присутствует устройство с адресом 0x23, а это как раз наш измеритель освещенности BH1750. К шине I2C также подключена погодная станция BME280 с адресом 0x76, а еще дисплей OLED SSD1306 с адресом 0x3c. В листинге 4 приведена несложная программа, которая получает данные от измерителя освещенности, преобразует их в значение, выраженное в люксах, а затем выводит на консоль. Листинг 4. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/bh1750.py Программа импортирует библиотеку smbus2 для работы с шиной I2C, а также библиотеку time для реализации функции задержки. Первым делом программа создает объект bus для обращения к шине I2C с номером 1. Далее команда выводит на шину по адресу 0x23 команду 0x10 для измерения освещенности в непрерывном режиме с разрешением в 1 люкс.  После задержки на 0,5 секунды программа читает два байта данных с результатами измерений и преобразует их в люксы с округлением до целого числа. Далее значение освещенности выводится на консоль. Подробную информацию об измерителе освещенности BH1750 можно найти здесь. Займемся подключением погодных станций BME280 и BMP280 (рис. 13). Первая из них измеряет температуру, давление и влажность, вторая — только температуру и давление.  При подключении погодной станции к микрокомпьютеру Repka Pi 3 контакты VIN и GND нужно подключить к источнику питания 3,3 В и к земле соответственно. Используйте для питания контакт Repka Pi 3 с физическим номером 17. Выводы SDA и SLC нужно подключить к контактам 3 и 5 микрокомпьютера Repka Pi 3 (рис. 2). Во втором варианте прошивки эти контакты используются для I2C. Хотя погодная станция BME280 представляет собой сложное устройство, программа получения данных измерений достаточно проста (листинг 5) благодаря использованию библиотеки bme280. Листинг 5. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/bme380.py Помимо bme280, в программе подключаются библиотеки smbus2 и json. Первая из них нужна для работы с шиной I2C, а вторая — для вывода на консоль результатов измерений в формате JSON. Этот формат удобен для мониторинга при помощи Zabbix. После создания объекта bus для работы с портом 1 шины I2C программа загружает параметры калибровки для BME280. Вслед за этим программа считывает данные с погодной станции, используя загруженные параметры калибровки. И, наконец, параметры преобразуются в формат JSON и выводятся на консоль: Техническое описание BME280 можно найти тут. Итак, теперь нам осталось только подключить к Repka Pi 3 дисплей OLED SSD1306 и написать программу, которая будет показывать на нем результаты измерений погоды, а также выводить предупреждение о протечке воды. На рис. 14 показан собранный макет погодной станции со всеми упомянутыми ранее модулями. Чашка с водой нужна для проверки обнаружения протечки. Дисплей OLED SSD1306 показан на рис. 15. Как видите, здесь есть все те же контакты VCC, GND, SCL и SDA. Теперь вы уже знаете, куда их подключать. Для вывода данных на дисплей мы будем использовать библиотеку luma.oled. Чтобы ее установить, потребуется всего две команды: Для изучения вы также можете установить другие программы, использующие эту библиотеку: В листинге 6 вы найдете программу, которая получает все данные от погодной станции и отображает их на дисплее. На время работы программы зажигается светодиод, подключенный к GPIO. Листинг 6. https://github.com/AlexandreFrolov/zabbix-repka-pi-iot/blob/main/get_weather.py Мы рассмотрим только фрагменты кода, предназначенные для работы с дисплеем. Прежде всего подключаются необходимые библиотеки: Далее создается объект для работы с дисплеем, при этом указывается номер порта и адрес дисплея на шине I2C: После этого загружаются шрифты: Создается объект draw, который предоставляет методы для рисования на дисплее. При этом canvas обеспечивает контекстное управление, что позволяет автоматически освобождать ресурсы после окончания работы с дисплеем: После этого на экран дисплея выводятся четыре строки с данными о температуре, давлении, влажности и освещенности: Вслед за этим, в зависимости от данных определения протечки, пятой строкой выводится сообщение об отсутствии или обнаружении воды (рис. 16): И, наконец, после небольшой задержки экран дисплея выключается командой 0xAE: Даташит для дисплея OLED SSD1306 можно найти здесь. Также рекомендую полезную статью про работу с дисплеем.   Предполагаем, что вы уже настроили мониторинг Repka Pi по статье «Zabbix-мониторинг российского микрокомпьютера Repka Pi». В частности, вы уже установили агент Zabbix Agent2 в Repka OS, подключили шаблоны Linux by Zabbix agent active и zabbix-agent-on-repka-pi. Теперь нужно добавить шаблон zabbix-repka-pi-iot, а также скрипты мониторинга данных для нашей метеостанции. Загрузите файл шаблона zabbix-repka-pi-iot и подключите его к узлу Repka Pi с помощью web-интерфейса вашего сервера Zabbix: Далее создайте на узле Repka Pi каталог /etc/zabbix/scripts (если такого каталога еще нет) и сделайте его текущим: Загрузите скрипты для получения данных из репозитория Github: Разрешите выполнение загруженных скриптов: Скрипт yl38.py (листинг 3) для выполнения требует прав пользователя root, так как обращается к системным файлам, например, к файлу /sys/class/gpio/export. Чтобы этот скрипт мог запускаться агентом с правами пользователя zabbix, создадим скрипт yl38_starter.sh. Он будет запускать программу yl38.py через команду sudo (листинг 7). Листинг 7. https://raw.githubusercontent.com/AlexandreFrolov/zabbix-repka-pi-iot/main/yl38_starter.sh Для того чтобы у агента Zabbix была возможность запуска программы yl38.py без указания пароля пользователя zabbix, отредактируем файл /etc/sudoers c помощью команды visudo: С помощью запущенного этой командой редактора вам нужно добавить следующую строку и сохранить изменения: Очень важно указать здесь полный путь к программе /etc/zabbix/scripts/yl38.py, а не только ее имя. Иначе можно будет запустить с правами root любую программу с именем yl38.py, расположенную в любом каталоге. Теперь проверьте, что скрипты работают при их запуске от имени пользователя zabbix и выводят на консоль данные для мониторинга: Для настройки конфигурации агента zabbix-agent2 отредактируйте файл /etc/zabbix/zabbix_agent2.conf: Добавьте в конец этого файла следующие строки: После этого перезапустите сервис zabbix-agent2 и проверьте его статус: Откройте через web-интерфейс Zabbix раздел Latest Data для вашего узла Repka Pi. На экране появятся данные метрик шаблона zabbix-repka-pi-iot (рис. 17). Метрики, полученные от контроллера BME280, возвращаются программой bme380.py в виде данных JSON: Для получения нужных значений в шаблоне zabbix-repka-pi-iot используется предварительная обработка JSON Path, аналогично тому, как это было описано в статье про мониторинг Repka Pi. В шаблоне zabbix-repka-pi-iot определен только один триггер, срабатывающий при обнаружении контроллером YL-38 протечки воды (рис. 18). Когда YL38 находит воду, на его выходе устанавливается нулевое значение напряжения. Именно на эту ситуацию и настроен триггер. Я присвоил триггеру высокий (High) уровень серьезности, но вы можете изменить его на катастрофический (Disaster), если протечка может иметь очень серьезные последствия. При необходимости добавьте триггеры, например, на слишком низкую и высокую температуру или на появление света там, где его не должно быть. При срабатывании триггера сервер Zabbix может отправлять вам сообщения Email, SMS, писать в Телеграм и даже звонить голосом по телефону, если все это настроить. Как известно, погода переменчива. Настроив мониторинг метеостанции с помощью Zabbix, вы сможете убедиться в этом лично. На рис. 19 показан график изменения температуры в районе рабочего стола автора этой статьи при открытом окне. Как видите, утром температура немного повысилась. В целом, для лета это неплохая температура. Влажность тоже вполне приемлемая, и к утру она немного повысилась (рис. 20). Давление изменялось не очень сильно. На рис. 21 показаны его значение в гПа. Измеряя освещенность, можно заметить, что солнце зашло примерно в 9 часов вечера, а в 4:19 начался восход (рис. 22). Сравнивая график освещенности с графиками температуры и влажности, можно обнаружить связь — с восходом солнца температура и влажность увеличились. Что логично. Для имитации протечки мы использовали чашку с водой, опуская в нее сенсор MH-RD, подключенный к контроллеру YL-38. На рис. 23 виден график изменения значений, полученных от YL-38. По умолчанию Zabbix получает значение раз в минуту. Пунктирной линией красного цвета на этом графике обозначено пороговое значение срабатывания триггера протечки. Итак, вы научились подключать устройства IoT к GPIO микрокомпьютера Repka Pi 3, обмениваться с ними данными, в том числе по шине I2C, а также отправлять эти данные в Zabbix для мониторинга и отображения в виде графиков. Также вы настроили триггер в Zabbix, срабатывающий при обнаружении протечки воды. Полученные знания пригодятся, если вы, например, создаете свой умный дом или автоматизируете какое-либо оборудование, подключенное к GPIO, с помощью российского микрокомпьютера Repka Pi 3. Использованы изображения с сайта https://commons.wikimedia.org с лицензией No restrictions: Механический термометр Волосяной гигрометр Карманный высотомер Автор: Александр Фролов. НЛО прилетело и оставило здесь промокод для читателей нашего блога: -15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS  Маркетолог