Nossa organização implantou um servidor Zabbix para monitorar a integridade de servidores e estações de trabalho. Devido às peculiaridades do processo técnico, o equipamento é “espalhado” em várias salas e distribuído por toda a empresa. Naturalmente, juntamente com os principais parâmetros dos computadores (funcionando / não funcionando), quero controlar o microclima nos servidores. Ao mesmo tempo, como de costume, as possibilidades são muito limitadas e "gastar" fundos significativos para sistemas complexos de monitoramento de temperatura (eu também incluo quadros de controle com sensores de temperatura para no-breaks da APC montados em rack) é uma tarefa separada.
Tudo é simples no servidor principal: uma dessas placas é instalada (comprada há muito tempo pelo antecessor, juntamente com o equipamento principal), um sensor APC é instalado, um agente é instalado no Zabbix, tudo funciona via SNMP. Chato :) Não há monitoramento do hardware remoto, significa também - veja acima. Portanto, decidiu-se ser inteligente, economizar o orçamento e, ao mesmo tempo, desenvolver uma nova habilidade, construindo uma solução simples e barata, “até os joelhos”, que, no entanto, se encaixa na infraestrutura de monitoramento Zabbix existente.
Componentes necessários:
O custo total dos componentes é de US $ 10 com a entrega.
A montagem do dispositivo não é difícil. O módulo de rede é colocado na placa principal com um "sanduíche", o sensor de temperatura é soldado aos pinos. Conexão do sensor: vermelho +5 V, preto - terra, amarelo - dados; Entre + 5V e Data, solde um resistor de 4,7 kΩ.
O pino de dados é selecionado levando em consideração os pinos usados pelo módulo de rede (D10 - SS; D11 - MOSI; D12 - MISO; D13 - SCK; D2 - IRQ).
Rake: no protótipo do dispositivo, deparei-me com um conflito - os dados de temperatura foram emitidos aleatoriamente, “dois a três”. O motivo foi que eu liguei o sensor de temperatura ao pino 2, que, como descobri mais tarde na Internet, é usado pelo módulo de rede para gerar uma interrupção quando um pacote chega. Reorganizado no dia 4 - funcionou como um relógio.Depois de montar o hardware, vá para o software.
O dispositivo funcionará na rede e fingirá ser um agente zabbix, para isso, precisa de um MAC e um endereço IP. Decidimos como é mais conveniente - difícil de costurar durante a programação, gerar um
MAC a partir do endereço do sensor de temperatura e receber IP via DHCP, etc. Peguei o caminho mais simples e codifiquei os dois parâmetros.
O protocolo de comunicação com o servidor zabbix é
descrito na
documentação . Nosso dispositivo responderá a dois comandos -
agent.ping e
env.temp (há espaço para mais criatividade, você pode ligar qualquer um dos módulos de expansão disponíveis para o arduino - pelo menos um sensor de umidade, pelo menos uma iluminação - o que seu coração desejar). Ele
jurará todos os outros comandos com uma resposta padrão, compreensível para o servidor zabbix.
Para quem começa do zero (como eu) - a programação do Arduino é feita usando o
Arduino IDE , cuja instalação e configuração são elementares. Os componentes requerem as bibliotecas UIPEthernet e OneWire, que são instaladas e conectadas ao projeto por meio do menu Esboço - Biblioteca Connect - Gerenciar bibliotecas ...
Se você tiver outros componentes (por exemplo, o módulo de rede não está no enc28j60, mas em outro chip) - você precisará de outras bibliotecas!O código para trabalhar com o módulo de rede e com o sensor de temperatura é típico, da Internet, com algumas suposições e simplificações.
Depois de preencher o código no controlador e conectar o cabo Ethernet, verificamos no console:
$ 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
Rake: a versão compilada do zabbix_get para Windows apresentada no zabbix.com está obsoleta e usa um protocolo diferente (com o cabeçalho ZBXD \ x01 na solicitação do servidor). A versão do Linux está atualizada e o protocolo corresponde ao código fornecido.Tudo funciona como pretendido. No painel de administração do zabbix, crie um novo host com o IP selecionado, com duas chaves: Numeric (não assinado) agent.ping e Numeric (float) env.temp, aproveite o trabalho. Gráficos, gatilhos - tudo está como sempre.
O dispositivo é alimentado por seu USB nativo. Caixa - opcional: caixa plástica adequada, termorretrátil, fita isolante azul.
A resolução do sensor é de aproximadamente 0,06 (mais precisamente, 1/16) ° C, precisão - quando imerso na neve derretida, mostrava 0,19 ° C (talvez caísse ainda mais, mas havia pouca neve e derretia rapidamente). Eu acho que para um dispositivo no valor de US $ 10 e os propósitos descritos - mais do que suficiente.
Esboço #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(); } }