HP Deskjet API

November 2014

Seit bald einem Jahr wohnt das Monster namens Deskjet 3520 nun hier im Regal und spottet mit wirren Meldungen wie “Tinte nachfüllen” oder “Ich habe ein paar Blatt Papier zerissen, bitte nachfüllen”, obwohl es eigentlich nur noch zum scannen da ist. Immerhin aber hat es ein Webinterface nebst API auf die komfortabel zugegriffen werden kann.

Daraus lässt sich bestimmt etwas machen. Scannen übers Terminal zum Beispiel. Whoo!

Scaninterface

Ein Klick auf “Scan starten” bspw. sendet ein Request an /Scan/Jobs, in dessen Payload die Einstellungen in wunderschönem XML liegen:

<scan:ScanJob xmlns:scan="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19" xmlns:fw="http://www.hp.com/schemas/imaging/con/firewall/2011/01/05" xmlns:dd="http://www.hp.com/schemas/imaging/con/dictionaries/1.0/">
    <scan:XResolution>300</scan:XResolution>
    <scan:YResolution>300</scan:YResolution>
    <scan:XStart>0</scan:XStart>
    <scan:YStart>0</scan:YStart>
    <scan:Width>2480</scan:Width>
    <scan:Height>3508</scan:Height>
    <scan:Format>Jpeg</scan:Format>
    <scan:CompressionQFactor>25</scan:CompressionQFactor>
    <scan:ColorSpace>Color</scan:ColorSpace>
    <scan:BitDepth>8</scan:BitDepth>
    <scan:InputSource>Platen</scan:InputSource>
    <scan:GrayRendering>NTSC</scan:GrayRendering>
    <scan:ToneMap>
        <scan:Gamma>1000</scan:Gamma>
        <scan:Brightness>1000</scan:Brightness>
        <scan:Contrast>1000</scan:Contrast>
        <scan:Highlite>179</scan:Highlite>
        <scan:Shadow>25</scan:Shadow>
    </scan:ToneMap>
    <scan:ContentType>Photo</scan:ContentType>
</scan:ScanJob>

Als Antwort bekommt man die Adresse des ScanJobs:

HTTP/1.1 201 Created
Server: HP HTTP Server; HP Deskjet 3520 series - CX052B; Serial Number: CN3861G2GM05SY; Stuttgart_pp_usr_hf Built:Mon Oct 15, 2012 11:37:04AM {STP1FN1241BR, ASIC id 0x00340104}
Location: http://192.168.0.22:80/Jobs/JobList/7
Content-Length: 0
Cache-Control: must-revalidate, max-age=0
Pragma: no-cache

Dort wiederum gibt es den aktuellen Status inkl. Pfad zur Datei zu sehen:

<?xml version="1.0" encoding="UTF-8"?>
<!-- THIS DATA SUBJECT TO DISCLAIMER(S) INCLUDED WITH THE PRODUCT OF ORIGIN. -->
<j:Job xmlns:j="http://www.hp.com/schemas/imaging/con/ledm/jobs/2009/04/30" xmlns:dd="http://www.hp.com/schemas/imaging/con/dictionaries/1.0/" xmlns:fax="http://www.hp.com/schemas/imaging/con/fax/2008/06/13" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hp.com/schemas/imaging/con/ledm/jobs/2009/04/30 ../schemas/Jobs.xsd">
    <j:JobUrl>/Jobs/JobList/8</j:JobUrl>
    <j:JobCategory>Scan</j:JobCategory>
    <j:JobState>Processing</j:JobState>
    <j:JobStateUpdate>115-15</j:JobStateUpdate>
    <j:JobSource>userIO</j:JobSource>
    <ScanJob xmlns="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19">
        <PreScanPage>
            <PageNumber>1</PageNumber>
            <PageState>PreparingScan</PageState>
            <BufferInfo>
                <ScanSettings>
                    <XResolution>300</XResolution>
                    <YResolution>300</YResolution>
                    <XStart>0</XStart>
                    <YStart>0</YStart>
                    <Width>2480</Width>
                    <Height>3508</Height>
                    <Format>Jpeg</Format>
                    <CompressionQFactor>25</CompressionQFactor>
                    <ColorSpace>Color</ColorSpace>
                    <BitDepth>8</BitDepth>
                    <InputSource>Platen</InputSource>
                    <ContentType>Photo</ContentType>
                </ScanSettings>
                <ImageWidth>2480</ImageWidth>
                <ImageHeight>3508</ImageHeight>
                <BytesPerLine>7440</BytesPerLine>
                <Cooked>enabled</Cooked>
            </BufferInfo>
            <BinaryURL>/Scan/Jobs/7/Pages/1</BinaryURL>
            <ImageOrientation>Normal</ImageOrientation>
        </PreScanPage>
    </ScanJob>
