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>
This commit is contained in:
169
analyze_supplies.py
Normal file
169
analyze_supplies.py
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Analyze SNMP supply data across multiple printers
|
||||
to validate OID index mappings
|
||||
"""
|
||||
|
||||
import csv
|
||||
import os
|
||||
from collections import defaultdict
|
||||
|
||||
# Base OIDs we care about
|
||||
SUPPLY_DESC_OID = "1.3.6.1.2.1.43.11.1.1.6.1" # prtMarkerSuppliesDescription
|
||||
SUPPLY_MAX_OID = "1.3.6.1.2.1.43.11.1.1.8.1" # prtMarkerSuppliesMaxCapacity
|
||||
SUPPLY_LEVEL_OID = "1.3.6.1.2.1.43.11.1.1.9.1" # prtMarkerSuppliesLevel
|
||||
MODEL_OID = "1.3.6.1.2.1.25.3.2.1.3.1" # hrDeviceDescr
|
||||
|
||||
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, 20): # Check indices 1-20
|
||||
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'
|
||||
|
||||
# Group printers by manufacturer
|
||||
hp_printers = []
|
||||
xerox_printers = []
|
||||
|
||||
print("=" * 80)
|
||||
print("SNMP SUPPLY INDEX VALIDATION")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# 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)
|
||||
|
||||
if 'HP' in result['model'] or 'hp' in result['model']:
|
||||
hp_printers.append(result)
|
||||
elif 'Xerox' in result['model']:
|
||||
xerox_printers.append(result)
|
||||
|
||||
# Analyze HP printers
|
||||
print("\n" + "=" * 80)
|
||||
print("HP PRINTERS - Supply Index Mapping")
|
||||
print("=" * 80)
|
||||
|
||||
# Get common indices across HP printers
|
||||
hp_indices = defaultdict(list)
|
||||
for printer in hp_printers[:3]: # Sample first 3
|
||||
print(f"\n{printer['name']}")
|
||||
print(f"Model: {printer['model']}")
|
||||
print(f"{'Index':<7} {'Description':<50} {'Level':<10} {'Max'}")
|
||||
print("-" * 80)
|
||||
for idx, supply in sorted(printer['supplies'].items()):
|
||||
desc_short = supply['description'][:48]
|
||||
print(f"{idx:<7} {desc_short:<50} {supply['level']:<10} {supply['max']}")
|
||||
hp_indices[idx].append(desc_short)
|
||||
|
||||
# Analyze Xerox printers
|
||||
print("\n" + "=" * 80)
|
||||
print("XEROX PRINTERS - Supply Index Mapping")
|
||||
print("=" * 80)
|
||||
|
||||
xerox_indices = defaultdict(list)
|
||||
for printer in xerox_printers[:3]: # Sample first 3
|
||||
print(f"\n{printer['name']}")
|
||||
print(f"Model: {printer['model']}")
|
||||
print(f"{'Index':<7} {'Description':<50} {'Level':<10} {'Max'}")
|
||||
print("-" * 80)
|
||||
for idx, supply in sorted(printer['supplies'].items()):
|
||||
desc_short = supply['description'][:48]
|
||||
print(f"{idx:<7} {desc_short:<50} {supply['level']:<10} {supply['max']}")
|
||||
xerox_indices[idx].append(desc_short)
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 80)
|
||||
print("SUMMARY - Index Mapping Patterns")
|
||||
print("=" * 80)
|
||||
|
||||
print("\nHP Printers:")
|
||||
print("-" * 80)
|
||||
common_hp = {}
|
||||
for idx, descs in sorted(hp_indices.items()):
|
||||
# Find common pattern
|
||||
desc_types = set([d.split(',')[0].split(' ')[0] for d in descs])
|
||||
if len(desc_types) == 1:
|
||||
common_hp[idx] = list(desc_types)[0]
|
||||
print(f"Index {idx}: {list(desc_types)[0]} (consistent across {len(descs)} printers)")
|
||||
|
||||
print("\nXerox Printers:")
|
||||
print("-" * 80)
|
||||
common_xerox = {}
|
||||
for idx, descs in sorted(xerox_indices.items()):
|
||||
# Find common pattern
|
||||
desc_types = set([d.split(',')[0].split('(')[0].strip() for d in descs])
|
||||
if len(desc_types) == 1:
|
||||
common_xerox[idx] = list(desc_types)[0]
|
||||
print(f"Index {idx}: {list(desc_types)[0]} (consistent across {len(descs)} printers)")
|
||||
|
||||
# Validation against current template
|
||||
print("\n" + "=" * 80)
|
||||
print("VALIDATION - Current Template vs Actual Data")
|
||||
print("=" * 80)
|
||||
|
||||
print("\nCurrent Template Assumptions:")
|
||||
print(" 1-4: Toner (Black, Cyan, Magenta, Yellow)")
|
||||
print(" 5-8: Drums (R1, R2, R3, R4) - XEROX SPECIFIC")
|
||||
print(" 9: Waste Toner Container")
|
||||
print(" 10: Transfer Belt Cleaner")
|
||||
print(" 11: Second Bias Transfer Roll")
|
||||
|
||||
print("\n✓ = Correct, ✗ = Incorrect, ? = Varies by model")
|
||||
|
||||
# Check toner
|
||||
print("\nToner Indices (1-4):")
|
||||
for idx in range(1, 5):
|
||||
hp_match = common_hp.get(idx, '').lower()
|
||||
xerox_match = common_xerox.get(idx, '').lower()
|
||||
status = "✓" if 'toner' in hp_match and 'toner' in xerox_match else "?"
|
||||
print(f" Index {idx}: {status} HP='{common_hp.get(idx, 'N/A')}' Xerox='{common_xerox.get(idx, 'N/A')}'")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user