Now that Patrick has so kindly added hooks for calling external programs to 
get sync/waitend/pagecount information from a printer, I've found it's not 
that bad to deal with a Xerox Phaser 5400 printer.  From what I've been told 
about the geneology of the Phaser 5400 by some of the more friendly Xerox 
support personel, this likely will work with the DocuPrint N??25 series 
printers, too.

Attached is a perl script check_printer_status.pl, along with a config file 
check_printer_status.xml containing printer-specific information.  I only use 
this program with a Phaser 5400; your mileage may vary with a DocuPrint.

To use this program, do the following:

        0.  you need perl with Net::SNMP installed; go get if if you don't 
            have it already
        1.  install check_printer_status.pl and config file somewhere
        2.  create symbolic links to it titled "check_printer_waitend.pl" 
            and "check_printer_pagecount.pl", likely in the same directory
        3.  edit check_printer_status.pl:
            - change perl path to your perl installation path
            - change path to default XML config file to wherever you put yours
        4.  the entry for "phaser5400" in ifhp.conf should look like this:

[ phaser5400 ] 
tc=hp4000_pcl

appsocket
sync=|/s/lprng-3.8/sbin/check_printer_status.pl
#sync
pagecount=|/s/lprng-3.8/sbin/check_printer_pagecount.pl
#pagecount
waitend=|/s/lprng-3.8/sbin/check_printer_waitend.pl
#waitend

             (Again, change paths to your installation path for this script.)

For large jobs, you may need to increase the lpd timeout for the printer; I 
haven't been able to stress-test this printer with lots of large jobs yet.

If anyone uses this program for other printer models, please report back any 
config file changes you needed to make to get it to work...

My first impression of this printer, despite Xerox support staff that won't 
talk to you if you have questions about anything beyond how to use their 
Windows printer driver, is this is a nice printer.  Supports PS version 3.  
Looks like it is a PostScript engine with PCL 5e/6 emulator, not the other way 
around.  Renders pages fast, too.  Documents that would not print on our HP 
LaserJet 8000/8100's print on this printer.  Time will tell how it holds up.

The duplexing mechanism is interesting on this printer, much like that of the 
Tektronix Phaser 850: the printer will print one side of the page, send it to 
the output tray, then pull it back in after the paper was pushed half-way out. 
 If the printer can render pages fast enough, it will keep 2 pages moving 
through the paper mechanism (two half-printed pages followed by two completed 
pages when in duplex mode).

-- 
============================================================================
   John Perkins                   |   University of Wisconsin-Madison
   Associate Researcher           |   Department of Computer Science
   [EMAIL PROTECTED]               |   1210 W. Dayton St.
   608-262-0438/608-262-9997 FAX  |   Madison, WI  53706-1685
============================================================================


<config>
  <snmp_params 
        community="public"
        timeout="5" 
        retries="3" >
  </snmp_params>

  <printerdata 
        name="phaser850" 
        pagecount_oid=".1.3.6.1.2.1.43.10.2.1.4.1" 
        jobstatus_oid=".1.3.6.1.4.1.253.8.59.6.1.1.9" 
        display_oid=".1.3.6.1.2.1.43.16.5.1.2.1.1" 
        status_ok="17">
           <status> </status>
  </printerdata>
  <printerdata 
        name="phaser5400" 
        pagecount_oid=".1.3.6.1.2.1.43.10.2.1.4.1.1" 
        jobstatus_oid=".1.3.6.1.4.1.253.8.59.6.1.1.9" 
        display_oid=".1.3.6.1.2.1.43.16.5.1.2.1.1" 
        status_ok="17">
        <status 
            Canceling.Job = "10007"
            Clear.Paper.Path = "40022"
            Close.Covers = "40105"
            Close.Stacker.Door = "40105"
            Close.Tray = "40104"
            Disk.Error = "32000"
            Disk.Full = "32002"
            Duplex.Jam = "40093"
            Duplex.Unit.Fail = "40124"
            Exit.Jam = "40022"
            Fan.Failure = "50006"
            Flash.Error = "40053"
            Flash.Full = "30036"
            Flushing = "10007"
            Format.Failed = "40083"
            Fuser.Failure = "50011"
            Initializing... = "10011"
            Insert.MBF = "40026"
            Insert.Tray = "40026"
            Install.Print = "40046"
            IOT.NVM.Fail = "40053"
            Laser.Failure = "50013"
            Open.Extend.MBF = "40053"
            Load.Tray = "41200"
            Low.Paper = "41200"
            Maintenance.Kit = "35075"
            Manual.Feed = "41100"
            Memory.Failure = "40063"
            Motor.Failure = "50023"
            NV.Memory.Fail = "40053"
            Offline = "10001"
            Open.Rear.Tray.Dr = "40022"
            Open.Stacker.Door = "30105"
            PCL.Out.of.Memory = "30016"
            Paper.Jam = "42100"
            Paper.Size.Jam = "42100"
            Please.Wait = "10024"
            Power.Saver.On = "10000"
            Print.Cartridge.OEM.ID = "40005"
            Print.Using = "10023"
            Processing = "10023"
            Ready = "10001"
            Remove.Output.From = "40019"
            Remove.Print.Cart = "40047"
            Replace.Print.Cartridge = "40046"
            Stacker.Bin.Fail = "30107"
            Stacker.Jam = "42100"
            Toner.Low = "10006"
            Tray...Jam = "42100"
            Tray.1.Failure = "50020"
            Tray.2.Failure = "50021"
            Tray.3.Failure = "50022"
            Tray...Empty = "41200"
            Waiting = "10024"
            Warming.Up = "10003"></status>
  </printerdata>
</config>


