Мониторинг температуры в серверной на arduino и dht11

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

Само устройство наипростейшее, просто ардуинка и болтающийся датчик температуры, подключенный ко 2 порту :) Все это безобразие подключено по usb порту к серверу, на котором крутится zabbix-agent. Сам датчик DHT11 может снимать температуру и относительную влажность. Влажность не будем учитывать, так как говорят датчик дает неточные показатели. Осталось решить как отдавать данные данные. Сначала думал по сети, но этот вариант не понравился только покупкой дополнительного модуля. Выбрали подключение по usb. забирать данные будем из com порта.

Самое сложное было решить, каким образом считывать данные. Если сделать как в примере к датчикам dht*, то данные, при просмотре в мониторе последовательного порта терялись и не всегда было точно понятно, что в итоге пришло и как это обрабатывать, проблему не решило даже установки задержки из COM порта. Первой программой было обращение один раз по com порту, чтобы захватить вывод и отправить в файл, дальше его обрабатывать. Протестировали на windows 10 и все понравилось, понесли в серверную, чтобы убедиться в работе, но нет)) Данные считывались только один раз, дальше COM порт не отвечал. В качестве скриптового языка был выбран Python, т.к. его я лучше знаю, чем bash.
В итоге было решено в потоке получать данные, путем отправки им какого-либо сообщения, например "1". Тогда все корректно выводилось. Осталось дело за малым, вывести это в файл, задать переменные в zabbix и вывести это в item

ARDUINO:

#include  <ThreadController.h>
#include  <Thread.h>
#include  <StaticThreadController.h>
#include  <DHT.h>

#define DATA1_LED 13 // Объявляем светодиоды

float temp1 = 0;

Thread DataRead = Thread();


DHT data1(2, DHT11); // Объявляем датчики температуры

void setup() {
    // Вывод светодиодов
    for(int i = 13; i >= 8; i--) { pinMode(i, OUTPUT); }

    data1.begin();


    // Запускам чтение дачиков DHT и одупляем красиво для подключения
    digitalWrite(DATA1_LED, LOW);delay(500);
    digitalWrite(DATA1_LED, HIGH);delay(500);

    for(int i = 13; i >= 8; i--) { digitalWrite(i, 1);delay(100); }
    delay(1000);
    for(int i = 13; i >= 8; i--) { digitalWrite(i, 0);delay(100); }    
    delay(1000);

    // Потоки вызова функций. Светодиод. Данные.
    DataRead.onRun(dread);
    DataRead.setInterval(10000); // Каждые 10 секунд читаем показания

    // Прочитаем данные на старте
    dread();

    Serial.begin(9600);
}

void loop() {  
    if (DataRead.shouldRun())
      DataRead.run();

    cread();
}

// Считываем данные и кажем светодиодами
void dread(){  
  temp1 = data1.readTemperature();
}

// Функция моргания ожидания
void ledBlink() {
    digitalWrite(DATA1_LED, HIGH);
    delay(100);
    digitalWrite(DATA1_LED, LOW);
    delay(200); 
}

// Функция обработки COM порта
void cread() {
  float t = 0; // Температура. 
  // Читаем ввод COM порта
  if (Serial.available() > 0) {
    int val = Serial.read();
      if (val=='1') {
        t = temp1;
        Serial.print("Temp_1: ");Serial.println(t);        
      }

  }
}

Заливаем скетч в ардуино и тестируем, путем отправки "1" в монитор COM-порта. Результат:

Temp_1: 19.5

Если все работает, то можно идти дальше.

Ставим библиотеку pyserial

PYTHON:
pip3 install pyserial

Пишем код на python temp_servers.py

Неоптимизированный код:

#!/usr/bin/python3
import serial
import time
import sys

ser = serial.Serial()
ser.port = "/dev/ttyACM0"
ser.baudrate = 9600

try:
    ser.open()

except Exception:
    print("PORT ERROR")
    sys.exit()

if ser.isOpen():
    ser.flushInput()
    ser.flushOutput()
    while True:
        time.sleep(15)
        # Датчик 1
        ser.write(b'1')
        data_1 = ser.readline().decode('utf-8')

        break
    ser.close()

sys.stdout.write(data_1);sys.stdout.flush();

Я отдельно поместил скрипт в отдельную папку /home/zabbix/scripts, сменил на владельца zabbix

BASH

chown -R zabbix /home/zabbix/*

Теперь добавляем в zabbix agent переменные для отображения

BASH

nano /etc/zabbix/zabbix_agentd.conf

В конец добавляем:

ПАРАМЕТРЫ
UserParameter=temp1[*],cat /home/zabbix/scripts/temp.txt | grep Temp_1 | cut -d " " -f2

Рестартуем агента:

BASH
systemctl restart zabbix-agent

Все это дело теперь добавляем в крон crontab -e

BASH
*/5 * * * * /home/zabbix/scripts/temp_servers.py > /home/zabbix/scripts/temp.txt

Проверим, если ли в файле данные, если да, то можно переходить в zabbix для добавления нового шаблона.

Переходим в нужный узел, там переходим в элементы данных

Готовое устройство выглядит так:

На момент написания статьи всё работало на debian 12 и zabbix 7.0.17

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

Оставить комментарий

Пока нет комментариев. Будьте первым!