Monitoreo de Temperatura y Humedad con Arduino y Zabbix
El monitoreo de condiciones ambientales es clave en muchos entornos industriales, comerciales y domésticos. Usar Arduino junto con Zabbix permite implementar una solución efectiva, escalable y de bajo costo. Este artículo describe cómo usar un agente Zabbix en un Arduino para monitorear temperatura y humedad utilizando un sensor DHT22. También puede ser una herramienta útil para monitorear data centers y entornos similares donde las condiciones ambientales son críticas.
¿Qué es un agente Zabbix?
Un agente Zabbix es un componente del sistema de monitoreo Zabbix que recolecta datos del hardware o software donde está instalado y los envía al servidor Zabbix. En este caso, hemos implementado un agente personalizado en un Arduino para reportar información ambiental.
Materiales
- 1x Arduino Uno R3 o Mega 2560.
- 1x Shield Ethernet WizNet W5100 R3.
- 1x Sensor DHT22 (Temperatura y Humedad).
- Conexión a Internet o red local.
Circuito
Sketch IDE Arduino
El siguiente código crea un agente Zabbix personalizado en Arduino:
/* ZABBIX AGENT (v1.0 FREE) */ #include <Ethernet.h> #include <DHT.h> // ---------------------------------------------------------------------------- static byte ip[4] = {30, 30, 30, 2}; // Direccion IP estatica static byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE}; // Direccion MAC EthernetServer zabbix_agent(10050); // Puerto del agente Zabbix DHT dht(3, DHT22); // Sensor DHT22 en el pin 3 // ---------------------------------------------------------------------------- // Variables para la lectura de temperatura y humedad float humidity = 0.00; float temperature = 0.00; // Variables para la gestion del tiempo unsigned long prev_millis = 0; unsigned long current_millis = 0; // Funcion para enviar respuesta zabbix void zbx_send(byte my_msg[], int len_msg) { static const byte zbx_head[5] = {'Z', 'B', 'X', 'D', 0x01}; byte my_len[8] = {len_msg, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; zabbix_agent.write(zbx_head, 5); // Enviar cabecera zabbix_agent.write(my_len, 8); // Enviar longitud zabbix_agent.write(my_msg, len_msg); // Enviar mensaje } void setup() { // Inicialización de Ethernet Ethernet.begin(mac, ip); zabbix_agent.begin(); // Inicialización del sensor DHT dht.begin(); delay(10); } void loop() { // Leer temperatura y humedad cada 15 segundos current_millis = millis(); if (current_millis - prev_millis > 15000) { humidity = dht.readHumidity(); temperature = dht.readTemperature(); // Verificar si las lecturas son validas if (isnan(humidity) || isnan(temperature)) { humidity = 0.00; temperature = 0.00; Serial.println("Error al leer el sensor DHT."); } prev_millis = current_millis; } // Revisar si hay un servidor Zabbix disponible para recibir comandos EthernetClient zabbix_server = zabbix_agent.available(); if (zabbix_server) { while (zabbix_server.available()) { char msg = zabbix_server.read(); // Verifica el primer byte (0x01) como separador if (msg == 0x01) { msg = zabbix_server.read(); // Saltar los 7 bytes siguientes for (int i = 1; i < 8; i++) { zabbix_server.read(); } // Leer el comando char zbx_cmd[32]; int cmd_len = int(msg); for (int i = 0; i < cmd_len; i++) { zbx_cmd[i] = zabbix_server.read(); } // Asegurarse de que la cadena este terminada zbx_cmd[cmd_len] = '\0'; // Responder segun el comando if (strcmp(zbx_cmd, "agent.ping") == 0) { // Mensaje de agente activo byte zbx_msg[] = {0x31}; zbx_send(zbx_msg, sizeof(zbx_msg)); } else if (strcmp(zbx_cmd, "agent.hostname") == 0) { // Nombre del host byte zbx_msg[] = {'A', 'r', 'd', 'u', 'i', 'n', 'o', ' ', 'S', 'e', 'n', 's', 'o', 'r'}; zbx_send(zbx_msg, sizeof(zbx_msg)); } else if (strcmp(zbx_cmd, "agent.version") == 0) { // Versión del agente byte zbx_msg[] = {'0', '.', '8', '0'}; zbx_send(zbx_msg, sizeof(zbx_msg)); } else if (strcmp(zbx_cmd, "agent.temperature") == 0) { // Temperatura char zbx_msg[8]; dtostrf(temperature, 6, 2, zbx_msg); zbx_send((byte*)zbx_msg, strlen(zbx_msg)); } else if (strcmp(zbx_cmd, "agent.humidity") == 0) { // Humedad char zbx_msg[8]; dtostrf(humidity, 6, 2, zbx_msg); zbx_send((byte*)zbx_msg, strlen(zbx_msg)); } else { // Comando no reconocido byte zbx_msg[] = {'Z', 'B', 'X', '_', 'N', 'O', 'T', 'S', 'U', 'P', 'P', 'O', 'R', 'T', 'E', 'D', 0x00, 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd', ' ', 'i', 't', 'e', 'm', ' ', 'k', 'e', 'y', '.'}; zbx_send(zbx_msg, sizeof(zbx_msg)); } // Detener la conexion con el servidor Zabbix zabbix_server.stop(); } } } delay(10); // Pequeño retardo para evitar sobrecargar el ciclo }
¿Cómo funciona el Sketch?
El Sketch funciona de la siguiente manera:
- Inicialización del hardware: Se configura el Arduino con una dirección IP estática y se inicializa el sensor DHT22.
- Ciclo principal:
- Cada 15 segundos, el Arduino lee datos de temperatura y humedad.
- Si un servidor Zabbix se conecta, el agente responde a comandos específicos como:
agent.ping
: Indica que el agente está activo.agent.temperature
: Envía la temperatura actual.agent.humidity
: Envía la humedad actual.
- Respuestas al servidor Zabbix: Las respuestas usan el protocolo Zabbix para enviar datos en el formato correcto.
Configuración en el Servidor Zabbix
- Crear un host:
- Nombre:
Arduino Sensor
- Dirección IP:
30.30.30.2
(modifique la dirección IP según su red) - Puerto:
10050
- Nombre:
- Configurar ítems:
agent.ping
(Chequear conectividad)agent.temperature
(Temperatura)agent.humidity
(Humedad)
Resultados
Con este setup, los datos de temperatura y humedad se envían al servidor Zabbix, donde puedes visualizarlos en gráficas, establecer alarmas y generar reportes.
Conclusión
Usar Arduino como agente Zabbix abre una gama de posibilidades para monitorear y gestionar entornos en tiempo real. Su flexibilidad y costo lo hacen ideal para implementaciones pequeñas y medianas.