#! /s/perl-5.6.1/bin/perl -w
#
# usage: 
#    check_printer_status
#
#
# Do SNMP query of printer; return PJL-style information for ifhp 
# (must have ifhp-3.5.8a3 or newer)
#
# Originally written to deal with Xerox appsocket printers, but could 
# easily work with other printers, too.
#
# Symlink this printer as 3 separate names.  I've used the following:
#    check_printer_status      (status check)
#    check_printer_waitend     (EOJ check--will spin until EOJ comes back)
#    check_printer_pagecount   (pagecount query)
#


#BEGIN {
#       if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) {
#               $runtimedir = $1;
#               $PROGNAME = $2;
#       }
#}

use strict;
use Net::SNMP;
use XML::Simple;
use Data::Dumper;

# XML config file containing printer-specific information
my $xml_config="/s/lprng-3.8/common/sbin/check_printer_status.xml";

# other variables
my $printcap;
my $host;
my $model;
my $ifhp;
my $error;
my $response;
my $status;
my $pagecount;
my $complete=0;
my $verbose=0;
my $pjl_status_code;
my $display;

if ($ENV{PRINTCAP_ENTRY}) {
  # get PRINTCAP_ENTRY
  $printcap = $ENV{PRINTCAP_ENTRY};
  # get host from :lp PRINTCAP_ENTRY
  foreach (split (/:/, $printcap)) {
    if (/^lp=/) { 
        $host = $_;
        $host =~ s/lp=//;
        $host =~ s/\%\S*\s*//;
    }
    if (/^ifhp=/) { 
      $ifhp = $_;
      $ifhp =~ s/ifhp=//;
      foreach (split(/,\s/, $ifhp)) {
        if (/model=/) {
          $model = $_;
          $model =~ s/model=//;
        }
      }
      $model =~ s/\s*//g;
    }
  }
} else {
  die("No host or model defined!\n");
}

print "Host: $host\tModel: $model\n" if $verbose;

# parse XML config file
# slurp in all printer-specific OID info, 
my $ref = XMLin($xml_config, forcearray => 0);

# SNMP parameters
# Not sure why the following line doesn't work...I suspect something 
# strange in XML::Simple...Nate thinks it's in XML::Parser called from
# XML::Simple.
#my $community=$ref->{snmp_params}->{community};
my $community=substr($ref->{snmp_params}->{community}, 0);
my $timeout=$ref->{snmp_params}->{timeout};
my $retries=$ref->{snmp_params}->{retries};
my $session;

if ( $host eq "" ) {
    die "No printer name defined or \$PRINTER set\n";
}

#print "progname: $0\n";

print Dumper($ref) if $verbose;

print "SNMP params: host $host, community $community, timeout $timeout, retries 
$retries\n" if $verbose;
($session, $error) = Net::SNMP->session(-hostname => $host,
                                        -community => $community,
                                        -timeout => $timeout,
                                        -retries => $retries);

# check status
if ($0 =~ /waitend/) {
  if ($ref->{printerdata}->{$model}->{jobstatus_oid}) {
    my $jobstatus_oid=$ref->{printerdata}->{$model}->{jobstatus_oid};
            my $status_ok=$ref->{printerdata}->{$model}->{status_ok};
            do {
              if ($response) {
                # be nice to the network
                sleep 3;
              }
              print "Running get_table ($jobstatus_oid)\n" if $verbose;
              ($response) = $session->get_table(($jobstatus_oid));
              print "jobstatus response: $response\n" if $verbose;
              # if we get an answer back, assume the printer job is complete and change
              # the flag if it is still printing; otherwise, assume the job is not done
              if ($response) {
                $complete=1;
                foreach (sort keys (%$response)) {
                  print "response for $_: $response->{$_}\n" if $verbose;
                  # Get "ok" status from XML config file
                  if ($response->{$_} != $status_ok) {
                    $complete=0;
                  }
                }
              } 
            } until ($complete);
              print "RESULT=OK\n";
              print "waitend=1\n";
          }
        } 

# check pagecount
if ($0 =~ /pagecount/) {
  print "Running pagecount\n" if $verbose;
  if ($ref->{printerdata}->{$model}->{pagecount_oid} &&
    $ref->{printerdata}->{$model}->{jobstatus_oid} ) {
  
  my $pagecount_oid=$ref->{printerdata}->{$model}->{pagecount_oid};
  print "Running get_request $pagecount_oid\n" if $verbose;
  ($response) = $session->get_request(($pagecount_oid));
  $pagecount = $response->{$pagecount_oid};
  print "pagecount response: $response\tpagecount: $pagecount\n" if $verbose;
  print "Error: $error\n" if $verbose;
  if ($pagecount) {
    print "PAGECOUNT=$pagecount\n";
  }
}
}

# check display status

if ($0 =~ /status/ && $ref->{printerdata}->{$model}->{display_oid}) {
  my $display_oid=$ref->{printerdata}->{$model}->{display_oid};
  print "Running get_table $display_oid\n" if $verbose;
  $display = $session->get_request($display_oid);
  print "Display status fetched: $display->{$display_oid}" if $verbose;

  my $status = $ref->{printerdata}->{$model}->{status};
  if ($status) {
    foreach (keys %$status) {
      print "Checking for $_\n" if $verbose;
      if ($display->{$display_oid} =~ /$_/) {
        $pjl_status_code = $status->{$_};
        print "CODE=$pjl_status_code\n";
        last;
      }
    }
    print "sync=1\n";
  } else {
    print "sync=0\n";
  }
}

# all done
  $session->close;


# exit with JSUCC
$status = 0;
print "Exit status: 0\n" if $verbose;
exit $status;


Reply via email to