Nuestra organización ha implementado un servidor Zabbix para monitorear el estado de los servidores y las estaciones de trabajo. Debido a las peculiaridades del proceso técnico, el equipo se "distribuye" en varias salas y se distribuye por toda la empresa. Naturalmente, junto con los parámetros principales de las computadoras (que funcionan / no funcionan), quiero controlar el microclima en los servidores. Al mismo tiempo, como de costumbre, las posibilidades son muy limitadas, y "eliminar" fondos significativos para sistemas complejos de monitoreo de temperatura (también incluyo paneles de control con sensores de temperatura para UPS APC de montaje en bastidor) es una búsqueda separada.
Todo es simple en el servidor principal: una de esas placas está instalada (fue comprada hace mucho tiempo por el predecesor junto con el equipo principal), se instaló un sensor APC, se instaló un agente en Zabbix, todo funciona a través de SNMP. Aburrido :) No hay monitoreo del hardware remoto, significa también - ver arriba. Por lo tanto, se decidió ser inteligente, ahorrar el presupuesto y, al mismo tiempo, desarrollar una nueva habilidad al construir una solución simple y barata "hasta las rodillas", que sin embargo se ajusta a la infraestructura de monitoreo existente de Zabbix.
Componentes necesarios:
El costo total de los componentes es de $ 10 con entrega.
Ensamblar el dispositivo no es difícil. El módulo de red se coloca en la placa principal con un "emparedado", el sensor de temperatura se suelda a sus pines. Conexión del sensor: rojo +5 V, negro - tierra, amarillo - datos; Entre + 5V y datos, suelde una resistencia pull-up de 4.7 kΩ.
El pin de datos se selecciona teniendo en cuenta los pines utilizados por el módulo de red (D10 - SS; D11 - MOSI; D12 - MISO; D13 - SCK; D2 - IRQ).
Rastrillo: en el prototipo del dispositivo me encontré con un conflicto: los datos de temperatura se emitieron al azar, "dos a tres". La razón fue que conecté el sensor de temperatura al pin 2, que, como descubrí más tarde en Internet, es utilizado por el módulo de red para generar una interrupción cuando llega un paquete. Reorganizado el 4to. Funcionó como un reloj.Después de ensamblar el hardware, vaya al software.
El dispositivo funcionará en la red y pretenderá ser un agente zabbix, para esto necesita un MAC y una dirección IP. Decidimos cómo es más conveniente: difícil de coser durante la programación, generar un
MAC desde la dirección del sensor de temperatura y recibir IP a través de DHCP, etc. Tomé el camino más simple y codifiqué ambos parámetros.
El protocolo de comunicación con el servidor zabbix se
describe en la
documentación . Nuestro dispositivo responderá a dos comandos:
agent.ping y
env.temp (hay espacio para una mayor creatividad, puede vincular cualquiera de los módulos de expansión disponibles para arduino, al menos un sensor de humedad, al menos una luz ambiental, lo que su corazón desee).
Jurará a todos los demás comandos con una respuesta estándar, comprensible para el servidor zabbix.
Para aquellos que comienzan desde cero (como yo): la programación de Arduino se realiza utilizando el
IDE de Arduino , cuya instalación y configuración es elemental. Los componentes requieren las bibliotecas UIPEthernet y OneWire, que están instaladas y conectadas al proyecto a través del menú Boceto - Conectar biblioteca - Administrar bibliotecas ...
Si tiene otros componentes (por ejemplo, el módulo de red no está en enc28j60, sino en otro chip), ¡necesitará otras bibliotecas!El código para trabajar con el módulo de red y con el sensor de temperatura es típico, de Internet, con algunos supuestos y simplificaciones.
Después de completar el código en el controlador y conectar el cable de ethernet, verificamos desde la consola:
$ 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
Rastrillo: la versión compilada de zabbix_get para Windows presentada en zabbix.com está en desuso y utiliza un protocolo diferente (con el encabezado ZBXD \ x01 en la solicitud del servidor). La versión de Linux está actualizada y el protocolo corresponde al código dado.Todo funciona según lo previsto. En el panel de administración de zabbix, cree un nuevo host con la IP seleccionada, dos claves, Numeric (unsigned) agent.ping y Numeric (float) env.temp, disfrute el trabajo. Gráficos, disparadores: todo es como siempre.
El dispositivo se alimenta a través de su USB nativo. Caja - opcional: caja de plástico adecuada, termocontraíble, cinta aislante azul.
La resolución del sensor es de aproximadamente 0.06 (más precisamente, 1/16) ° C, precisión: cuando se sumerge en la nieve derretida, mostró 0.19 ° C (tal vez habría caído aún más bajo, pero había poca nieve y se derritió rápidamente). Creo que para un dispositivo con un valor de $ 10 y los propósitos descritos, más que suficiente.
Bosquejo #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(); } }