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.







