Durch Zufall hab ich herausgefunden, dass die meisten HP Drucker ein offenes SNMP-Interface haben, über dieses man verschiedene Parameter abfragen kann, unter anderem den Tintenstand. Als ich dies bei meinem HP Officejet 6700 Premium testete, antwortete dieser auch prompt auf SNMP-Anfragen. Diese Entdeckung wollte ich mir gleich zu Nutze machen, um den Tintenstand mit munin zu überwachen. Nach einer kurzen google suche fand sich auch schnell ein kleines Skript, was aber nicht funktionierte. Zum Glück ließen sich die Probleme schnell lösen.
Zunächst einmal muss man die passenden OIDs herausfinden, die die entsprechende Information enthalten. Leider konnte ich keine passende MIB-Datei finden, sodass ich mich selbst auf Suche begeben musste. Als erstes installieren wir auf unserem System die SNMP-Tools, falls noch nicht vorhanden:
$ apt-get install snmp
Anschließend scannen wir unseren Drucker nach allen möglichen OIDs ab. Dazu führen wir folgenden Befehl aus, wobei 192.168.178.31 für die IP des Druckers steht, die gegebenenfalls angepasst werden muss:
$ snmpwalk -v1 -c public 192.168.178.31
Nun sollten wir eine lange Ausgabe erhalten, die alle verfügbaren Informationen enthält. HP codiert den Tintenfüllstand, indem in einer OID der maximal mögliche Füllstand gespeichert ist und in einer anderen der verbleibende Füllstand. Dies liegt wohl darin begründet, dass z.B. die schwarze Patrone wesentlich größer ist als die Farbpatronen.
Am besten sucht ihr in eurer Ausgabe nach Wörtern wie „black“ oder „ink“, um die entsprechenden Einträge zu finden. Zudem müsst ihr nach dem Namen von eurem Drucker suchen. Bei mir sieht das z.B. wie folgt aus (Ausschnitt):
[...] iso.3.6.1.2.1.1.5.0 = STRING: "printer1" [...] iso.3.6.1.2.1.43.11.1.1.6.0.1 = STRING: "black ink" iso.3.6.1.2.1.43.11.1.1.6.0.2 = STRING: "yellow ink" iso.3.6.1.2.1.43.11.1.1.6.0.3 = STRING: "cyan ink" iso.3.6.1.2.1.43.11.1.1.6.0.4 = STRING: "magenta ink" iso.3.6.1.2.1.43.11.1.1.7.0.1 = INTEGER: 15 iso.3.6.1.2.1.43.11.1.1.7.0.2 = INTEGER: 15 iso.3.6.1.2.1.43.11.1.1.7.0.3 = INTEGER: 15 iso.3.6.1.2.1.43.11.1.1.7.0.4 = INTEGER: 15 iso.3.6.1.2.1.43.11.1.1.8.0.1 = INTEGER: 297 iso.3.6.1.2.1.43.11.1.1.8.0.2 = INTEGER: 114 iso.3.6.1.2.1.43.11.1.1.8.0.3 = INTEGER: 117 iso.3.6.1.2.1.43.11.1.1.8.0.4 = INTEGER: 125 iso.3.6.1.2.1.43.11.1.1.9.0.1 = INTEGER: 282 iso.3.6.1.2.1.43.11.1.1.9.0.2 = INTEGER: 87 iso.3.6.1.2.1.43.11.1.1.9.0.3 = INTEGER: 23 iso.3.6.1.2.1.43.11.1.1.9.0.4 = INTEGER: 89
Zeile 2 enthält den Namen des Druckers.
Zeile 4-7 ist der Name der Tinte gespeichert, 1 ist also black, 2 ist yellow usw.
Zeile 8-11 enthält immer 15, welche Bedeutung das hat weiß ich leider nicht.
Zeile 12-15 enthält der maximal mögliche Füllstand. Wie man sieht ist schwarz mit 297 fast dreifach so groß wie die Farbpatronen.
Zeile 16-19 enthalten den verbleibenden Tintenfüllstand.
Diese OIDs merken wir uns nun bzw. notieren sie uns in einem Editor.
Als nächstes benötigen wir ein Skript, dass diese Daten verarbeitet. Dazu habe ich folgendes Skript als Grundlage genommen: klick. Leider hatte das Skript nicht auf Anhieb funktioniert, das Problem war das snmpget immer Probleme hatte, die letzte OID zu lesen was zu Fehlern führte. Daher habe ich den Befehl einfach durch snmpwalk ersetzt sowie kleinere Anpassungen vorgenommen, wie z.B. einen Wert für warning und critical festgelegt sowie die Gelbtöne zur besseren Leserlichkeit etwas angepasst. Das fertige Skript könnt ihr hier runterladen: klick.
Sobald ihr das Skript heruntergeladen habt, kopiert ihr es auf eurem Server unter /etc/munin/plugins/ und sorgt dafür, dass es ausführbar. Das ganze könnt ihr z.B. mit folgenden drei Befehlen erreichen (als root ausführen):
$ cd /etc/munin/plugins/ $ wget http://public.julian-w.de/other/scripts/snmp_hp_tonerlevel.sh $ chmod +x /etc/munin/plugins/snmp_hp_tonerlevel.sh
Anschließend müsst ihr das Skript noch anpassen. Dazu öffnen wir die Datei in einem Editor
$ mcedit /etc/munin/plugins/snmp_hp_tonerlevel.sh
Und bearbeiten die folgenden Zeilen. Hier müsst ihr die OIDs einfügen, die ihr weiter oben bestimmt habt. Zudem müsst ihr die IP so ändern, dass sie auf euren Drucker zeigt. Sorgt am besten dafür, dass euer HP Drucker eine statische IP in eurem Netzwerk besitzt.
# printer name MIB_NAME="iso.3.6.1.2.1.1.5.0" # cartridge colors max level MIB_MAX_BLACK="iso.3.6.1.2.1.43.11.1.1.8.0.1" MIB_MAX_CYAN="iso.3.6.1.2.1.43.11.1.1.8.0.3" MIB_MAX_MAGENTA="iso.3.6.1.2.1.43.11.1.1.8.0.4" MIB_MAX_YELLOW="iso.3.6.1.2.1.43.11.1.1.8.0.2" # cartridge colors current level MIB_LEVEL_BLACK="iso.3.6.1.2.1.43.11.1.1.9.0.1" MIB_LEVEL_CYAN="iso.3.6.1.2.1.43.11.1.1.9.0.3" MIB_LEVEL_MAGENTA="iso.3.6.1.2.1.43.11.1.1.9.0.4" MIB_LEVEL_YELLOW="iso.3.6.1.2.1.43.11.1.1.9.0.2" # ------------------------------------------------------- # Get printer specs # ------------------------------------------------------- # get printer name from script name #PRINTER_IP=$(basename $0 | cut -d'_' -f2) PRINTER_IP="192.168.178.31"
Sobald ihr die Änderungen vorgenommen und die Datei gespeichert habt, könnt ihr das Plugin auch gleich testen. Führt dazu folgende Befehle aus:
$ munin-run snmp_hp_tonerlevel.sh config $ munin-run snmp_hp_tonerlevel.sh
Die Ausgabe sollte in etwa wie folgt aussehen:
root@server:/etc/munin/plugins# munin-run snmp_hp_tonerlevel.sh multigraph black black-left.value 94 black-used.value 6 multigraph cyan cyan-left.value 19 cyan-used.value 81 multigraph magenta magenta-left.value 71 magenta-used.value 29 multigraph yellow yellow-left.value 76 yellow-used.value 24 root@server:/etc/munin/plugins# munin-run snmp_hp_tonerlevel.sh config multigraph black graph_title Black Toner graph_vlabel Cartridge level (%) graph_category toner graph_info This graph shows the Black toner level in % graph_args --upper-limit 100 -l 0 --rigid black-left.info printer1 black toner level is 282 out of 297 black-left.label Black available black-left.draw AREASTACK black-left.colour 000000 black-left.min 0 black-left.max 100 black-used.label Black used black-used.draw AREASTACK black-used.colour d0d0d0 black-used.min 0 black-used.max 100 black-left.warning 15:100 black-left.critical 7:100 multigraph cyan graph_title Cyan Toner graph_vlabel Cartridge level (%) graph_category toner graph_info This graph shows the Cyan toner level in % graph_args --upper-limit 100 -l 0 --rigid cyan-left.info printer1 cyan toner level is 23 out of 117 cyan-left.label Cyan available cyan-left.draw AREASTACK cyan-left.colour 00ffff cyan-left.min 0 cyan-left.max 100 cyan-used.label Cyan used cyan-used.draw AREASTACK cyan-used.colour d0ffff cyan-used.min 0 cyan-used.max 100 cyan-left.warning 15:100 cyan-left.critical 7:100 multigraph magenta graph_title Magenta Toner graph_vlabel Cartridge level (%) graph_category toner graph_info This graph shows the Magenta toner level in % graph_args --upper-limit 100 -l 0 --rigid magenta-left.info printer1 magenta toner level is 89 out of 125 magenta-left.label Magenta available magenta-left.draw AREASTACK magenta-left.colour ff00ff magenta-left.min 0 magenta-left.max 100 magenta-used.label Magenta used magenta-used.draw AREASTACK magenta-used.colour ffd0ff magenta-used.min 0 magenta-used.max 100 magenta-left.warning 15:100 magenta-left.critical 7:100 multigraph yellow graph_title Yellow Toner graph_vlabel Cartridge level (%) graph_category toner graph_info This graph shows the Yellow toner level in % graph_args --upper-limit 100 -l 0 --rigid yellow-left.info printer1 yellow toner level is 87 out of 114 yellow-left.label Yellow available yellow-left.draw AREASTACK yellow-left.colour e6e600 yellow-left.min 0 yellow-left.max 100 yellow-used.label Yellow used yellow-used.draw AREASTACK yellow-used.colour ffffcd yellow-used.min 0 yellow-used.max 100 yellow-left.warning 15:100 yellow-left.critical 7:100
Passt die Ausgabe, braucht ihr nur noch euren munin-client neu zu starten und schon werden die Daten geloggt.
$ service munin-node restart
Sollte ein Tintenstand unter 15% fallen, wird eine warning generiert, für alles unter 7% ein critical. Diese Werte könnt ihr einfach anpassen, dazu müsst ihr nur folgende selbsterklärende Zeilen für jede Farbe einzeln abändern:
echo "***-left.warning 15:100" echo "***-left.critical 7:100"
Hier noch einmal der komplette Quellcode im Artikel:
#!/bin/bash # -*- sh -*- # ------------------------------------------------------- # Munin node script # # Monitor the toner level of HP color printers # Retrieves toner levels for black, cyan, magenta & yellow cartridges # # Used in http://bernaerts.dyndns.org/linux/320-munin-snmp-plugin-hp-laser-toner-level # and used in https://www.ioblogger.de/2016/09/hp-officejet-6700-tintenstand-munin/ # # Parameters : # $1 : none, "snmpconf" or "config" # # 20/06/2014, V1.0 - Creation by N. Bernaerts # 07/07/2014, V2.0 - Changed to multigraph # 21/08/2014, V3.0 - Handle multigraph as an option # 17/09/2016, V4.0 - Julian Wolter, julian-w.de - updated to work with more printer, workaround snmp bug # ------------------------------------------------------- : << =cut =head1 NAME snmp__tonerlevel_hp - Munin plugin to monitor the toner level of HP Color Laser Printers =head1 APPLICABLE SYSTEMS Any SNMP-capable HP Color Printer =head1 CONFIGURATION No specific configuration needed. This plugin uses public community. =head1 INTERPRETATION The level in percentage of printer toner cartridges =head1 VERSION $Id$ =head1 BUGS None known. =head1 AUTHOR Copyright (C) 2014 Nicolas Bernaerts, edited 2016 by Julian Wolter =head1 LICENSE GPLv2. =cut # ------------------------------------------------------- # User defined configuration # ------------------------------------------------------- # if defines if display is multigraph (one graph per toner) # or if you want to get all toner levels on the same graph # on : one graph per toner # off : all toner levels on the same graph MULTIGRAPH="on" # ------------------------------------------------------- # Configure all MIBs adresses # ------------------------------------------------------- # printer name MIB_NAME="iso.3.6.1.2.1.1.5.0" # cartridge colors max level MIB_MAX_BLACK="iso.3.6.1.2.1.43.11.1.1.8.0.1" MIB_MAX_CYAN="iso.3.6.1.2.1.43.11.1.1.8.0.3" MIB_MAX_MAGENTA="iso.3.6.1.2.1.43.11.1.1.8.0.4" MIB_MAX_YELLOW="iso.3.6.1.2.1.43.11.1.1.8.0.2" # cartridge colors current level MIB_LEVEL_BLACK="iso.3.6.1.2.1.43.11.1.1.9.0.1" MIB_LEVEL_CYAN="iso.3.6.1.2.1.43.11.1.1.9.0.3" MIB_LEVEL_MAGENTA="iso.3.6.1.2.1.43.11.1.1.9.0.4" MIB_LEVEL_YELLOW="iso.3.6.1.2.1.43.11.1.1.9.0.2" # ------------------------------------------------------- # Get printer specs # ------------------------------------------------------- # get printer name from script name # PRINTER_IP=$(basename $0 | cut -d'_' -f2) PRINTER_IP="192.168.178.31" # ------------------------------------------------------- # Read all MIBs data from the printer # ------------------------------------------------------- # if not in autoconf process, read SNMP data if [ "$1" != "snmpconf" ]; then # read SNMP MIB # MIB_RESULT=$(snmpget -v1 -One -c public $PRINTER_IP $MIB_NAME \ # $MIB_MAX_BLACK $MIB_MAX_CYAN $MIB_MAX_MAGENTA $MIB_MAX_YELLOW \ # $MIB_LEVEL_BLACK $MIB_LEVEL_CYAN $MIB_LEVEL_MAGENTA $MIB_LEVEL_YELLOW) MIB_RESULT=$(snmpwalk -v1 -c public $PRINTER_IP) # get values from result PRINTER_NAME=$(echo $MIB_RESULT | sed 's/.*'$MIB_NAME'[^"]*"\([^"]*\).*/\1/g') MAX_BLACK=$(echo $MIB_RESULT | sed 's/.*'$MIB_MAX_BLACK'[ =:A-Z]*\([0-9]*\).*/\1/g') MAX_CYAN=$(echo $MIB_RESULT | sed 's/.*'$MIB_MAX_CYAN'[ =:A-Z]*\([0-9]*\).*/\1/g') MAX_MAGENTA=$(echo $MIB_RESULT | sed 's/.*'$MIB_MAX_MAGENTA'[ =:A-Z]*\([0-9]*\).*/\1/g') MAX_YELLOW=$(echo $MIB_RESULT | sed 's/.*'$MIB_MAX_YELLOW'[ =:A-Z]*\([0-9]*\).*/\1/g') LEVEL_BLACK=$(echo $MIB_RESULT | sed 's/.*'$MIB_LEVEL_BLACK'[ =:A-Z]*\([0-9]*\).*/\1/g') LEVEL_CYAN=$(echo $MIB_RESULT | sed 's/.*'$MIB_LEVEL_CYAN'[ =:A-Z]*\([0-9]*\).*/\1/g') LEVEL_MAGENTA=$(echo $MIB_RESULT | sed 's/.*'$MIB_LEVEL_MAGENTA'[ =:A-Z]*\([0-9]*\).*/\1/g') LEVEL_YELLOW=$(echo $MIB_RESULT | sed 's/.*'$MIB_LEVEL_YELLOW'[ =:A-Z]*\([0-9]*\).*/\1/g') fi # ------------------------------------------------------- # Handle SNMP autoconf call # ------------------------------------------------------- # snmpconf : announce required MIBs if [ "$1" = "snmpconf" ]; then echo "require $MIB_NAME" echo "require $MIB_MAX_BLACK" echo "require $MIB_MAX_CYAN" echo "require $MIB_MAX_MAGENTA" echo "require $MIB_MAX_YELLOW" echo "require $MIB_LEVEL_BLACK" echo "require $MIB_LEVEL_CYAN" echo "require $MIB_LEVEL_MAGENTA" echo "require $MIB_LEVEL_YELLOW" # ------------------------------------------------------- # Handle configuration call # ------------------------------------------------------- # config : read node configuration elif [ "$1" = "config" ]; then # printer general infos # echo "host_name $PRINTER_IP" if [ "$MULTIGRAPH" = "off" ]; then echo "graph_title Printer Toners" echo "graph_vlabel Cartridge level (%)" echo "graph_category toner" echo "graph_info This graph shows all toner levels in %" echo "graph_args --upper-limit 400 -l 0 --rigid" fi # -------------------- # Black cartridge # -------------------- if [ "$MULTIGRAPH" = "on" ]; then echo "multigraph black" echo "graph_title Black Toner" echo "graph_vlabel Cartridge level (%)" echo "graph_category toner" echo "graph_info This graph shows the Black toner level in %" echo "graph_args --upper-limit 100 -l 0 --rigid" fi echo "black-left.info $PRINTER_NAME black toner level is $LEVEL_BLACK out of $MAX_BLACK" echo "black-left.label Black available" echo "black-left.draw AREASTACK" echo "black-left.colour 000000" echo "black-left.min 0" echo "black-left.max 100" echo "black-used.label Black used" echo "black-used.draw AREASTACK" echo "black-used.colour d0d0d0" echo "black-used.min 0" echo "black-used.max 100" echo "black-left.warning 15:100" echo "black-left.critical 7:100" # -------------------- # Cyan cartridge # -------------------- if [ "$MULTIGRAPH" = "on" ]; then echo "multigraph cyan" echo "graph_title Cyan Toner" echo "graph_vlabel Cartridge level (%)" echo "graph_category toner" echo "graph_info This graph shows the Cyan toner level in %" echo "graph_args --upper-limit 100 -l 0 --rigid" fi echo "cyan-left.info $PRINTER_NAME cyan toner level is $LEVEL_CYAN out of $MAX_CYAN" echo "cyan-left.label Cyan available" echo "cyan-left.draw AREASTACK" echo "cyan-left.colour 00ffff" echo "cyan-left.min 0" echo "cyan-left.max 100" echo "cyan-used.label Cyan used" echo "cyan-used.draw AREASTACK" echo "cyan-used.colour d0ffff" echo "cyan-used.min 0" echo "cyan-used.max 100" echo "cyan-left.warning 15:100" echo "cyan-left.critical 7:100" # -------------------- # Magenta cartridge # -------------------- if [ "$MULTIGRAPH" = "on" ]; then echo "multigraph magenta" echo "graph_title Magenta Toner" echo "graph_vlabel Cartridge level (%)" echo "graph_category toner" echo "graph_info This graph shows the Magenta toner level in %" echo "graph_args --upper-limit 100 -l 0 --rigid" fi echo "magenta-left.info $PRINTER_NAME magenta toner level is $LEVEL_MAGENTA out of $MAX_MAGENTA" echo "magenta-left.label Magenta available" echo "magenta-left.draw AREASTACK" echo "magenta-left.colour ff00ff" echo "magenta-left.min 0" echo "magenta-left.max 100" echo "magenta-used.label Magenta used" echo "magenta-used.draw AREASTACK" echo "magenta-used.colour ffd0ff" echo "magenta-used.min 0" echo "magenta-used.max 100" echo "magenta-left.warning 15:100" echo "magenta-left.critical 7:100" # -------------------- # Yellow cartridge # -------------------- if [ "$MULTIGRAPH" = "on" ]; then echo "multigraph yellow" echo "graph_title Yellow Toner" echo "graph_vlabel Cartridge level (%)" echo "graph_category toner" echo "graph_info This graph shows the Yellow toner level in %" echo "graph_args --upper-limit 100 -l 0 --rigid" fi echo "yellow-left.info $PRINTER_NAME yellow toner level is $LEVEL_YELLOW out of $MAX_YELLOW" echo "yellow-left.label Yellow available" echo "yellow-left.draw AREASTACK" echo "yellow-left.colour e6e600" echo "yellow-left.min 0" echo "yellow-left.max 100" echo "yellow-used.label Yellow used" echo "yellow-used.draw AREASTACK" echo "yellow-used.colour ffffcd" echo "yellow-used.min 0" echo "yellow-used.max 100" echo "yellow-left.warning 15:100" echo "yellow-left.critical 7:100" # ------------------------------------------------------- # Handle data read call # ------------------------------------------------------- # normal case : read cartridge levels else # -------------------- # Black level # -------------------- BLACK_AVAILABLE=$((100 * LEVEL_BLACK / MAX_BLACK)) BLACK_USED=$((100 - BLACK_AVAILABLE)) [ "$MULTIGRAPH" = "on" ] && echo "multigraph black" echo "black-left.value $BLACK_AVAILABLE" echo "black-used.value $BLACK_USED" # -------------------- # Cyan level # -------------------- CYAN_AVAILABLE=$((100 * LEVEL_CYAN / MAX_CYAN)) CYAN_USED=$((100 - CYAN_AVAILABLE)) [ "$MULTIGRAPH" = "on" ] && echo "multigraph cyan" echo "cyan-left.value $CYAN_AVAILABLE" echo "cyan-used.value $CYAN_USED" # -------------------- # Magenta level # -------------------- MAGENTA_AVAILABLE=$((100 * LEVEL_MAGENTA / MAX_MAGENTA)) MAGENTA_USED=$((100 - MAGENTA_AVAILABLE)) [ "$MULTIGRAPH" = "on" ] && echo "multigraph magenta" echo "magenta-left.value $MAGENTA_AVAILABLE" echo "magenta-used.value $MAGENTA_USED" # -------------------- # Yellow level # -------------------- YELLOW_AVAILABLE=$((100 * LEVEL_YELLOW / MAX_YELLOW)) YELLOW_USED=$((100 - YELLOW_AVAILABLE)) [ "$MULTIGRAPH" = "on" ] && echo "multigraph yellow" echo "yellow-left.value $YELLOW_AVAILABLE" echo "yellow-used.value $YELLOW_USED" fi exit 0