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>
684 lines
27 KiB
Python
684 lines
27 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generate Zabbix SNMP Item Configuration
|
|
Creates Zabbix item definitions for printer monitoring
|
|
Includes: Toner, Maintenance Kit, Fuser, Drums, Waste
|
|
"""
|
|
|
|
import json
|
|
import uuid
|
|
import yaml
|
|
|
|
# Zabbix SNMP items configuration for HP & Xerox printers
|
|
ZABBIX_ITEMS = {
|
|
"printer_info": [
|
|
{
|
|
"name": "Printer Model",
|
|
"key": "printer.model",
|
|
"oid": "1.3.6.1.2.1.25.3.2.1.3.1",
|
|
"type": "text",
|
|
"description": "Device model information"
|
|
},
|
|
{
|
|
"name": "Printer Hostname",
|
|
"key": "printer.hostname",
|
|
"oid": "1.3.6.1.2.1.1.5.0",
|
|
"type": "text",
|
|
"description": "System hostname"
|
|
},
|
|
{
|
|
"name": "Printer Serial Number",
|
|
"key": "printer.serial",
|
|
"oid": "1.3.6.1.2.1.43.5.1.1.17.1",
|
|
"type": "text",
|
|
"description": "Printer serial number"
|
|
},
|
|
{
|
|
"name": "System Location",
|
|
"key": "printer.location",
|
|
"oid": "1.3.6.1.2.1.1.6.0",
|
|
"type": "text",
|
|
"description": "Physical location"
|
|
},
|
|
{
|
|
"name": "MAC Address",
|
|
"key": "printer.macaddress",
|
|
"oid": "1.3.6.1.2.1.2.2.1.6.2",
|
|
"type": "text",
|
|
"description": "Primary network interface MAC address"
|
|
}
|
|
],
|
|
"toner_levels": [
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Black toner current level (raw value)"
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Black toner maximum capacity"
|
|
},
|
|
{
|
|
"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": "%",
|
|
"description": "Black toner percentage",
|
|
"color": "black",
|
|
"is_percentage": True,
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Cyan toner current level (raw value)"
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Cyan toner maximum capacity"
|
|
},
|
|
{
|
|
"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": "%",
|
|
"description": "Cyan toner percentage",
|
|
"color": "cyan",
|
|
"is_percentage": True,
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Magenta toner current level (raw value)"
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Magenta toner maximum capacity"
|
|
},
|
|
{
|
|
"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": "%",
|
|
"description": "Magenta toner percentage",
|
|
"color": "magenta",
|
|
"is_percentage": True,
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Yellow toner current level (raw value)"
|
|
},
|
|
{
|
|
"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_unsigned",
|
|
"units": "",
|
|
"description": "Yellow toner maximum capacity"
|
|
},
|
|
{
|
|
"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": "%",
|
|
"description": "Yellow toner percentage",
|
|
"color": "yellow",
|
|
"is_percentage": True,
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
}
|
|
],
|
|
"cartridge_info": [
|
|
{
|
|
"name": "Black Cartridge Part Number",
|
|
"key": "printer.cartridge.black",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.1",
|
|
"type": "text",
|
|
"description": "Black toner cartridge model/part number"
|
|
},
|
|
{
|
|
"name": "Cyan Cartridge Part Number",
|
|
"key": "printer.cartridge.cyan",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.2",
|
|
"type": "text",
|
|
"description": "Cyan toner cartridge model/part number"
|
|
},
|
|
{
|
|
"name": "Magenta Cartridge Part Number",
|
|
"key": "printer.cartridge.magenta",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.3",
|
|
"type": "text",
|
|
"description": "Magenta toner cartridge model/part number"
|
|
},
|
|
{
|
|
"name": "Yellow Cartridge Part Number",
|
|
"key": "printer.cartridge.yellow",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.4",
|
|
"type": "text",
|
|
"description": "Yellow toner cartridge model/part number"
|
|
}
|
|
],
|
|
"other_supplies": [
|
|
# Drum Cartridge R1
|
|
{
|
|
"name": "Drum Cartridge R1 Part Number",
|
|
"key": "printer.drum.r1",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.5",
|
|
"type": "text",
|
|
"description": "Drum cartridge R1 part number"
|
|
},
|
|
{
|
|
"name": "Drum Cartridge R1 Level",
|
|
"key": "printer.drum.r1.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.5",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Drum cartridge R1 remaining life percentage",
|
|
"part_number_item": "printer.drum.r1",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
# Drum Cartridge R2
|
|
{
|
|
"name": "Drum Cartridge R2 Part Number",
|
|
"key": "printer.drum.r2",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.6",
|
|
"type": "text",
|
|
"description": "Drum cartridge R2 part number"
|
|
},
|
|
{
|
|
"name": "Drum Cartridge R2 Level",
|
|
"key": "printer.drum.r2.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.6",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Drum cartridge R2 remaining life percentage",
|
|
"part_number_item": "printer.drum.r2",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
# Drum Cartridge R3
|
|
{
|
|
"name": "Drum Cartridge R3 Part Number",
|
|
"key": "printer.drum.r3",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.7",
|
|
"type": "text",
|
|
"description": "Drum cartridge R3 part number"
|
|
},
|
|
{
|
|
"name": "Drum Cartridge R3 Level",
|
|
"key": "printer.drum.r3.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.7",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Drum cartridge R3 remaining life percentage",
|
|
"part_number_item": "printer.drum.r3",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
# Drum Cartridge R4
|
|
{
|
|
"name": "Drum Cartridge R4 Part Number",
|
|
"key": "printer.drum.r4",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.8",
|
|
"type": "text",
|
|
"description": "Drum cartridge R4 part number"
|
|
},
|
|
{
|
|
"name": "Drum Cartridge R4 Level",
|
|
"key": "printer.drum.r4.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.8",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Drum cartridge R4 remaining life percentage",
|
|
"part_number_item": "printer.drum.r4",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
# Waste Toner Container
|
|
{
|
|
"name": "Waste Toner Container Part Number",
|
|
"key": "printer.waste.partnumber",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.9",
|
|
"type": "text",
|
|
"description": "Waste toner container part number"
|
|
},
|
|
{
|
|
"name": "Waste Toner Container Level",
|
|
"key": "printer.waste.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.9",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Waste toner container fill level (higher is more full)",
|
|
"part_number_item": "printer.waste.partnumber",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 80, "expression": ">"},
|
|
{"severity": "high", "threshold": 90, "expression": ">"}
|
|
]
|
|
},
|
|
# Transfer Belt Cleaner
|
|
{
|
|
"name": "Transfer Belt Cleaner Part Number",
|
|
"key": "printer.transfer.belt",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.10",
|
|
"type": "text",
|
|
"description": "Transfer belt cleaner part number"
|
|
},
|
|
{
|
|
"name": "Transfer Belt Cleaner Level",
|
|
"key": "printer.transfer.belt.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.10",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Transfer belt cleaner remaining life percentage",
|
|
"part_number_item": "printer.transfer.belt",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
},
|
|
# Second Bias Transfer Roll
|
|
{
|
|
"name": "Second Bias Transfer Roll Part Number",
|
|
"key": "printer.transfer.roller",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.6.1.11",
|
|
"type": "text",
|
|
"description": "Second bias transfer roll part number"
|
|
},
|
|
{
|
|
"name": "Second Bias Transfer Roll Level",
|
|
"key": "printer.transfer.roller.level",
|
|
"oid": "1.3.6.1.2.1.43.11.1.1.9.1.11",
|
|
"type": "numeric_unsigned",
|
|
"units": "%",
|
|
"description": "Second bias transfer roll remaining life percentage",
|
|
"part_number_item": "printer.transfer.roller",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 20, "expression": "<"},
|
|
{"severity": "high", "threshold": 10, "expression": "<"}
|
|
]
|
|
}
|
|
],
|
|
"maintenance_kit_hp": [
|
|
{
|
|
"name": "Maintenance Kit Model (HP)",
|
|
"key": "printer.maintenance.model",
|
|
"oid": "1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.3.0",
|
|
"type": "text",
|
|
"description": "HP maintenance kit model/serial number"
|
|
},
|
|
{
|
|
"name": "Maintenance Kit Remaining (HP)",
|
|
"key": "printer.maintenance.remaining",
|
|
"oid": "1.3.6.1.4.1.11.2.3.9.4.2.1.4.1.2.0",
|
|
"type": "numeric_unsigned",
|
|
"units": "pages",
|
|
"description": "HP maintenance kit remaining pages",
|
|
"part_number_item": "printer.maintenance.model",
|
|
"triggers": [
|
|
{"severity": "warning", "threshold": 10000, "expression": "<"},
|
|
{"severity": "high", "threshold": 5000, "expression": "<"}
|
|
]
|
|
},
|
|
{
|
|
"name": "Printer Model (HP MIB)",
|
|
"key": "printer.maintenance.printer_model",
|
|
"oid": "1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.2.0",
|
|
"type": "text",
|
|
"description": "Printer model from HP maintenance MIB"
|
|
}
|
|
],
|
|
"supply_capacity": [
|
|
{
|
|
"name": "Supply 1 Max Capacity",
|
|
"key": "printer.supply.1.max",
|
|
"oid": "1.3.6.1.2.1.43.10.2.1.4.1.1",
|
|
"type": "numeric_unsigned",
|
|
"description": "Maximum capacity for supply index 1 (usually black)"
|
|
},
|
|
{
|
|
"name": "Supply 1 Current Level",
|
|
"key": "printer.supply.1.current",
|
|
"oid": "1.3.6.1.2.1.43.10.2.1.9.1.1",
|
|
"type": "numeric_unsigned",
|
|
"description": "Current level for supply index 1 (usually black)"
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
def generate_zabbix_cli_commands():
|
|
"""
|
|
Generate Zabbix CLI commands for adding SNMP items
|
|
"""
|
|
print("=" * 80)
|
|
print("ZABBIX SNMP ITEM CONFIGURATION")
|
|
print("=" * 80)
|
|
print("\nThese commands can be used in Zabbix CLI or adapted for the web interface.\n")
|
|
|
|
for category, items in ZABBIX_ITEMS.items():
|
|
print(f"\n## {category.replace('_', ' ').title()}")
|
|
print("-" * 80)
|
|
|
|
for item in items:
|
|
print(f"\n### {item['name']}")
|
|
if 'oid' in item:
|
|
print(f"OID: {item['oid']}")
|
|
if 'formula' in item:
|
|
print(f"Formula: {item['formula']}")
|
|
print(f"Key: {item['key']}")
|
|
print(f"Type: {item['type']}")
|
|
if 'units' in item:
|
|
print(f"Units: {item['units']}")
|
|
print(f"Description: {item['description']}")
|
|
|
|
if 'triggers' in item:
|
|
print(f"\nRecommended Triggers:")
|
|
for trigger in item['triggers']:
|
|
print(f" - {trigger['severity'].upper()}: "
|
|
f"{item['name']} {trigger['expression']} {trigger['threshold']}{item.get('units', '')}")
|
|
|
|
print()
|
|
|
|
|
|
def generate_zabbix_import_json():
|
|
"""
|
|
Generate a Zabbix 7.4 importable JSON template
|
|
Note: Zabbix requires UUIDs to be 32 characters without hyphens
|
|
"""
|
|
template = {
|
|
"zabbix_export": {
|
|
"version": "7.4",
|
|
"template_groups": [
|
|
{
|
|
"uuid": "3cd4e8d0b828464e8f4b3becf13a9dbd",
|
|
"name": "Printers"
|
|
}
|
|
],
|
|
"templates": [
|
|
{
|
|
"uuid": uuid.uuid4().hex,
|
|
"template": "Printer SNMP Monitor",
|
|
"name": "Printer SNMP Monitor",
|
|
"groups": [
|
|
{
|
|
"name": "Printers"
|
|
}
|
|
],
|
|
"items": []
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
# Build items list with Zabbix 7.4 format
|
|
for category, items in ZABBIX_ITEMS.items():
|
|
for item in items:
|
|
# Handle calculated items differently
|
|
if item['type'] == 'calculated':
|
|
# Only add component:toner and color tags if this is a percentage item
|
|
is_percentage = item.get('is_percentage', False)
|
|
|
|
zabbix_item = {
|
|
"uuid": uuid.uuid4().hex,
|
|
"name": item['name'],
|
|
"type": "CALCULATED",
|
|
"key": item['key'],
|
|
"delay": "1h",
|
|
"history": "90d",
|
|
"trends": "365d",
|
|
"value_type": "FLOAT",
|
|
"params": item['formula'],
|
|
"description": item['description'],
|
|
"tags": [
|
|
{
|
|
"tag": "component",
|
|
"value": "toner" if is_percentage else "printer"
|
|
},
|
|
{
|
|
"tag": "category",
|
|
"value": category
|
|
}
|
|
]
|
|
}
|
|
|
|
# Add color tag only for toner percentage items
|
|
if is_percentage and 'color' in item:
|
|
zabbix_item['tags'].append({
|
|
"tag": "color",
|
|
"value": item['color']
|
|
})
|
|
else:
|
|
# Use get[OID] for better performance in Zabbix 7.4
|
|
snmp_oid = f"get[{item['oid']}]"
|
|
|
|
zabbix_item = {
|
|
"uuid": uuid.uuid4().hex,
|
|
"name": item['name'],
|
|
"type": "SNMP_AGENT",
|
|
"snmp_oid": snmp_oid,
|
|
"key": item['key'],
|
|
"delay": "1h",
|
|
"history": "90d",
|
|
"trends": "365d" if item['type'] != 'text' else "0d",
|
|
"value_type": "TEXT" if item['type'] == 'text' else "FLOAT",
|
|
"description": item['description'],
|
|
"tags": [
|
|
{
|
|
"tag": "component",
|
|
"value": "printer"
|
|
},
|
|
{
|
|
"tag": "category",
|
|
"value": category
|
|
}
|
|
]
|
|
}
|
|
|
|
# Add inventory mapping for specific items
|
|
if item['key'] == 'printer.model':
|
|
zabbix_item['inventory_link'] = 'MODEL'
|
|
elif item['key'] == 'printer.serial':
|
|
zabbix_item['inventory_link'] = 'SERIALNO_A'
|
|
elif item['key'] == 'printer.hostname':
|
|
zabbix_item['inventory_link'] = 'NAME'
|
|
elif item['key'] == 'printer.macaddress':
|
|
zabbix_item['inventory_link'] = 'MACADDRESS_A'
|
|
|
|
# Add preprocessing for text items to handle hex-encoded strings
|
|
# Some SNMP values come as hex strings like "FD E8 48 50 20 4C 61..."
|
|
# or as binary with control chars like "ýèHP LaserJet"
|
|
if item['type'] == 'text':
|
|
zabbix_item['preprocessing'] = [
|
|
{
|
|
"type": "JAVASCRIPT",
|
|
"parameters": [
|
|
"// Handle hex-encoded SNMP strings\n// Try multiple approaches to convert hex to ASCII\n\n// First, check if it looks like hex (with spaces, newlines, or other separators)\nvar hexPattern = /^[0-9A-Fa-f\\s]+$/;\nif (hexPattern.test(value) && value.length > 4) {\n // Extract all hex pairs (2 characters)\n var hexBytes = value.match(/[0-9A-Fa-f]{2}/g);\n if (hexBytes && hexBytes.length > 0) {\n var result = '';\n for (var i = 0; i < hexBytes.length; i++) {\n var code = parseInt(hexBytes[i], 16);\n // Only keep printable ASCII (0x20-0x7E)\n if (code >= 32 && code <= 126) {\n result += String.fromCharCode(code);\n }\n }\n if (result.length > 0) {\n return result;\n }\n }\n}\n\n// Fallback: Remove non-printable characters\nreturn value.replace(/[^\\x20-\\x7E]/g, '');"
|
|
]
|
|
}
|
|
]
|
|
|
|
if 'units' in item:
|
|
zabbix_item['units'] = item['units']
|
|
|
|
# Add triggers if defined - nested inside the item
|
|
if 'triggers' in item:
|
|
zabbix_item['triggers'] = []
|
|
for trigger_def in item['triggers']:
|
|
severity_map = {
|
|
"warning": "WARNING",
|
|
"high": "HIGH",
|
|
"average": "AVERAGE"
|
|
}
|
|
|
|
template_name = template['zabbix_export']['templates'][0]['template']
|
|
|
|
# Build description and expression with part number reference
|
|
description = f"{item['name']} has dropped below {trigger_def['threshold']}{item.get('units', '')}"
|
|
|
|
# Build base expression
|
|
expression = f"last(/{template_name}/{item['key']}){trigger_def['expression']}{trigger_def['threshold']}"
|
|
|
|
# Add replacement part reference for toner items
|
|
# We need to add the part number item to the expression so we can reference it with {ITEM.LASTVALUE2}
|
|
if 'color' in item and category == "toner_levels":
|
|
color = item['color'].lower()
|
|
part_key = f"printer.cartridge.{color}"
|
|
# Add the part number item to the expression using "and" so it's evaluated but doesn't affect trigger logic
|
|
expression = f"last(/{template_name}/{item['key']}){trigger_def['expression']}{trigger_def['threshold']} and length(last(/{template_name}/{part_key}))>0"
|
|
description += ". Replacement part: {ITEM.LASTVALUE2}"
|
|
# Add replacement part reference for other items with part_number_item
|
|
elif 'part_number_item' in item:
|
|
part_key = item['part_number_item']
|
|
# Add the part number item to the expression using "and" so it's evaluated but doesn't affect trigger logic
|
|
expression = f"last(/{template_name}/{item['key']}){trigger_def['expression']}{trigger_def['threshold']} and length(last(/{template_name}/{part_key}))>0"
|
|
description += ". Replacement part: {ITEM.LASTVALUE2}"
|
|
|
|
trigger = {
|
|
"uuid": uuid.uuid4().hex,
|
|
"expression": expression,
|
|
"name": f"{item['name']} is low on {{{{HOST.NAME}}}}",
|
|
"priority": severity_map.get(trigger_def['severity'], "WARNING"),
|
|
"description": description,
|
|
"tags": [
|
|
{
|
|
"tag": "scope",
|
|
"value": "availability"
|
|
}
|
|
]
|
|
}
|
|
|
|
zabbix_item['triggers'].append(trigger)
|
|
|
|
template["zabbix_export"]["templates"][0]["items"].append(zabbix_item)
|
|
|
|
return template
|
|
|
|
|
|
def main():
|
|
"""
|
|
Main function
|
|
"""
|
|
print("\n" + "=" * 80)
|
|
print("ZABBIX CONFIGURATION GENERATOR FOR PRINTER SNMP MONITORING")
|
|
print("Includes: Toner, Maintenance Kit, Fuser, Drums, Waste, Transfer components")
|
|
print("=" * 80)
|
|
|
|
# Generate CLI-friendly output
|
|
generate_zabbix_cli_commands()
|
|
|
|
# Generate importable template
|
|
print("\n" + "=" * 80)
|
|
print("ZABBIX IMPORT TEMPLATE")
|
|
print("=" * 80)
|
|
print("\nSave this template to a file and import it into Zabbix:")
|
|
print("Configuration -> Templates -> Import\n")
|
|
|
|
template_data = generate_zabbix_import_json()
|
|
|
|
# Save as YAML (like the working example)
|
|
# Use default_flow_style=None to let PyYAML choose when to quote
|
|
yaml_output = yaml.dump(template_data, default_flow_style=False, sort_keys=False, allow_unicode=True, width=1000)
|
|
print(yaml_output)
|
|
|
|
with open('zabbix_printer_template.yaml', 'w') as f:
|
|
f.write(yaml_output)
|
|
|
|
# Also save JSON version
|
|
json_output = json.dumps(template_data, indent=2)
|
|
with open('zabbix_printer_template.json', 'w') as f:
|
|
f.write(json_output)
|
|
|
|
print("\n" + "=" * 80)
|
|
print(f"✓ Zabbix template saved to: zabbix_printer_template.yaml (YAML)")
|
|
print(f"✓ Zabbix template saved to: zabbix_printer_template.json (JSON)")
|
|
print("=" * 80)
|
|
|
|
print("\n## Quick Setup Instructions:")
|
|
print("1. Import zabbix_printer_template.json into Zabbix")
|
|
print("2. Create/Edit a host for each printer")
|
|
print("3. Set the SNMP interface with:")
|
|
print(" - IP address: [printer IP]")
|
|
print(" - Port: 161")
|
|
print(f" - SNMP community: WestJeff2025")
|
|
print(" - SNMP version: SNMPv2")
|
|
print("4. Link the 'SNMP Printer Template (HP & Xerox) - Complete' to each host")
|
|
print("5. Wait 1 hour for data collection to begin (or trigger manual check)")
|
|
|
|
print("\n## What Gets Monitored:")
|
|
print("✓ Toner levels (Black, Cyan, Magenta, Yellow)")
|
|
print("✓ Cartridge part numbers for ordering")
|
|
print("✓ Maintenance kit status (HP printers)")
|
|
print("✓ Fuser assembly part number")
|
|
print("✓ Drum cartridge part numbers (all colors)")
|
|
print("✓ Waste cartridge part number")
|
|
print("✓ Transfer belt/roller part numbers")
|
|
print("✓ Supply capacity data for percentage calculations")
|
|
|
|
print("\n## Triggers Configured:")
|
|
print("- Warning: Toner < 20%")
|
|
print("- Critical: Toner < 10%")
|
|
print("- Warning: Maintenance kit < 10,000 pages")
|
|
print("- Critical: Maintenance kit < 5,000 pages")
|
|
|
|
print("\n## Notes:")
|
|
print("- Not all OIDs exist on all printers (e.g., drums on HP, maintenance on Xerox)")
|
|
print("- Color toner OIDs only exist on color printers")
|
|
print("- HP-specific MIB items only work on HP printers")
|
|
print("- Check interval is 1 hour (supplies don't change rapidly)")
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|