In den letzten Wochen habe ich mich damit beschäftigt, wie ich Werte aus der KNX-Welt via SNMP an ein übergeordnetes Monitoring-System angebunden bekomme.
Wieso SNMP? Klar, es gibt ja scheinbar schon Lösungen für z.B. Nagios, aber SNMP ist ein offener, universeller Standard, der nicht an ein bestimmtes Produkt gebunden ist. SNMP in der Monitoring-Welt ist sowas wie KNX in der Gebäudeautomatisierung. Ist nicht perfekt, erledigt aber seinen Job zuverlässig und wird von vielen Produkten herstellerunabhängig unterstützt.
Im Wiregate ist zwar von Haus aus eine eigene OID vorhanden (1.3.6.1.4.1.25798.1), diese tut jedoch momentan nichts anderes, als ein "Hello World" auszuspucken. Ein Zugriff auf tatsächliche Werte von Temperatursensoren oder gar dem KNX-Bus ist nicht implementiert und die Implementierung, laut elabnet, aufgrund der geringen Nachfrage in nächster Zeit auch nicht vorgesehen.
Ich bin mittlerweile bei folgender selbstgestrickter Lösung angekommen:
Unterschiedliche Datenquellen deshalb, weil ich mir nicht die Mühe gemacht habe, bestimmte Datentypen - nämlich DPT:9 (Temperatur) und DPT:14 (Stromaufnahme) - aufwändig zu konvertieren. Hier war es für mich einfacher, diese Werte aus den RRDs auszulesen.
Eine Abfrage über SNMP sähe beispielsweise so aus:
Ergebnis:
0/5/202 ist dabei die gewünschte GA, die abgefragt werden soll. 355 ist das Ergebnis der Abfrage.
Als Datenquellen werden angenommen:
Woher die Datenquelle stammt, ist für die SNMP-Abfrage letztlich uninteressant; dies wird durch das Bash-Script respektive die definierten extends bewusst abstrahiert.
Hier eine Übersicht, wie ich das verwende:
Implementierung
Also, nochmal zum Ablauf:
Es müssen zwei Komponenten konfiguriert werden. Einmal muss das Converter-Script (knxread.sh) angelegt werden. Und dann müssen die extends im SNMP-Daemon hinterlegt werden. Diese extends rufen das Converter-Script auf, das seinerseits die jeweiligen Daten zurückgibt.
1. Script anlegen
Man braucht root-Zugriff auf das Wiregate und loggt sich via SSH ein.
Zuerst wird das Converter-Script (knxread.sh - siehe Anhang) angelegt. Ich lege es z.B. unter /usr/local/bin/knxread.sh ab.
Dem Script werden passende Ausführungsrechte zugewiesen (chmod 700 /usr/local/bin/knxread.sh). Fehler werden übrigens nach /var/log/syslog geloggt (Tipp: 'grep knxread /var/log/syslog').
2. SNMP-Daemon konfigurieren
Dann ist der SNMP-Daemon dran. Man öffnet die Konfigurationsdatei des SNMP-Daemon (/etc/snmp/snmpd.conf) und hängt ans Ende der Datei die extends an. Für jeden Wert, der über SNMP abgefragt werden soll, muss ein eigenes extend angelegt werden, z.B.:
Dabei sind drei Parameter wichtig: Einmal der Name des extends, unter dem er via SNMP abgefragt werden kann. Ich verwende als Namen eine GA (das ist die erste hier angegebene GA 2/4/150). Das muss jedoch keine GA sein; im Prinzip könnte man auch folgendes angeben:
Dann würde die Abfrage via SNMP so aussehen:
Dann kommt der Schalter, also z.B. -r oder -c. Die verfügbaren Schalter werden ausgegeben, wenn man folgenden Befehl aufruft: /usr/local/bin/knxread.sh -? help. Auszug:
Als letztes wird die Quelle angegeben. Das kann entweder eine GA sein (2/4/150) oder der Dateiname eines RRD (28.4DFAAA030000_temp.rrd). Die RRDs sind im Wiregate unter /var/www/rrd abgelegt.
Hat man alle extends eingetragen, muss zum Abschluss noch der SNMP-Daemon neu gestartet werden (/etc/init.d/snmpd restart). Ab dem Neustart können die angegebenen Extends dann über SNMP ausgelesen werden.
Im Anhang das Script.
Wieso SNMP? Klar, es gibt ja scheinbar schon Lösungen für z.B. Nagios, aber SNMP ist ein offener, universeller Standard, der nicht an ein bestimmtes Produkt gebunden ist. SNMP in der Monitoring-Welt ist sowas wie KNX in der Gebäudeautomatisierung. Ist nicht perfekt, erledigt aber seinen Job zuverlässig und wird von vielen Produkten herstellerunabhängig unterstützt.
Im Wiregate ist zwar von Haus aus eine eigene OID vorhanden (1.3.6.1.4.1.25798.1), diese tut jedoch momentan nichts anderes, als ein "Hello World" auszuspucken. Ein Zugriff auf tatsächliche Werte von Temperatursensoren oder gar dem KNX-Bus ist nicht implementiert und die Implementierung, laut elabnet, aufgrund der geringen Nachfrage in nächster Zeit auch nicht vorgesehen.
Ich bin mittlerweile bei folgender selbstgestrickter Lösung angekommen:
- Anstatt umständlich eigene MIBs zu definieren, werden die Werte über SNMP extends ausgegeben. Die OIDs sind nach Gruppenadressen benannt, also sehr einfach zu implementieren. D.h. in dem auf dem Wiregate befindlichen SNMP-Daemon werden die gewünschten Extends hinterlegt.
- Die extends rufen ein simples Bash-Script auf, das die Werte aus unterschiedlichen Datenquellen abholt, konvertiert und das Ergebnis an den SNMP-Daemon zurückgibt.
Unterschiedliche Datenquellen deshalb, weil ich mir nicht die Mühe gemacht habe, bestimmte Datentypen - nämlich DPT:9 (Temperatur) und DPT:14 (Stromaufnahme) - aufwändig zu konvertieren. Hier war es für mich einfacher, diese Werte aus den RRDs auszulesen.
Eine Abfrage über SNMP sähe beispielsweise so aus:
Code:
snmpget -v2c -c public wiregate.example.com 'NET-SNMP-EXTEND-MIB::nsExtendOutLine."[B]0/5/202[/B]".1'
Code:
NET-SNMP-EXTEND-MIB::nsExtendOutLine."[B]0/5/202[/B]".1 = STRING: [B]355[/B]
Als Datenquellen werden angenommen:
- RRD-Datei (last oder AVERAGE)
- EIB Cache
- direkte Abfrage aus dem KNX.
Woher die Datenquelle stammt, ist für die SNMP-Abfrage letztlich uninteressant; dies wird durch das Bash-Script respektive die definierten extends bewusst abstrahiert.
Hier eine Übersicht, wie ich das verwende:
ELEMENT | DPT | Needs conversion | Sampling frequency | Sampling frequency | Source |
Schalten/Status (Ein/Aus) | DPT:1 | no | high | (5m) | direct read (use sparingly!) |
Rollo Position (0-100%) | DPT:5 | yes (easy) | medium | (5m) | cache |
Helligkeit (lux) | DPT:7 | no | high | (5m) | cache |
Betriebsstunden (h) | DPT:7 | no | low | (30m) | cache |
Temperatur (°C) | DPT:9 | yes | high | (2m) | rrd |
Stromverbrauch (Wh) | DPT:13 | no | low | (30m) | cache |
Stromaufnahme (A) | DPT:14 | yes | high | (10m) | cache (delta) |
System info | - | - | high | (5m) | rrd |
Also, nochmal zum Ablauf:
Es müssen zwei Komponenten konfiguriert werden. Einmal muss das Converter-Script (knxread.sh) angelegt werden. Und dann müssen die extends im SNMP-Daemon hinterlegt werden. Diese extends rufen das Converter-Script auf, das seinerseits die jeweiligen Daten zurückgibt.
1. Script anlegen
Man braucht root-Zugriff auf das Wiregate und loggt sich via SSH ein.
Zuerst wird das Converter-Script (knxread.sh - siehe Anhang) angelegt. Ich lege es z.B. unter /usr/local/bin/knxread.sh ab.
Dem Script werden passende Ausführungsrechte zugewiesen (chmod 700 /usr/local/bin/knxread.sh). Fehler werden übrigens nach /var/log/syslog geloggt (Tipp: 'grep knxread /var/log/syslog').
2. SNMP-Daemon konfigurieren
Dann ist der SNMP-Daemon dran. Man öffnet die Konfigurationsdatei des SNMP-Daemon (/etc/snmp/snmpd.conf) und hängt ans Ende der Datei die extends an. Für jeden Wert, der über SNMP abgefragt werden soll, muss ein eigenes extend angelegt werden, z.B.:
Code:
# Syntax: #extend [B][Name][/B] /usr/local/bin/knxread.sh [B][Schalter][/B] [B][Quelle][/B] # Stromverbrauch Gesamt extend [B]0/5/202[/B] /usr/local/bin/knxread.sh [B]-c 0/5/202[/B] # Temperatur EG Bad extend [B] 2/4/150[/B] /usr/local/bin/knxread.sh [B]-r 28.4DFAAA030000_temp.rrd[/B]
Code:
# Temperatur EG Bad extend [B]temp_eg_bad[/B] /usr/local/bin/knxread.sh -r 28.4DFAAA030000_temp.rrd
Code:
snmpget -v2c -c public wiregate.example.com 'NET-SNMP-EXTEND-MIB::nsExtendOutLine."[B]temp_eg_bad[/B]".1'
Code:
Usage: '[B]/usr/local/bin/knxread.sh [options] [source][/B]'. The options are: [B]-r[/B] Read last raw value from a RRD file. The name of the RRD file has to be specified. Example: '[I]knxread.sh -r 28.4DFAAA030000_temp.rrd[/I]'. [B]-a[/B] Read last AVERAGE value from a RRD file. The name of the RRD file has to be specified. Example: '[I]knxread.sh -a 28.4DFAAA030000_temp.rrd[/I]'. [B]-c[/B] Read from the KNX cache. The name of a KNX group address (GA) has to be specified. Example: '[I]knxread.sh -c 0/5/202[/I]'. [B]-k[/B] Directly read from KNX. The name of a KNX group address (GA) has to be specified. Example: '[I]knxread.sh -k 0/5/202[/I]'. Be aware that this causes KNX bus traffic! [B]-4[/B] Read from the KNX cache and perform a conversion on DPT:14. Example: '[I]knxread.sh -4 0/5/202[/I]'. [B]-5[/B] Read from the KNX cache and perform a conversion on DPT:5. Example: '[I]knxread.sh -5 0/5/202[/I]'. [B]-9[/B] Read from the KNX cache and perform a conversion on DPT:9. Example: '[I]knxread.sh -9 0/5/202[/I]'. [B]-?[/B] Show this help.
Hat man alle extends eingetragen, muss zum Abschluss noch der SNMP-Daemon neu gestartet werden (/etc/init.d/snmpd restart). Ab dem Neustart können die angegebenen Extends dann über SNMP ausgelesen werden.
Im Anhang das Script.
Kommentar