Cleanup config.nodes_of
[check_mk.git] / checks / printer_supply
blob837ff6c6bc692edf21a242fb47d03155216328f5
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 # In some cases the name of the part is not uniq. e.g. for c5900
28 # devices. In this cases add the color from the dedicated OID to
29 # the item name.
31 # Example output for this case:
33 #['Toner Cartridge OKI DATA CORP', '100', '30', 'black']
34 #['Toner Cartridge OKI DATA CORP', '100', '10', 'cyan']
35 #['Toner Cartridge OKI DATA CORP', '100', '10', 'magenta']
36 #['Toner Cartridge OKI DATA CORP', '100', '40', 'yellow']
37 #['Image Drum Unit OKI DATA CORP', '20000', '-409', '']
38 #['Image Drum Unit OKI DATA CORP', '20000', '7969', '']
39 #['Image Drum Unit OKI DATA CORP', '20000', '11597', '']
40 #['Image Drum Unit OKI DATA CORP', '20000', '4621', '']
41 #['Belt Unit OKI DATA CORP', '60000', '47371', '']
42 #['Fuser Unit OKI DATA CORP', '60000', '26174', '']
43 #['Waste Toner box OKI DATA CORP', '1', '-2', '']
45 # Warn/Crit/upturn current
46 factory_settings["printer_supply_default_levels"] = {
47 "levels": (20.0, 10.0),
50 # When the printer reports -3 as fill threshold the toner
51 # might be empty or might have some small remaining capacities
52 # the exact amount is unknown. This makes the nagios state reported
53 # in this state configurable
54 printer_supply_some_remaining_status = 1
56 # TODO: This variable is deprecated. Remove it in future
57 check_config_variables.append("printer_supply_some_remaining_status")
59 # Workaround for toners and drum units in c5900 devices
60 # which have equal names for the single parts.
61 # Add the color description to that item
62 # Fix name for toners in DELL devices that have serial
63 # numbers in item name
66 def printer_supply_fix_infos(info):
67 colors = []
68 new_info = []
69 for index, (description, max_capacity, level, class_, color) in enumerate(info):
70 # give chance for latin1->utf8 decoding
71 line_0 = description
73 # For toners or drum units add the color (if available)
74 if line_0.startswith('Toner Cartridge') \
75 or line_0.startswith('Image Drum Unit'):
76 if color:
77 colors += [color]
78 elif color == '' and colors:
79 color = colors[index - len(colors)]
80 else:
81 color = None
82 if color:
83 line_0 = '%s %s' % (color.title(), line_0)
85 if " S/N:" in line_0:
86 line_0 = line_0[:line_0.find(" S/N:")]
88 new_info.append([line_0, max_capacity, level, class_, color])
89 return new_info
92 def inventory_printer_supply(info):
93 # Ignore devices which show -2 for current value and -2 for max value -> useless
94 # Also fix trailing zero bytes (seen on HP Jetdirect 143)
95 return [
96 (description.rstrip('\0'), {})
97 for description, max_capacity, level, _class, _color in printer_supply_fix_infos(info)
98 # ignore useless devices
99 if not (max_capacity == '-2' and level == '-2') and level and len(max_capacity) > 0
103 def check_printer_supply(item, params, info):
104 if isinstance(params, tuple):
105 if len(params) == 2:
106 params = {"levels": params}
107 else:
108 params = {
109 "levels": params[:2],
110 "upturn_toner": params[2],
113 for description, max_capacity, level, class_, color in printer_supply_fix_infos(info):
114 if description.rstrip('\0') == item:
115 max_capacity = int(max_capacity)
116 level = saveint(level)
118 color_info = ""
119 if color and color.lower() not in item.lower():
120 color_info = "[%s] " % color
122 # Assume 100% as maximum when 0 is reported
123 # Saw some toner cartridge reporting value=0 and max_capacity=0 on empty toner
124 if max_capacity == 0:
125 max_capacity = 100
127 warn, crit = params["levels"]
128 perfdata = [("pages", level, warn / 100.0 * max_capacity, crit / 100.0 * max_capacity,
129 0, max_capacity)]
131 # handle cases with partial data
132 if max_capacity == -2 or level in [-3, -2, -1]: # no percentage possible
133 if level == -1 or max_capacity == -1:
134 return 0, "%sThere are no restrictions on this supply" % color_info
135 elif level == -3:
136 return params.get("some_remaining", printer_supply_some_remaining_status),\
137 "%sSome remaining" % color_info, perfdata
138 elif level == -2:
139 return 3, "%s Unknown level" % color_info
140 elif max_capacity == -2:
141 # no percentage possible. We compare directly against levels
142 return 0, "%sLevel: %d" % (color_info, level), [("pages", level)]
144 leftperc = 100.0 * float(level) / max_capacity
145 # When unit type is
146 # 1 = other
147 # 3 = supplyThatIsConsumed
148 # 4 = supplyThatIsFilled
149 # the value is contains the current level if this supply is a container
150 # but when the remaining space if this supply is a receptacle
152 # This table can be missing on some devices. Assume type 3 in this case.
153 if class_ == '4':
154 leftperc = 100 - leftperc
156 # Some printers handle the used / remaining material differently
157 # With the upturn option we can toggle the point of view (again)
158 if params.get("upturn_toner", False):
159 leftperc = 100 - leftperc
161 infotext = "%sRemaining: %.0f%%" % (color_info, leftperc)
162 state = 0
163 if leftperc <= crit:
164 state = 2
165 elif leftperc <= warn:
166 state = 1
167 if state:
168 infotext += " (warn/crit at %.0f%%/%.0f%%)" % (warn, crit)
169 return state, infotext, perfdata
172 check_info["printer_supply"] = {
173 'inventory_function': inventory_printer_supply,
174 'check_function': check_printer_supply,
175 'service_description': 'Supply %s',
176 'snmp_info': (
177 '.1.3.6.1.2.1.43',
179 '11.1.1.6', # Printer-MIB::prtMarkerSuppliesDescription
180 '11.1.1.8', # Printer-MIB::prtMarkerSuppliesMaxCapacity
181 '11.1.1.9', # Printer-MIB::prtMarkerSuppliesLevel
182 '11.1.1.4', # Printer-MIB::prtMarkerSuppliesClass
183 '12.1.1.4', # Printer-MIB::prtMarkerColorantValue
185 'snmp_scan_function': lambda oid: all((
186 oid(".1.3.6.1.2.1.43.11.1.1.6.1.1") is not None,
187 oid(".1.3.6.1.2.1.1.2.0") != ".1.3.6.1.4.1.367.1.1",
188 )), # exclude ricoh printer
189 'has_perfdata': True,
190 'group': 'printer_supply',
191 'default_levels_variable': 'printer_supply_default_levels',