reading data from raw printer
Kurt Pfeifle
kurt.pfeifle at infotec.com
Thu Jul 5 14:54:02 PDT 2007
> Johannes Meixner recently wrote:
>
> > > The command interface has the potential to be really useful, not least
> > > for things like finding out ink levels. It's just that no-one seems to
> > > be using it or understand how it works...
> >
> > At least for me this is true.
>
>
> I remember to have started to play with CUPS command files a loooong
> time ago, but I never followed up with it. There should be some initial
> command filter script that I started with still sleeping somewhere in
> my backup archives.
>
> There are a lot of nice little things you can imagine that this
> interface could be used for. The thing I did was to send a CUPS-command
> file to "print" on a network printer; that job contained the command "GetCounter".
>
> The name of that command was completely arbitrary. The printer's PPD
> had (additionally, on top of the existing ones) a "*cupsFilter:" line:
>
> *cupsFilter: "application/vnd.cups-command 0 count_requester.sh"
>
> Then, my filter "count_requester" made sure it parsed and followed the
> "GetCounter" command. (Of course, I could have sent an empty CUPS
> command job as well, and made the count_requester to do what I meant it
> to do regardless of the command.
>
> Since the count_requester has access to all commandline arguments as
> well as the environment variables handed over by CUPS, it could find
> out what the target printer was.
>
> It then run an snmpwalk command on that printer and grep-ped for the
> current total life count in the response. That figure was then used
> to send another job to (possibly another) printer reporting the
> page count of $original printer.
>
> [But instead of printing, it could have sent me an e-Mail, or written
> the figure into a database, or whatever you can imagine...]
>
> My original idea was to use the command file as a CUPS banner page.
> That scenario possibly would be a bit shaky, because of timing issues,
> and the "banner" not arriving immediately after the main job on very
> busy printers. I never tested if this concept works for me like I
> imagined, but I think the basics of it should.
>
> Later tonight I'll have a look for my old scripting experiments and
> see if it turns up something useful.
OK, found it.
The CUPS command file is "snmp-read-command":
------------ snip -------------
#CUPS-COMMAND
GetAndPrintSNMPCounter
------------ snap -------------
The "*cupsFilter:" line in the PPD is:
------------ snip -------------
*cupsFilter: "application/vnd.cups-command 0 my_snmp_counter_requester.sh"
------------ snap -------------
The "my_snmp_counter_requester.sh" is (I just changed my e-Mail address
to the current one, and left it un-changed and un-tested; I seem to
remember that it somehow had started to work for me before I forgot
about it again)::
------------ snip -------------
#!/bin/bash
#
# (c) Kurt Pfeifle, 2005
# <kurt.pfeifle at infotec.com>
#
# license: Use freely as you please -- it is only a simple script
# (but find bugs on your own, and don't blame me for any fault)
#
# (1) uncomment the next line
#set -x
# (2) set "LogLevel debug" in cupsd.conf
# (3) restart cupsd
# (4) now find in error_log file what goes wrong
# $0 job-id user title copies options [file]
jobid=$1
user=$2
title=$3
copies=$4
options=$5
#fixed_address=10.162.5.84
oid='.1.3.6.1.2.1.43.10.2.1.4.1.1'
#oid='.1.3.6.1.2.1.43.10.2.1.4.1'
community_name=public
CMD=snmpget
#CMD=snmpwalk
function check_cups_filter_calling_conventions() {
case ${#} in
0) echo "Usage: ${0} job-id user title copies options [file]"
exit 0
;;
5) input="-"
;;
6) input=$6
;;
*) echo "ERROR: not correct number of arguments to ${0}."
echo "ERROR: ${0} should have 5 or 6 args, but had ${#}."
exit 1
;;
esac
}
function parse_command_file() {
grep GetAndPrintSNMPCounter ${input} #1> /dev/null 2> /dev/null
parseexit=${?}
if [ x${parseexit} == x0 ]; then
echo "INFO: I am asked to query the printer for its life count and print it."
else
echo "ERROR: don't know what to do. Exiting."
exit 1
fi
}
function find_target_ip() {
echo ${DEVICE_URI} | grep "^ipp://"
findipp=${?}
echo ${DEVICE_URI} | grep "^socket://"
findsocket=${?}
if [ x${findipp} == x0 ]; then
proto='ipp://'
host_port=$(echo ${DEVICE_URI#socket://})
host=${host_port%:631} # right now we assume a hard-coded 631 port
# and we assume it at the end of the string
elif [ x${findsocket} == x0 ]; then
proto='socket://'
host_port=$(echo ${DEVICE_URI#socket://})
host=${host_port%:9100} # right now we assume a hard-coded 9100 port
else
proto=UNSUPPORTED
host_port=UNSUPPORTED
host=UNSUPPORTED
fi
printer_ip_or_name=${host}
#printer_ip_or_name=${fixed_address}
}
function run_snmp_query() {
# We run this commmand and grep its output: it should give us the
# current reading of the internal page counter inside the printer:
# ${CMD} -c {community_name} -Lo -OQ -t3 -r5 -v1 ${fixed_adddress} ${oid}
CURRENT_PAGE_COUNT="$(${CMD} -c ${community_name} -Lo -OQ -t3 -r5 -v1 ${printer_ip_or_name} ${oid} | awk -F ' = ' '{print $2}')"
}
function send_job() {
text="
The internal page counter of this printer currently
reports a life time total count of
========================================
${CURRENT_PAGE_COUNT} page impressions
========================================
"
echo "${text}" \
| lp -d ${PRINTER} \
-o page-top=50 \
-o page-left=40 \
-o prettyprint=true \
-o lpi=5.4 \
-o cpi=7.5 \
-o PageSize=A4 \
-
}
# now do the work
check_cups_filter_calling_conventions "${@}" # the quotes around ${@} are important!
parse_command_file
find_target_ip
run_snmp_query
send_job
exit $?
------------ snap -------------
Looking again at the code, I think it should work. (There are however
some $incomplete parts; it doesn't handle the non-socket/ipp backends
-- when "proto=UNSUPPORTED" it should not attempt to run the snmpget
command and should print a different text; etc.pp.)
--
Kurt Pfeifle
System & Network Printing Consultant ---- Linux/Unix/Windows/Samba/CUPS
Infotec Deutschland GmbH ..................... Hedelfinger Strasse 58
A RICOH Company ........................... D-70327 Stuttgart/Germany
More information about the cups
mailing list