</j:Job>

Hinter der BinaryURL versteckt sich tatsächlich was man erwartet: Ein Bild, das gerade noch erstellt wird.

Würde man sich um den Tintenstand seines Druckers kümmern, könnte sicher auch dieser Problemlos ausgelesen und in seine Conky Config oder sein Today-Script integriert werden. Aber wie gesagt …

Hier noch mein dilettantisch zusammengepapptes Skript zum Scannen und speichern von Dingen™:

$ ./scan.sh foo.jpg
#!/bin/sh

base='http://192.168.0.22'
xres="300"
yres="300"
xstart="0"
ystart="0"
width="2480"
height="3508"
format="Jpeg"
compression="25"
color="Color"
depth="8"
insource="Platen"
grayrendering="NTSC"
gamma="1000"
brightness="1000"
contrast="1000"
highlite="179"
shadow="25"
ctype="Photo"

response=`curl -s -D - -X POST "$base/Scan/Jobs" -d '<scan:ScanJob xmlns:scan="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19" xmlns:fw="http://www.hp.com/schemas/imaging/con/firewall/2011/01/05" xmlns:dd="http://www.hp.com/schemas/imaging/con/dictionaries/1.0/"><scan:XResolution>'$xres'</scan:XResolution><scan:YResolution>'$yres'</scan:YResolution><scan:XStart>'$xstart'</scan:XStart><scan:YStart>'$ystart'</scan:YStart><scan:Width>'$width'</scan:Width><scan:Height>'$height'</scan:Height><scan:Format>'$format'</scan:Format><scan:CompressionQFactor>'$compression'</scan:CompressionQFactor><scan:ColorSpace>'$color'</scan:ColorSpace><scan:BitDepth>'$depth'</scan:BitDepth><scan:InputSource>'$insource'</scan:InputSource><scan:GrayRendering>'$grayrendering'</scan:GrayRendering><scan:ToneMap><scan:Gamma>'$gamma'</scan:Gamma><scan:Brightness>'$brightness'</scan:Brightness><scan:Contrast>'$contrast'</scan:Contrast><scan:Highlite>'$highlite'</scan:Highlite><scan:Shadow>'$shadow'</scan:Shadow></scan:ToneMap><scan:ContentType>'$ctype'</scan:ContentType></scan:ScanJob>'`
file="scan.jpg"
code=`echo $response | egrep -o "HTTP/1.1 2[0-9]{2}"`
location=`echo $response | egrep -o "/Jobs/JobList/[0-9]+"`

if [ "$1" != "" ]; then
	file=$1
fi

if [ "$code" == "" ] || [ "$location" == "" ]; then
	echo $response | egrep --colour=never -o "HTTP/1.1 [0-9]{3}"
	exit
fi

response=`curl -s $base$location`
image=`echo $response | egrep -o "/Scan/Jobs/[0-9]+/Pages/[0-9]+"`

if [ "$image" == "" ]; then
	echo $response | egrep --colour=never -o "HTTP/1.1 [0-9]{3}"
	exit
fi

echo "Scanning ..."

curl -s $base$image -o $file
Scanning ...