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>
184 lines
6.2 KiB
Python
184 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Comprehensive printer analysis to create separate templates
|
|
"""
|
|
|
|
import csv
|
|
import os
|
|
from collections import defaultdict
|
|
|
|
# Base OIDs
|
|
SUPPLY_DESC_OID = "1.3.6.1.2.1.43.11.1.1.6.1"
|
|
SUPPLY_MAX_OID = "1.3.6.1.2.1.43.11.1.1.8.1"
|
|
SUPPLY_LEVEL_OID = "1.3.6.1.2.1.43.11.1.1.9.1"
|
|
MODEL_OID = "1.3.6.1.2.1.25.3.2.1.3.1"
|
|
|
|
def parse_csv(filepath):
|
|
"""Parse printer SNMP CSV file"""
|
|
data = {}
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
for line in f:
|
|
parts = line.strip().split(',', 2)
|
|
if len(parts) >= 2:
|
|
oid = parts[0]
|
|
value = parts[1].strip('"')
|
|
data[oid] = value
|
|
except Exception as e:
|
|
print(f"Error reading {filepath}: {e}")
|
|
return data
|
|
|
|
def analyze_printer(filepath):
|
|
"""Analyze a single printer's supply configuration"""
|
|
data = parse_csv(filepath)
|
|
printer_name = os.path.basename(filepath).replace('.csv', '')
|
|
|
|
# Get model
|
|
model = data.get(MODEL_OID, "Unknown")
|
|
|
|
# Get all supply descriptions
|
|
supplies = {}
|
|
for i in range(1, 25):
|
|
desc_oid = f"{SUPPLY_DESC_OID}.{i}"
|
|
level_oid = f"{SUPPLY_LEVEL_OID}.{i}"
|
|
max_oid = f"{SUPPLY_MAX_OID}.{i}"
|
|
|
|
if desc_oid in data:
|
|
desc = data[desc_oid]
|
|
level = data.get(level_oid, "N/A")
|
|
max_cap = data.get(max_oid, "N/A")
|
|
supplies[i] = {
|
|
'description': desc,
|
|
'level': level,
|
|
'max': max_cap
|
|
}
|
|
|
|
return {
|
|
'name': printer_name,
|
|
'model': model,
|
|
'supplies': supplies
|
|
}
|
|
|
|
def main():
|
|
output_dir = '/home/camp/output'
|
|
|
|
# Categorize printers
|
|
hp_modern = [] # HP LaserJet Pro, newer models
|
|
hp_legacy = [] # HP LaserJet 600 series, older models
|
|
xerox_color = [] # Xerox VersaLink Color
|
|
xerox_mono = [] # Xerox VersaLink B&W
|
|
|
|
print("=" * 100)
|
|
print("COMPREHENSIVE PRINTER ANALYSIS FOR TEMPLATE CREATION")
|
|
print("=" * 100)
|
|
|
|
# Analyze all printers
|
|
for filename in sorted(os.listdir(output_dir)):
|
|
if not filename.endswith('.csv'):
|
|
continue
|
|
|
|
filepath = os.path.join(output_dir, filename)
|
|
result = analyze_printer(filepath)
|
|
model = result['model']
|
|
|
|
# Categorize
|
|
if 'HP LaserJet Pro' in model or 'HP LaserJet 4' in model:
|
|
hp_modern.append(result)
|
|
elif 'HP LaserJet' in model or 'hp' in model.lower():
|
|
hp_legacy.append(result)
|
|
elif 'Xerox VersaLink C' in model:
|
|
xerox_color.append(result)
|
|
elif 'Xerox VersaLink B' in model:
|
|
xerox_mono.append(result)
|
|
|
|
# Print summaries
|
|
print(f"\nFound {len(hp_modern)} HP Modern printers")
|
|
print(f"Found {len(hp_legacy)} HP Legacy printers")
|
|
print(f"Found {len(xerox_color)} Xerox Color printers")
|
|
print(f"Found {len(xerox_mono)} Xerox Mono printers")
|
|
|
|
# Analyze each category
|
|
categories = [
|
|
("HP MODERN (LaserJet Pro 4xxx)", hp_modern),
|
|
("HP LEGACY (LaserJet 600)", hp_legacy),
|
|
("XEROX COLOR (VersaLink C)", xerox_color),
|
|
("XEROX MONO (VersaLink B)", xerox_mono)
|
|
]
|
|
|
|
for cat_name, printers in categories:
|
|
if not printers:
|
|
continue
|
|
|
|
print("\n" + "=" * 100)
|
|
print(f"{cat_name} - {len(printers)} printers")
|
|
print("=" * 100)
|
|
|
|
# Show all printers in this category
|
|
for printer in printers:
|
|
print(f"\n{printer['name']}")
|
|
print(f"Model: {printer['model']}")
|
|
if printer['supplies']:
|
|
print(f"{'Index':<7} {'Description':<65} {'Level':<12} {'Max'}")
|
|
print("-" * 100)
|
|
for idx, supply in sorted(printer['supplies'].items()):
|
|
desc = supply['description'][:63]
|
|
print(f"{idx:<7} {desc:<65} {supply['level']:<12} {supply['max']}")
|
|
else:
|
|
print("No supplies found")
|
|
|
|
# Generate OID mappings for each category
|
|
print("\n" + "=" * 100)
|
|
print("RECOMMENDED OID MAPPINGS FOR TEMPLATES")
|
|
print("=" * 100)
|
|
|
|
for cat_name, printers in categories:
|
|
if not printers:
|
|
continue
|
|
|
|
print(f"\n{cat_name}:")
|
|
print("-" * 100)
|
|
|
|
# Collect all indices and their descriptions
|
|
index_map = defaultdict(set)
|
|
for printer in printers:
|
|
for idx, supply in printer['supplies'].items():
|
|
# Normalize description
|
|
desc = supply['description'].lower()
|
|
if 'black' in desc and 'toner' in desc:
|
|
index_map[idx].add('Black Toner')
|
|
elif 'cyan' in desc and 'toner' in desc:
|
|
index_map[idx].add('Cyan Toner')
|
|
elif 'magenta' in desc and 'toner' in desc:
|
|
index_map[idx].add('Magenta Toner')
|
|
elif 'yellow' in desc and 'toner' in desc:
|
|
index_map[idx].add('Yellow Toner')
|
|
elif 'black' in desc and 'drum' in desc:
|
|
index_map[idx].add('Black Drum')
|
|
elif 'cyan' in desc and 'drum' in desc:
|
|
index_map[idx].add('Cyan Drum')
|
|
elif 'magenta' in desc and 'drum' in desc:
|
|
index_map[idx].add('Magenta Drum')
|
|
elif 'yellow' in desc and 'drum' in desc:
|
|
index_map[idx].add('Yellow Drum')
|
|
elif 'waste' in desc:
|
|
index_map[idx].add('Waste Container')
|
|
elif 'fuser' in desc:
|
|
index_map[idx].add('Fuser')
|
|
elif 'transfer belt' in desc:
|
|
index_map[idx].add('Transfer Belt')
|
|
elif 'transfer roll' in desc:
|
|
index_map[idx].add('Transfer Roller')
|
|
elif 'maintenance' in desc:
|
|
index_map[idx].add('Maintenance Kit')
|
|
|
|
# Print consistent mappings
|
|
for idx in sorted(index_map.keys()):
|
|
components = index_map[idx]
|
|
if len(components) == 1:
|
|
print(f" Index {idx}: {list(components)[0]} ✓")
|
|
else:
|
|
print(f" Index {idx}: VARIES - {', '.join(components)}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|