Hmmm... well there are others as well. Here is a snippet from the ifhp code that seems to address this problem. See the convoluted logic in the code below. Experiments indicated that a 1 second delay was suffient for most purposes. I suppose that I should add Yet Another Configure Variable - snmp_wait_after_close, to allow you to modify/extend this value. Sigh....
Yow! The things we get forced into doing!
Here's another piece of test code. It prints out the value of several SNMP variables every second. You start it running, then send a print job to the printer. It might be nice to create a collection of two outputs from this script for a number of different printers - one for "printer cold" and another for "printer warm".
If I get time, I will add internal documentation as to the meanings of the values of the status and error variables.
-Rick
-- |Rick Cochran phone: 607-255-7618| |Cornell CIT - Systems & Operations - Net-Print FAX: 607-255-8521| |730 Rhodes Hall, Ithaca, N.Y. 14853 email: [EMAIL PROTECTED]|
#!/usr/common/bin/perl -w # Watch printer status
#use diagnostics;
use strict;
use Net::SNMP;
$| = 1;
my $ip = $ARGV[0];
if ( not defined($ip) ) {
die "Usage: $0 <printer IP>\n";
}
# OIDs for SNMP variables
# Techniques for figuring out OIDs:
# To get OID for printer serial number:
# snmpwalk uris1 public .iso.3.6.1 | grep 11CKWB3
# To access an OID:
# snmpget uris1 public .1.3.6.1.4.1.641.2.1.2.1.6.1
# Helpful URL: www.ibr.cs.tu-bs.de/cgi-bin/sbrowser.cgi
# OIDs common to all printers (I hope)
my $PAGECOUNT_OID = '1.3.6.1.2.1.43.10.2.1.4.1.1'; # prtMarkerLifeCount.1.1
my $MODEL_OID = '1.3.6.1.2.1.25.3.2.1.3.1'; # hrDeviceDescr.1
my $DEVICE_STATUS_OID = '1.3.6.1.2.1.25.3.2.1.5.1'; # hrDeviceStatus.1
my $PRINTER_STATUS_OID= '1.3.6.1.2.1.25.3.5.1.1.1'; # hrPrinterStatus.1
my $ERROR_STATE_OID = '1.3.6.1.2.1.25.3.5.1.2.1'; # hrPrinterDetectedErrorState.1
my $MEMORY_SIZE_OID = '1.3.6.1.2.1.25.2.2.0'; # hrMemorySize.0
my $CONSOLE_OID = '1.3.6.1.2.1.43.16.5.1.2.1.1'; #
prtConsoleDisplayBufferText.1.1
# Manufacturer or model-specific OIDs
my $LEX_MODEL_OID = '1.3.6.1.4.1.641.2.1.2.1.2.1'; # prtgenPrinterName.1
my $LEX_OPTRA_SERIAL_NO_OID = '1.3.6.1.4.1.641.2.1.2.1.6.1'; # Not in published
Lexmark MIB
my $LEX_INT_SERIAL_NO_OID = '1.3.6.1.4.1.641.2.1.2.1.5.1'; # Bogus (not available)
my $HP_SERIAL_NO_OID = '1.3.6.1.2.1.43.5.1.1.17.1'; # Not in published RFC1759
my $HP_5M_SERIAL_NO_OID= '1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.3.0'; # HP private MIB
my $XEROX_SERIAL_NO_OID= '1.3.6.1.4.1.253.8.53.3.2.1.3.1'; # xcmHrDevInfoSerialNumber.1
sub get_status {
my($ip) = @_;
my %status;
my $community = 'public';
my($session, $msg) = Net::SNMP->session(-hostname => $ip, -community =>
$community, -retries => 2, -timeout => 2);
if ( not defined($session) ) {
die "Couldn't open SNMP session to $ip: $msg";
}
my($result) = $session->get_request(-varbindlist => [$DEVICE_STATUS_OID,
$PRINTER_STATUS_OID, $ERROR_STATE_OID, $PAGECOUNT_OID, $CONSOLE_OID]);
if ( not defined($result) ) {
die "SNMP query failed ($!)\n";
}
$status{device_status} = $result->{$DEVICE_STATUS_OID};
$status{printer_status} = $result->{$PRINTER_STATUS_OID};
$status{error} = fix_octet_string($result->{$ERROR_STATE_OID});
$status{pagecount} = $result->{$PAGECOUNT_OID};
$status{console} = $result->{$CONSOLE_OID};
return(\%status);
}
#########################################################
# Net::SNMP will translate most, but not all, non-printing characters
# in an octet string to hexadecimal notation. Since we want translation
# in most cases, this makes our job interesting in this case where we don't.
# Also, some printers (eg. Lexmark C910) return an empty string instead of a
# null byte.
sub fix_octet_string {
my($octet) = @_;
if ( $octet =~ /0x.*/ ) {
$octet = hex($octet);
}
else {
$octet =~ s/\s//g;
if ( $octet eq '' ) {
$octet = 0;
}
else {
$octet = unpack("C", $octet);
}
}
# Under some circumstances (Xerox printer changing paper trays) $octet
# magically gets its high order bit (out of 32) set.
# $octet = $octet & ($PSTAT_MAX*2-1);
return($octet);
}
print "device_status printer_status error pagecount console\n";
print "hrDeviceStatus.1 hrPrinterStatus.1 hrPrinterDetectedErrorState.1
prtMarkerLifeCount.1.1 prtConsoleDisplayBufferText.1.1\n";
while ( 1 ) {
my $status = get_status($ip);
printf "$status->{device_status} $status->{printer_status} $status->{error}
$status->{pagecount} $status->{console}\n";
sleep(1);
}
exit(0);
