Files
snmp-scanner/generate_printer_templates.py
cproudlock 389e620261 Initial commit: SNMP scanner and Zabbix template generator
Tools for printer discovery and monitoring:
- snmp_scanner.py: SNMP-based printer discovery
- generate_printer_templates.py: Generate Zabbix templates
- analyze_supplies.py: Analyze printer supply levels
- extract_summary.py: Extract printer data summaries

Includes Zabbix templates for:
- HP Color/Mono printers
- HP DesignJet T1700
- Xerox Color/Mono/Enterprise printers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 13:52:21 -05:00

793 lines
43 KiB
Python

#!/usr/bin/env python3
"""
Generate separate Zabbix templates for different printer types
Based on actual SNMP analysis of network printers
Includes supply compatibility/consolidation recommendations
"""
import json
import uuid
import yaml
# Supply compatibility and consolidation data
# Maps specific part numbers to compatible/consolidated alternatives
SUPPLY_COMPATIBILITY = {
# HP LaserJet Pro M404n/M406 - HIGH VALUE consolidation
'CF258A': {
'consolidated': 'CF258A or CF258X (58A/58X)',
'compatible_models': ['HP LaserJet Pro M404n', 'HP LaserJet Pro M406'],
'note': 'Both models share identical toner and fuser'
},
'CF258X': {
'consolidated': 'CF258A or CF258X (58A/58X)',
'compatible_models': ['HP LaserJet Pro M404n', 'HP LaserJet Pro M406'],
'note': 'High-yield version - Both models compatible'
},
# HP Color LaserJet M254dw - CRITICAL correction
'CF500A': {
'consolidated': 'CF500A (202A Black)',
'compatible_models': ['HP Color LaserJet M254dw'],
'note': 'Uses 202A series, NOT 414A series'
},
'CF501A': {
'consolidated': 'CF501A (202A Cyan)',
'compatible_models': ['HP Color LaserJet M254dw'],
'note': 'Uses 202A series, NOT 414A series'
},
'CF502A': {
'consolidated': 'CF502A (202A Magenta)',
'compatible_models': ['HP Color LaserJet M254dw'],
'note': 'Uses 202A series, NOT 414A series'
},
'CF503A': {
'consolidated': 'CF503A (202A Yellow)',
'compatible_models': ['HP Color LaserJet M254dw'],
'note': 'Uses 202A series, NOT 414A series'
},
# HP LaserJet 90A/X family
'CE390A': {
'consolidated': 'CE390A or CE390X (90A/90X)',
'compatible_models': ['HP LaserJet M4555', 'HP LaserJet M602', 'HP LaserJet M603'],
'note': 'Standard yield - compatible across M4555/M602/M603'
},
'CE390X': {
'consolidated': 'CE390A or CE390X (90A/90X)',
'compatible_models': ['HP LaserJet M4555', 'HP LaserJet M602', 'HP LaserJet M603'],
'note': 'High yield - compatible across M4555/M602/M603'
},
# HP LaserJet 42A/X family
'Q5942A': {
'consolidated': 'Q5942A or Q5942X (42A/42X)',
'compatible_models': ['HP LaserJet 4250', 'HP LaserJet 4350'],
'note': 'Standard yield - compatible across 4250/4350'
},
'Q5942X': {
'consolidated': 'Q5942A or Q5942X (42A/42X)',
'compatible_models': ['HP LaserJet 4250', 'HP LaserJet 4350'],
'note': 'High yield - compatible across 4250/4350'
},
# HP LaserJet 55X family
'CE255X': {
'consolidated': 'CE255X (55X)',
'compatible_models': ['HP LaserJet P3015', 'HP LaserJet P3010'],
'note': 'High yield - compatible across P3015/P3010'
},
# Xerox VersaLink C405/C400 series
'106R03536': {
'consolidated': '106R03536 (Black)',
'compatible_models': ['Xerox VersaLink C405', 'Xerox VersaLink C400'],
'note': 'C405 and C400 share identical toner series'
},
'106R03537': {
'consolidated': '106R03537 (Yellow)',
'compatible_models': ['Xerox VersaLink C405', 'Xerox VersaLink C400'],
'note': 'C405 and C400 share identical toner series'
},
'106R03538': {
'consolidated': '106R03538 (Cyan)',
'compatible_models': ['Xerox VersaLink C405', 'Xerox VersaLink C400'],
'note': 'C405 and C400 share identical toner series'
},
'106R03539': {
'consolidated': '106R03539 (Magenta)',
'compatible_models': ['Xerox VersaLink C405', 'Xerox VersaLink C400'],
'note': 'C405 and C400 share identical toner series'
},
# Xerox VersaLink B405/B400 series
'106R03580': {
'consolidated': '106R03580/81/82 (Standard/High/Extra-High)',
'compatible_models': ['Xerox VersaLink B405', 'Xerox VersaLink B400'],
'note': 'B405 and B400 share 106R035xx toner family'
},
'106R03581': {
'consolidated': '106R03580/81/82 (Standard/High/Extra-High)',
'compatible_models': ['Xerox VersaLink B405', 'Xerox VersaLink B400'],
'note': 'B405 and B400 share 106R035xx toner family'
},
'106R03582': {
'consolidated': '106R03580/81/82 (Standard/High/Extra-High)',
'compatible_models': ['Xerox VersaLink B405', 'Xerox VersaLink B400'],
'note': 'B405 and B400 share 106R035xx toner family'
},
}
def get_compatibility_info(part_number_string):
"""
Extract part number and look up compatibility information
Returns consolidated recommendation or original part number
"""
if not part_number_string:
return None
# Extract part number patterns (e.g., "CF258A", "106R03536")
import re
# Look for common HP/Xerox part number patterns
patterns = [
r'([A-Z]{2}\d{3,4}[A-Z]{0,1})', # HP: CF258A, CE390X, etc.
r'(\d{3}R\d{5})', # Xerox: 106R03536, etc.
]
for pattern in patterns:
match = re.search(pattern, part_number_string)
if match:
part_num = match.group(1)
if part_num in SUPPLY_COMPATIBILITY:
compat = SUPPLY_COMPATIBILITY[part_num]
return f"{compat['consolidated']} - {compat['note']}"
# No compatibility info found, return original
return None
# Common preprocessing JavaScript for hex-encoded strings
HEX_PREPROCESSOR = """// Handle hex-encoded SNMP strings
// Try multiple approaches to convert hex to ASCII
// First, check if it looks like hex (with spaces, newlines, or other separators)
var hexPattern = /^[0-9A-Fa-f\\s]+$/;
if (hexPattern.test(value) && value.length > 4) {
// Extract all hex pairs (2 characters)
var hexBytes = value.match(/[0-9A-Fa-f]{2}/g);
if (hexBytes && hexBytes.length > 0) {
var result = '';
for (var i = 0; i < hexBytes.length; i++) {
var code = parseInt(hexBytes[i], 16);
// Only keep printable ASCII (0x20-0x7E)
if (code >= 32 && code <= 126) {
result += String.fromCharCode(code);
}
}
if (result.length > 0) {
return result;
}
}
}
// Fallback: Remove non-printable characters
return value.replace(/[^\\x20-\\x7E]/g, '');"""
# Preprocessing for numeric items that may return -3 (unknown), -2 (unknown), or other negative "special" values
# Per RFC 3805: -1 = other, -2 = unknown, -3 = unknown
# Convert negative values to 0 (indicates empty/problem state)
UNKNOWN_VALUE_PREPROCESSOR = """// Handle SNMP unknown values (-3, -2, etc.)
// Per RFC 3805: -1 = other, -2 = unknown, -3 = unknown
// Convert to 0 to indicate empty/problem state
var numValue = parseInt(value);
if (numValue < 0) {
return '0';
}
return value;"""
# Preprocessing for part number fields - removes serial numbers and firmware info
PART_NUMBER_CLEANER = """// Clean up part number by removing serial numbers and firmware
// Handles formats like:
// "Toner Cartridge;SNACC7952D80730000" -> "Toner Cartridge"
// "Black Cartridge HP 58A (CF258A);FW:V4.23.3" -> "Black Cartridge HP 58A (CF258A)"
// "Drum Cartridge, PN 101R00554;SN2600A90008100000" -> "Drum Cartridge, PN 101R00554"
// First, apply hex conversion if needed
var hexPattern = /^[0-9A-Fa-f\\s]+$/;
if (hexPattern.test(value) && value.length > 4) {
var hexBytes = value.match(/[0-9A-Fa-f]{2}/g);
if (hexBytes && hexBytes.length > 0) {
var result = '';
for (var i = 0; i < hexBytes.length; i++) {
var code = parseInt(hexBytes[i], 16);
if (code >= 32 && code <= 126) {
result += String.fromCharCode(code);
}
}
if (result.length > 0) {
value = result;
}
}
}
// Remove serial numbers (;SN followed by anything)
value = value.replace(/;SN[^;]*/g, '');
// Remove firmware info (;FW: or ;FW followed by anything)
value = value.replace(/;FW[^;]*/g, '');
// Remove any other semicolon-separated metadata
// (but keep the main description before first semicolon)
var parts = value.split(';');
value = parts[0];
// Trim whitespace
value = value.trim();
// For Xerox printers reporting just "Toner Cartridge" without PN,
// try to add known part numbers (must match model-specific logic)
// This is handled by triggers showing compatibility notes instead
return value;"""
# Template configurations
TEMPLATES = {
"hp_mono": {
"name": "HP LaserJet - Monochrome",
"description": "HP LaserJet printers (all models - mono)",
"items": [
# Basic info
{"name": "Printer Model", "key": "printer.model", "oid": "1.3.6.1.2.1.25.3.2.1.3.1", "type": "text"},
{"name": "Printer Hostname", "key": "printer.hostname", "oid": "1.3.6.1.2.1.1.5.0", "type": "text"},
{"name": "Printer Serial Number", "key": "printer.serial", "oid": "1.3.6.1.2.1.43.5.1.1.17.1", "type": "text"},
{"name": "System Location", "key": "printer.location", "oid": "1.3.6.1.2.1.1.6.0", "type": "text"},
# Black toner - Index 1
{"name": "Black Toner Part Number", "key": "printer.cartridge.black", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.1", "type": "text"},
{"name": "Black Toner Current", "key": "printer.toner.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Max", "key": "printer.toner.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Level", "key": "printer.toner.black", "type": "calculated",
"formula": "round((last(//printer.toner.black.current)/last(//printer.toner.black.max))*100,0)",
"units": "%", "part_key": "printer.cartridge.black", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Maintenance kit - Index 2 or HP MIB
{"name": "Maintenance Kit Part Number", "key": "printer.maintenance.model", "oid": "1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.3.0", "type": "text"},
{"name": "Maintenance Kit Remaining", "key": "printer.maintenance.remaining", "oid": "1.3.6.1.4.1.11.2.3.9.4.2.1.4.1.2.0", "type": "numeric", "units": "pages",
"part_key": "printer.maintenance.model", "triggers": [
{"severity": "warning", "threshold": 10000, "expression": "<"},
{"severity": "high", "threshold": 5000, "expression": "<"}
]},
]
},
"hp_color": {
"name": "HP LaserJet - Color",
"description": "HP Color LaserJet printers (all models)",
"items": [
# Basic info
{"name": "Printer Model", "key": "printer.model", "oid": "1.3.6.1.2.1.25.3.2.1.3.1", "type": "text"},
{"name": "Printer Hostname", "key": "printer.hostname", "oid": "1.3.6.1.2.1.1.5.0", "type": "text"},
{"name": "Printer Serial Number", "key": "printer.serial", "oid": "1.3.6.1.2.1.43.5.1.1.17.1", "type": "text"},
{"name": "System Location", "key": "printer.location", "oid": "1.3.6.1.2.1.1.6.0", "type": "text"},
# Toner cartridges - Indices 1-4
{"name": "Black Toner Part Number", "key": "printer.cartridge.black", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.1", "type": "text"},
{"name": "Black Toner Current", "key": "printer.toner.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Max", "key": "printer.toner.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Level", "key": "printer.toner.black", "type": "calculated",
"formula": "round((last(//printer.toner.black.current)/last(//printer.toner.black.max))*100,0)",
"units": "%", "color": "black", "part_key": "printer.cartridge.black", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Cyan Toner Part Number", "key": "printer.cartridge.cyan", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.2", "type": "text"},
{"name": "Cyan Toner Current", "key": "printer.toner.cyan.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Max", "key": "printer.toner.cyan.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Level", "key": "printer.toner.cyan", "type": "calculated",
"formula": "round((last(//printer.toner.cyan.current)/last(//printer.toner.cyan.max))*100,0)",
"units": "%", "color": "cyan", "part_key": "printer.cartridge.cyan", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Magenta Toner Part Number", "key": "printer.cartridge.magenta", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.3", "type": "text"},
{"name": "Magenta Toner Current", "key": "printer.toner.magenta.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Max", "key": "printer.toner.magenta.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Level", "key": "printer.toner.magenta", "type": "calculated",
"formula": "round((last(//printer.toner.magenta.current)/last(//printer.toner.magenta.max))*100,0)",
"units": "%", "color": "magenta", "part_key": "printer.cartridge.magenta", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Yellow Toner Part Number", "key": "printer.cartridge.yellow", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.4", "type": "text"},
{"name": "Yellow Toner Current", "key": "printer.toner.yellow.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Max", "key": "printer.toner.yellow.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Level", "key": "printer.toner.yellow", "type": "calculated",
"formula": "round((last(//printer.toner.yellow.current)/last(//printer.toner.yellow.max))*100,0)",
"units": "%", "color": "yellow", "part_key": "printer.cartridge.yellow", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
]
},
"xerox_color": {
"name": "Xerox VersaLink - Color",
"description": "Xerox VersaLink Color multifunction printers",
"items": [
# Basic info
{"name": "Printer Model", "key": "printer.model", "oid": "1.3.6.1.2.1.25.3.2.1.3.1", "type": "text"},
{"name": "Printer Hostname", "key": "printer.hostname", "oid": "1.3.6.1.2.1.1.5.0", "type": "text"},
{"name": "Printer Serial Number", "key": "printer.serial", "oid": "1.3.6.1.2.1.43.5.1.1.17.1", "type": "text"},
{"name": "System Location", "key": "printer.location", "oid": "1.3.6.1.2.1.1.6.0", "type": "text"},
# Toner cartridges - Indices 1-4
{"name": "Black Toner Part Number", "key": "printer.toner.black.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.1", "type": "text"},
{"name": "Black Toner Current", "key": "printer.toner.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Max", "key": "printer.toner.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Level", "key": "printer.toner.black", "type": "calculated",
"formula": "round((last(//printer.toner.black.current)/last(//printer.toner.black.max))*100,0)",
"units": "%", "color": "black", "part_key": "printer.toner.black.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Yellow Toner Part Number", "key": "printer.toner.yellow.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.2", "type": "text"},
{"name": "Yellow Toner Current", "key": "printer.toner.yellow.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Max", "key": "printer.toner.yellow.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Level", "key": "printer.toner.yellow", "type": "calculated",
"formula": "round((last(//printer.toner.yellow.current)/last(//printer.toner.yellow.max))*100,0)",
"units": "%", "color": "yellow", "part_key": "printer.toner.yellow.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Magenta Toner Part Number", "key": "printer.toner.magenta.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.3", "type": "text"},
{"name": "Magenta Toner Current", "key": "printer.toner.magenta.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Max", "key": "printer.toner.magenta.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Level", "key": "printer.toner.magenta", "type": "calculated",
"formula": "round((last(//printer.toner.magenta.current)/last(//printer.toner.magenta.max))*100,0)",
"units": "%", "color": "magenta", "part_key": "printer.toner.magenta.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Cyan Toner Part Number", "key": "printer.toner.cyan.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.4", "type": "text"},
{"name": "Cyan Toner Current", "key": "printer.toner.cyan.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Max", "key": "printer.toner.cyan.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Level", "key": "printer.toner.cyan", "type": "calculated",
"formula": "round((last(//printer.toner.cyan.current)/last(//printer.toner.cyan.max))*100,0)",
"units": "%", "color": "cyan", "part_key": "printer.toner.cyan.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Waste cartridge - Index 5
{"name": "Waste Cartridge Part Number", "key": "printer.waste.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.5", "type": "text"},
{"name": "Waste Cartridge Level", "key": "printer.waste.level", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.5", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.waste.part", "triggers": [
{"severity": "warning", "threshold": 80, "expression": ">"},
{"severity": "high", "threshold": 90, "expression": ">"}
]},
# Drum cartridges - Indices 6-9
{"name": "Black Drum Part Number", "key": "printer.drum.black.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.6", "type": "text"},
{"name": "Black Drum Current", "key": "printer.drum.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.6", "type": "numeric", "can_be_unknown": True},
{"name": "Black Drum Max", "key": "printer.drum.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.6", "type": "numeric", "can_be_unknown": True},
{"name": "Black Drum Level", "key": "printer.drum.black", "type": "calculated",
"formula": "round((last(//printer.drum.black.current)/last(//printer.drum.black.max))*100,0)",
"units": "%", "part_key": "printer.drum.black.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Yellow Drum Part Number", "key": "printer.drum.yellow.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.7", "type": "text"},
{"name": "Yellow Drum Current", "key": "printer.drum.yellow.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.7", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Drum Max", "key": "printer.drum.yellow.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.7", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Drum Level", "key": "printer.drum.yellow", "type": "calculated",
"formula": "round((last(//printer.drum.yellow.current)/last(//printer.drum.yellow.max))*100,0)",
"units": "%", "part_key": "printer.drum.yellow.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Magenta Drum Part Number", "key": "printer.drum.magenta.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.8", "type": "text"},
{"name": "Magenta Drum Current", "key": "printer.drum.magenta.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.8", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Drum Max", "key": "printer.drum.magenta.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.8", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Drum Level", "key": "printer.drum.magenta", "type": "calculated",
"formula": "round((last(//printer.drum.magenta.current)/last(//printer.drum.magenta.max))*100,0)",
"units": "%", "part_key": "printer.drum.magenta.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Cyan Drum Part Number", "key": "printer.drum.cyan.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.9", "type": "text"},
{"name": "Cyan Drum Current", "key": "printer.drum.cyan.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.9", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Drum Max", "key": "printer.drum.cyan.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.9", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Drum Level", "key": "printer.drum.cyan", "type": "calculated",
"formula": "round((last(//printer.drum.cyan.current)/last(//printer.drum.cyan.max))*100,0)",
"units": "%", "part_key": "printer.drum.cyan.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Transfer components - Indices 10-11
{"name": "Transfer Roller Part Number", "key": "printer.transfer.roller.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.10", "type": "text"},
{"name": "Transfer Belt Part Number", "key": "printer.transfer.belt.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.11", "type": "text"},
# Fuser - Index 12
{"name": "Fuser Part Number", "key": "printer.fuser.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.12", "type": "text"},
]
},
"xerox_enterprise": {
"name": "Xerox Enterprise - Color",
"description": "Xerox EC8036, AltaLink C8xxx enterprise color printers",
"items": [
# Basic info
{"name": "Printer Model", "key": "printer.model", "oid": "1.3.6.1.2.1.25.3.2.1.3.1", "type": "text"},
{"name": "Printer Hostname", "key": "printer.hostname", "oid": "1.3.6.1.2.1.1.5.0", "type": "text"},
{"name": "Printer Serial Number", "key": "printer.serial", "oid": "1.3.6.1.2.1.43.5.1.1.17.1", "type": "text"},
{"name": "System Location", "key": "printer.location", "oid": "1.3.6.1.2.1.1.6.0", "type": "text"},
# Toner cartridges - Indices 1-4
{"name": "Black Toner Part Number", "key": "printer.toner.black.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.1", "type": "text"},
{"name": "Black Toner Current", "key": "printer.toner.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Max", "key": "printer.toner.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Black Toner Level", "key": "printer.toner.black", "type": "calculated",
"formula": "round((last(//printer.toner.black.current)/last(//printer.toner.black.max))*100,0)",
"units": "%", "color": "black", "part_key": "printer.toner.black.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Cyan Toner Part Number", "key": "printer.toner.cyan.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.2", "type": "text"},
{"name": "Cyan Toner Current", "key": "printer.toner.cyan.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Max", "key": "printer.toner.cyan.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.2", "type": "numeric", "can_be_unknown": True},
{"name": "Cyan Toner Level", "key": "printer.toner.cyan", "type": "calculated",
"formula": "round((last(//printer.toner.cyan.current)/last(//printer.toner.cyan.max))*100,0)",
"units": "%", "color": "cyan", "part_key": "printer.toner.cyan.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Magenta Toner Part Number", "key": "printer.toner.magenta.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.3", "type": "text"},
{"name": "Magenta Toner Current", "key": "printer.toner.magenta.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Max", "key": "printer.toner.magenta.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.3", "type": "numeric", "can_be_unknown": True},
{"name": "Magenta Toner Level", "key": "printer.toner.magenta", "type": "calculated",
"formula": "round((last(//printer.toner.magenta.current)/last(//printer.toner.magenta.max))*100,0)",
"units": "%", "color": "magenta", "part_key": "printer.toner.magenta.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Yellow Toner Part Number", "key": "printer.toner.yellow.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.4", "type": "text"},
{"name": "Yellow Toner Current", "key": "printer.toner.yellow.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Max", "key": "printer.toner.yellow.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.4", "type": "numeric", "can_be_unknown": True},
{"name": "Yellow Toner Level", "key": "printer.toner.yellow", "type": "calculated",
"formula": "round((last(//printer.toner.yellow.current)/last(//printer.toner.yellow.max))*100,0)",
"units": "%", "color": "yellow", "part_key": "printer.toner.yellow.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Drum cartridges - Indices 5-8 (percentage-based)
{"name": "Drum Cartridge R1 Part Number", "key": "printer.drum.r1.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.5", "type": "text"},
{"name": "Drum Cartridge R1 Level", "key": "printer.drum.r1", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.5", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.drum.r1.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Drum Cartridge R2 Part Number", "key": "printer.drum.r2.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.6", "type": "text"},
{"name": "Drum Cartridge R2 Level", "key": "printer.drum.r2", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.6", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.drum.r2.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Drum Cartridge R3 Part Number", "key": "printer.drum.r3.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.7", "type": "text"},
{"name": "Drum Cartridge R3 Level", "key": "printer.drum.r3", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.7", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.drum.r3.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Drum Cartridge R4 Part Number", "key": "printer.drum.r4.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.8", "type": "text"},
{"name": "Drum Cartridge R4 Level", "key": "printer.drum.r4", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.8", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.drum.r4.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Fuser - Index 9
{"name": "Fuser Part Number", "key": "printer.fuser.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.9", "type": "text"},
{"name": "Fuser Level", "key": "printer.fuser", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.9", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.fuser.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Waste container - Index 10
{"name": "Waste Container Part Number", "key": "printer.waste.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.10", "type": "text"},
{"name": "Waste Container Level", "key": "printer.waste", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.10", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.waste.part", "triggers": [
{"severity": "warning", "threshold": 80, "expression": ">"},
{"severity": "high", "threshold": 90, "expression": ">"}
]},
# Transfer components - Indices 11-12
{"name": "Transfer Belt Cleaner Part Number", "key": "printer.transfer.belt.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.11", "type": "text"},
{"name": "Transfer Belt Cleaner Level", "key": "printer.transfer.belt", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.11", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.transfer.belt.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
{"name": "Second Bias Transfer Roll Part Number", "key": "printer.transfer.roller.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.12", "type": "text"},
{"name": "Second Bias Transfer Roll Level", "key": "printer.transfer.roller", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.12", "type": "numeric", "units": "%",
"can_be_unknown": True, "part_key": "printer.transfer.roller.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
]
},
"xerox_mono": {
"name": "Xerox VersaLink - Monochrome",
"description": "Xerox VersaLink B&W multifunction printers",
"items": [
# Basic info
{"name": "Printer Model", "key": "printer.model", "oid": "1.3.6.1.2.1.25.3.2.1.3.1", "type": "text"},
{"name": "Printer Hostname", "key": "printer.hostname", "oid": "1.3.6.1.2.1.1.5.0", "type": "text"},
{"name": "Printer Serial Number", "key": "printer.serial", "oid": "1.3.6.1.2.1.43.5.1.1.17.1", "type": "text"},
{"name": "System Location", "key": "printer.location", "oid": "1.3.6.1.2.1.1.6.0", "type": "text"},
# Toner cartridge - Index 1
{"name": "Toner Part Number", "key": "printer.toner.black.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.1", "type": "text"},
{"name": "Toner Current", "key": "printer.toner.black.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Toner Max", "key": "printer.toner.black.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.1", "type": "numeric", "can_be_unknown": True},
{"name": "Toner Level", "key": "printer.toner.black", "type": "calculated",
"formula": "round((last(//printer.toner.black.current)/last(//printer.toner.black.max))*100,0)",
"units": "%", "part_key": "printer.toner.black.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Drum cartridge - Index 6
{"name": "Drum Part Number", "key": "printer.drum.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.6", "type": "text"},
{"name": "Drum Current", "key": "printer.drum.current", "oid": "1.3.6.1.2.1.43.11.1.1.9.1.6", "type": "numeric", "can_be_unknown": True},
{"name": "Drum Max", "key": "printer.drum.max", "oid": "1.3.6.1.2.1.43.11.1.1.8.1.6", "type": "numeric", "can_be_unknown": True},
{"name": "Drum Level", "key": "printer.drum", "type": "calculated",
"formula": "round((last(//printer.drum.current)/last(//printer.drum.max))*100,0)",
"units": "%", "part_key": "printer.drum.part", "triggers": [
{"severity": "warning", "threshold": 20, "expression": "<"},
{"severity": "high", "threshold": 10, "expression": "<"}
]},
# Transfer roller - Index 10
{"name": "Transfer Roller Part Number", "key": "printer.transfer.roller.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.10", "type": "text"},
# Fuser - Index 12
{"name": "Fuser Part Number", "key": "printer.fuser.part", "oid": "1.3.6.1.2.1.43.11.1.1.6.1.12", "type": "text"},
]
}
}
def create_zabbix_item(item_def, template_name):
"""Create a Zabbix item from definition"""
if item_def['type'] == 'calculated':
# Calculated item
zabbix_item = {
"uuid": uuid.uuid4().hex,
"name": item_def['name'],
"type": "CALCULATED",
"key": item_def['key'],
"delay": "1h",
"history": "90d",
"trends": "365d",
"value_type": "FLOAT",
"params": item_def['formula'],
"description": item_def.get('description', item_def['name']),
"tags": [
{"tag": "component", "value": "supplies"},
{"tag": "type", "value": "level"}
]
}
if 'color' in item_def:
zabbix_item['tags'].append({"tag": "color", "value": item_def['color']})
else:
# SNMP item
zabbix_item = {
"uuid": uuid.uuid4().hex,
"name": item_def['name'],
"type": "SNMP_AGENT",
"snmp_oid": f"get[{item_def['oid']}]",
"key": item_def['key'],
"delay": "1h",
"history": "90d",
"trends": "365d" if item_def['type'] == 'numeric' else "0d",
"value_type": "TEXT" if item_def['type'] == 'text' else "FLOAT",
"description": item_def.get('description', item_def['name']),
"tags": [
{"tag": "component", "value": "printer"},
{"tag": "type", "value": "info" if item_def['type'] == 'text' else "raw"}
]
}
# Add preprocessing for text items
if item_def['type'] == 'text':
# Use part number cleaner for items with "Part Number" in the name
if 'Part Number' in item_def['name'] or 'part' in item_def.get('key', ''):
zabbix_item['preprocessing'] = [
{
"type": "JAVASCRIPT",
"parameters": [PART_NUMBER_CLEANER]
}
]
else:
# Use hex preprocessor for other text items
zabbix_item['preprocessing'] = [
{
"type": "JAVASCRIPT",
"parameters": [HEX_PREPROCESSOR]
}
]
# Add preprocessing for numeric items that can report unknown values
# This applies to items marked with 'can_be_unknown' flag
if item_def['type'] == 'numeric' and item_def.get('can_be_unknown', False):
zabbix_item['preprocessing'] = [
{
"type": "JAVASCRIPT",
"parameters": [UNKNOWN_VALUE_PREPROCESSOR]
}
]
# Add units if specified
if 'units' in item_def:
zabbix_item['units'] = item_def['units']
# Add triggers if specified
if 'triggers' in item_def:
zabbix_item['triggers'] = []
for trigger_def in item_def['triggers']:
severity_map = {"warning": "WARNING", "high": "HIGH", "average": "AVERAGE"}
# Build expression
expression = f"last(/{template_name}/{item_def['key']}){trigger_def['expression']}{trigger_def['threshold']}"
# Add part number check if specified
description = f"{item_def['name']} is {'high' if trigger_def['expression'] == '>' else 'low'} on {{{{HOST.NAME}}}}"
if 'part_key' in item_def:
expression += f" and length(last(/{template_name}/{item_def['part_key']}))>0"
# Check if we have compatibility info for common parts
# This will be displayed in the trigger description to help with ordering
part_recommendation = "{{ITEM.LASTVALUE2}}"
# Add note about checking compatibility table for alternatives
description += f". Current level: {{{{ITEM.LASTVALUE}}}}. Replacement part: {part_recommendation}"
description += " (See compatibility notes for potential alternatives)"
trigger = {
"uuid": uuid.uuid4().hex,
"expression": expression,
"name": description,
"priority": severity_map.get(trigger_def['severity'], "WARNING"),
"tags": [{"tag": "scope", "value": "availability"}]
}
zabbix_item['triggers'].append(trigger)
return zabbix_item
def generate_template(template_key):
"""Generate a complete Zabbix template"""
config = TEMPLATES[template_key]
template = {
"zabbix_export": {
"version": "7.4",
"template_groups": [
{
"uuid": "3cd4e8d0b828464e8f4b3becf13a9dbd",
"name": "Printers"
}
],
"templates": [
{
"uuid": uuid.uuid4().hex,
"template": config['name'],
"name": config['name'],
"description": config['description'],
"groups": [{"name": "Printers"}],
"items": []
}
]
}
}
# Add all items
for item_def in config['items']:
zabbix_item = create_zabbix_item(item_def, config['name'])
template["zabbix_export"]["templates"][0]["items"].append(zabbix_item)
return template
def main():
"""Generate all templates"""
print("=" * 100)
print("GENERATING ZABBIX PRINTER TEMPLATES")
print("=" * 100)
for template_key in TEMPLATES.keys():
config = TEMPLATES[template_key]
print(f"\nGenerating: {config['name']}")
print(f"Description: {config['description']}")
print(f"Items: {len(config['items'])}")
template = generate_template(template_key)
# Save YAML
yaml_filename = f"zabbix_template_{template_key}.yaml"
yaml_output = yaml.dump(template, default_flow_style=False, sort_keys=False, allow_unicode=True, width=1000)
with open(yaml_filename, 'w') as f:
f.write(yaml_output)
print(f" ✓ Saved: {yaml_filename}")
# Save JSON
json_filename = f"zabbix_template_{template_key}.json"
json_output = json.dumps(template, indent=2)
with open(json_filename, 'w') as f:
f.write(json_output)
print(f" ✓ Saved: {json_filename}")
print("\n" + "=" * 100)
print("TEMPLATE USAGE GUIDE")
print("=" * 100)
print("\n1. HP LaserJet - Monochrome")
print(" Use for: HP LaserJet Pro 4xxx, M4xx, M6xx (B&W models)")
print(" Monitors: Black toner, Maintenance kit")
print()
print("2. HP LaserJet - Color")
print(" Use for: HP Color LaserJet Pro, M4xx, M2xx (Color models)")
print(" Monitors: Black/Cyan/Magenta/Yellow toner")
print()
print("3. Xerox VersaLink - Color")
print(" Use for: Xerox VersaLink C7xxx, C4xxx (Color MFPs)")
print(" Monitors: 4 toners, 4 drums, waste, transfer components, fuser")
print()
print("4. Xerox VersaLink - Monochrome")
print(" Use for: Xerox VersaLink B7xxx, B4xxx (B&W MFPs)")
print(" Monitors: Toner, drum, transfer roller, fuser")
print()
print("5. Xerox Enterprise - Color")
print(" Use for: Xerox EC8036, AltaLink C8xxx (Enterprise Color MFPs)")
print(" Monitors: 4 toners, 4 drums, fuser, waste, 2 transfer components (all percentage-based)")
print()
print("\n" + "=" * 100)
print("IMPORT INSTRUCTIONS")
print("=" * 100)
print("\n1. In Zabbix web UI: Configuration → Templates → Import")
print("2. Select the appropriate YAML or JSON file for each printer type")
print("3. Link template to printer hosts")
print("4. Configure SNMP interface:")
print(" - Port: 161")
print(" - SNMP version: SNMPv2")
print(" - Community: WestJeff2025")
print()
if __name__ == "__main__":
main()