Notre organisation a déployé un serveur Zabbix pour surveiller la santé des serveurs et des postes de travail. En raison des particularités du processus technique, l'équipement est «réparti» dans plusieurs salles et distribué dans toute l'entreprise. Naturellement, avec les principaux paramètres des ordinateurs (fonctionnant / ne fonctionnant pas), je veux contrôler le microclimat dans ceux du serveur. Dans le même temps, comme d'habitude, les possibilités sont très limitées et «éliminer» des fonds importants pour des systèmes de surveillance de température complexes (j'inclus également des cartes de contrôle avec des capteurs de température pour les onduleurs APC montés en rack) est une quête distincte.
Tout est simple dans le serveur principal: une telle carte est installée (elle a été achetée il y a longtemps par le prédécesseur avec l'équipement principal), un capteur APC est installé, un agent est installé dans Zabbix, tout fonctionne via SNMP. Boring :) Il n'y a pas de surveillance du matériel distant, cela signifie aussi - voir ci-dessus. Par conséquent, il a été décidé d'être intelligent, d'économiser le budget et en même temps de pomper une nouvelle compétence en construisant une solution simple et bon marché «jusqu'aux genoux», qui s'intègre néanmoins dans l'infrastructure de surveillance existante de Zabbix.
Composants nécessaires:
Le coût total des composants est de 10 $ à la livraison.
L'assemblage de l'appareil n'est pas difficile. Le module réseau est placé sur la carte principale avec un "sandwich", le capteur de température est soudé à ses broches. Connexion du capteur: rouge +5 V, noir - masse, jaune - données; Entre + 5 V et données, soudez une résistance de rappel de 4,7 kΩ.
La broche de données est sélectionnée en tenant compte des broches utilisées par le module réseau (D10 - SS; D11 - MOSI; D12 - MISO; D13 - SCK; D2 - IRQ).
Rake: dans le prototype de l'appareil, j'ai rencontré un conflit - les données de température ont été émises au hasard, «deux à trois». La raison en était que j'ai accroché le capteur de température à la broche 2, qui, comme je l'ai trouvé plus tard sur Internet, est utilisée par le module réseau pour générer une interruption lorsqu'un paquet arrive. Réarrangé le 4 - cela a fonctionné comme une horloge.Après avoir assemblé le matériel, accédez au logiciel.
L'appareil fonctionnera sur le réseau et fera semblant d'être un agent zabbix, pour cela il a besoin d'un MAC et d'une adresse IP. Nous décidons comment c'est plus pratique - difficile à coudre pendant la programmation, générer un
MAC à partir de l'adresse du capteur de température et recevoir IP via DHCP, etc. J'ai pris le chemin le plus simple et codé en dur les deux paramètres.
Le protocole de communication avec le serveur zabbix est
décrit dans la
documentation . Notre appareil répondra à deux commandes -
agent.ping et
env.temp (il y a de la place pour plus de créativité, vous pouvez lier n'importe lequel des modules d'extension disponibles pour arduino - au moins un capteur d'humidité, au moins un éclairage - tout ce que votre cœur désire). Il
jurera à toutes les autres commandes avec une réponse standard, compréhensible pour le serveur zabbix.
Pour ceux qui partent de zéro (comme moi) - La programmation Arduino se fait en utilisant l'
IDE Arduino , dont l'installation et la configuration sont élémentaires. Les composants nécessitent les bibliothèques UIPEthernet et OneWire, qui sont installées et connectées au projet via le menu Sketch - Connecter la bibliothèque - Gérer les bibliothèques ...
Si vous avez d'autres composants (par exemple, le module réseau n'est pas sur enc28j60, mais sur une autre puce) - vous aurez besoin d'autres bibliothèques!Le code pour travailler avec le module réseau et avec le capteur de température est typique, à partir d'Internet, avec quelques hypothèses et simplifications.
Après avoir rempli le code dans le contrôleur et connecté le câble Ethernet, nous vérifions à partir de la 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: la version compilée de zabbix_get pour Windows sur zabbix.com est obsolète et utilise un protocole différent (avec l'en-tête ZBXD \ x01 dans la demande du serveur). La version Linux est à jour et le protocole correspond au code donné.Tout fonctionne comme prévu. Dans le panneau d'administration zabbix, créez un nouvel hôte avec l'IP sélectionnée, deux clés, Numeric (non signé) agent.ping et Numeric (float) env.temp, profitez du travail. Graphiques, déclencheurs - tout est comme d'habitude.
L'appareil est alimenté via son port USB natif. Boîtier - en option: boîte en plastique appropriée, thermorétractable, ruban électrique bleu.
La résolution du capteur est d'environ 0,06 (plus précisément, 1/16) ° C, précision - lorsqu'il était immergé dans la neige fondante, il montrait 0,19 ° C (peut-être aurait-il chuté encore plus bas, mais il y avait peu de neige et il fondait rapidement). Je pense que pour un appareil d'une valeur de 10 $ et les objectifs décrits - plus que suffisant.
Esquisse #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(); } }