Unsere Organisation hat einen Zabbix-Server bereitgestellt, um den Zustand von Servern und Workstations zu überwachen. Aufgrund der Besonderheiten des technischen Prozesses werden die Geräte in mehreren Räumen „verteilt“ und im gesamten Unternehmen verteilt. Natürlich möchte ich zusammen mit den Hauptparametern von Computern (arbeiten / nicht funktionieren) das Mikroklima in den Servern steuern. Gleichzeitig sind die Möglichkeiten wie üblich sehr begrenzt, und das „Ausschalten“ erheblicher Mittel für komplexe Temperaturüberwachungssysteme (ich schließe auch Steuerplatinen mit Temperatursensoren für Rack-APC-USVs ein) ist eine separate Aufgabe.
Auf dem Hauptserver ist alles einfach: Eine solche Karte ist installiert (sie wurde vor langer Zeit vom Vorgänger zusammen mit der Hauptausrüstung gekauft), ein APC-Sensor ist installiert, ein Agent ist in Zabbix installiert, alles funktioniert über SNMP. Langweilig :) Es gibt keine Überwachung der Remote-Hardware, bedeutet auch - siehe oben. Aus diesem Grund wurde beschlossen, intelligent zu sein, das Budget zu sparen und gleichzeitig neue Fähigkeiten zu entwickeln, indem eine einfache und kostengünstige „knietiefe“ Lösung entwickelt wurde, die dennoch in die vorhandene Überwachungsinfrastruktur von Zabbix passt.
Notwendige Komponenten:
Die Gesamtkosten der Komponenten betragen 10 USD bei Lieferung.
Die Montage des Gerätes ist nicht schwierig. Das Netzwerkmodul wird mit einem „Sandwich“ auf die Hauptplatine gelegt, der Temperatursensor wird an seine Stifte gelötet. Sensoranschluss: rot +5 V, schwarz - Masse, gelb - Daten; Löten Sie zwischen + 5V und Daten einen 4,7-kΩ-Pull-up-Widerstand.
Der Daten-Pin wird unter Berücksichtigung der vom Netzwerkmodul verwendeten Pins ausgewählt (D10-SS; D11-MOSI; D12-MISO; D13-SCK; D2-IRQ).
Rechen: Im Prototyp des Geräts bin ich auf einen Konflikt gestoßen - Temperaturdaten wurden zufällig ausgegeben, "zwei bis drei". Der Grund war, dass ich den Temperatursensor an Pin 2 angeschlossen habe, der, wie ich später im Internet fand, vom Netzwerkmodul verwendet wird, um einen Interrupt zu generieren, wenn ein Paket ankommt. Am 4. neu arrangiert - es funktionierte wie eine Uhr.Wechseln Sie nach dem Zusammenbau der Hardware zur Software.
Das Gerät arbeitet im Netzwerk und gibt vor, ein Zabbix-Agent zu sein. Dazu benötigt es einen MAC und eine IP-Adresse. Wir entscheiden, wie es bequemer ist - schwer zu nähen während der Programmierung, generieren einen
MAC aus der Adresse des Temperatursensors und empfangen IP über DHCP usw. Ich habe den einfachsten Weg genommen und beide Parameter fest codiert.
Das Kommunikationsprotokoll mit dem zabbix-Server ist in der
Dokumentation beschrieben . Unser Gerät reagiert auf zwei Befehle -
agent.ping und
env.temp (es gibt Raum für weitere Kreativität, Sie können jedes der für Arduino verfügbaren Erweiterungsmodule binden - zumindest einen Feuchtigkeitssensor, mindestens eine Beleuchtung - was auch immer Ihr Herz begehrt). Es wird auf alle anderen Befehle mit einer Standardantwort
schwören , die für den zabbix-Server verständlich ist.
Für diejenigen, die von vorne anfangen (wie ich) - Die Arduino-Programmierung erfolgt mit der
Arduino-IDE , deren Installation und Konfiguration elementar ist. Für die Komponenten sind die UIPEthernet- und OneWire-Bibliotheken erforderlich, die über das Menü Skizze - Bibliothek verbinden - Bibliotheken verwalten ... installiert und mit dem Projekt verbunden werden.
Wenn Sie andere Komponenten haben (zum Beispiel befindet sich das Netzwerkmodul nicht auf enc28j60, sondern auf einem anderen Chip), benötigen Sie andere Bibliotheken!Der Code für die Arbeit mit dem Netzwerkmodul und dem Temperatursensor ist typisch für das Internet, mit einigen Annahmen und Vereinfachungen.
Nachdem wir den Code in die Steuerung eingegeben und das Ethernet-Kabel angeschlossen haben, überprüfen wir von der Konsole aus:
$ 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: Die kompilierte Version von zabbix_get für Windows auf zabbix.com ist veraltet und verwendet ein anderes Protokoll (mit dem Header ZBXD \ x01 in der Serveranforderung). Die Linux-Version ist aktuell und das Protokoll entspricht dem angegebenen Code.Alles funktioniert wie vorgesehen. Erstellen Sie im zabbix-Administrationsbereich einen neuen Host mit der ausgewählten IP-Adresse und zwei Schlüsseln, Numeric (unsigned) agent.ping und Numeric (float) env.temp. Charts, Trigger - alles ist wie gewohnt.
Das Gerät wird über seinen nativen USB-Anschluss mit Strom versorgt. Gehäuse - optional: geeignete Kunststoffbox, Schrumpfschlauch, blaues Isolierband.
Die Auflösung des Sensors beträgt ungefähr 0,06 (genauer gesagt 1/16) ° C, Genauigkeit - beim Eintauchen in schmelzenden Schnee zeigte er 0,19 ° C (vielleicht wäre er noch tiefer gefallen, aber es gab wenig Schnee und er schmolz schnell). Ich denke für ein Gerät im Wert von 10 Dollar und die beschriebenen Zwecke - mehr als genug.
Skizze #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(); } }