Brother printers - REGEX/XSLT help requested

I have some Brother printers (one per floor) which i would like to monitor in openhab. I’m mainly interested in ink levels, later on perhaps other stuff as well.

My initial approach was to use the SNMP binding, but unfortunately Brother printers do not report the level, but only values of “near empty” and “empty”, so i thought of a different approach. The status page of the printers returns a nice chart with the current ink levels:

so i took a look at the source of that page to see if I could do something with it:

general_status.html.pdf (69.6 KB)

my initial idea was to use the HTTP binding to parse this and get the values for toner levels, however i’m struggling with the regex or XSL transformation to retrieve the values for Black, Yellow, Cyan and Magenta (50px seems to be 100%, but I’m not sure about it yet). My current approach now is to retrieve the status page from a bash script, retrieving the values from there, and post them to openhab… however this seems a bit complicated. Can someone led me to getting the correct values from the above html using openhab capabilities ?

I’d do it like this:

root@KGTec1Openhab2Server:/mnt/openhab/configurations/images# cat status.html | sed "s#[<>]#\n#g" | fgrep tonerremain
img src="../common/images/black.gif" alt="Black" class="tonerremain" height="44px" /
img src="../common/images/yellow.gif" alt="Yellow" class="tonerremain" height="8px" /
img src="../common/images/cyan.gif" alt="Cyan" class="tonerremain" height="11px" /
img src="../common/images/magenta.gif" alt="Magenta" class="tonerremain" height="11px" /

from these i’d create curl commands with sed again to post the values… However this looks quite complicated to me :slight_smile:

1 Like

Just in case someone else is interested in this, here is my current solution which works fine but is a bit awkward… For sure it is a quick & dirty hack, but it does what i wanted to achieve so for me it is OK for now.

It consists of three files, tested on Ubuntu, might need modifications for other variations of Unix/Linux/whatever.

Just copy the files into the same directory, make the “.sh” one executable, test them, and if all works fine create a cron job to have them executed regularly.

You also need items for your printers, BrotherPrinter.items:

String  DGOfficePrinterStatus
String  DGOfficePrinterStatusText
Number  DGOfficePrinterBlack
Number  DGOfficePrinterYellow
Number  DGOfficePrinterCyan
Number  DGOfficePrinterMagenta

String  KGOfficePrinterStatus
String  KGOfficePrinterStatusText
Number  KGOfficePrinterBlack
Number  KGOfficePrinterYellow
Number  KGOfficePrinterCyan
Number  KGOfficePrinterMagenta

The item names have to have the hostname of the printer in front, followed by:

  • Status - possible values OK, Warning, Error, Etc
  • StatusText - Textual status description in your local language, as seen on the printer status page
  • Black - ink level (for my printer the maximum seems to be 56, but not completely sure yet)
  • Yellow
  • Cyan
  • Magenta

The main shell script BrotherPrinter.sh:
(the name of your openhabserver needs to be filled in, perhaps also paths to the REST interface modified or for curl/sed/grep corrected)

#!/bin/sh

# set -x

PRINTERNAME=$1

DIR=`dirname $0`
SCRIPT=`basename $0 .sh`

OPENHABSERVER=KGTec1Openhab2Server
OPENHABRESTURL="http://"$OPENHABSERVER":8080/rest/items/"$PRINTERNAME
TEMPFILE=/tmp/$SCRIPT.$$

CURL=/usr/bin/curl
GREP=/bin/fgrep
SED=/bin/sed
CAT=/bin/cat

$CURL -s "http://"$PRINTERNAME"/general/status.html" | $CAT -v | $SED "s#<#\n#g" | $GREP -f $DIR/$SCRIPT.grep | $SED -f $DIR/$SCRIPT.sed > $TEMPFILE
. $TEMPFILE
rm $TEMPFILE

the command file to grep the interesting line from the html BrotherPrinter.grep (note there is a single space after moni):

tonerremain
moni

and a command file to create curl commands using sed BrotherPrinter.sed:

s#.*alt\=\"\(.*\)\" class\=.*height\=\"\([0-9]*\)px.*#\$CURL -s --header \"Content-Type: text/plain\" --request POST --data \2 "\$OPENHABRESTURL"\1#g
s#.*moni\(.*\)\">\(.*\)#\$CURL -s --header \"Content-Type: text/plain\" --request POST --data \"\1\" "\$OPENHABRESTURL"Status\n\$CURL -s --header \"Content-Type: text/plain\" --request POST --data \"\2\" "\$OPENHABRESTURL"StatusText#g

Brief explanation of how/what it does:

BrotherPrinter.sh KGOfficePrinter

it is called with one parameter, the hostname of the printer in question. The item names need to correspond to this hostname as shown in the items file above.

$CURL -s "http://"$PRINTERNAME"/general/status.html" | $CAT -v | $SED "s#<#\n#g"

this line requests the status.html page from the printer using curl, eliminates non-printable characters using cat (there was an issue with german Umlaut and grep), and finally splits the html file into lines - there are for sure better approaches, but again, this works for me. After this the lines I am interested in look like this, although there is far more crap in the output.

.....
dd>
div id="moni_data">
span class="moni moniOk">Bereit
/span>
.....
/tr>
tr>
td>
img src="../common/images/black.gif" alt="Black" class="tonerremain" height="42px" />
/td>
td>
img src="../common/images/yellow.gif" alt="Yellow" class="tonerremain" height="56px" />
/td>
td>
img src="../common/images/cyan.gif" alt="Cyan" class="tonerremain" height="56px" />
/td>
td>
img src="../common/images/magenta.gif" alt="Magenta" class="tonerremain" height="56px" />
/td>
/tr>
.....

then this is reduced only to the interesting lines using

$GREP -f $DIR/$SCRIPT.grep

After this we are getting much closer:

span class="moni moniOk">Bereit
img src="../common/images/black.gif" alt="Black" class="tonerremain" height="42px" />
img src="../common/images/yellow.gif" alt="Yellow" class="tonerremain" height="56px" />
img src="../common/images/cyan.gif" alt="Cyan" class="tonerremain" height="56px" />
img src="../common/images/magenta.gif" alt="Magenta" class="tonerremain" height="56px" />

Using sed:

$SED -f $DIR/$SCRIPT.sed

this is then converted into a temporary shell script:

$CURL -s --header "Content-Type: text/plain" --request POST --data "Ok" "$OPENHABRESTURL"Status
$CURL -s --header "Content-Type: text/plain" --request POST --data "Bereit" "$OPENHABRESTURL"StatusText
$CURL -s --header "Content-Type: text/plain" --request POST --data 42 "$OPENHABRESTURL"Black
$CURL -s --header "Content-Type: text/plain" --request POST --data 56 "$OPENHABRESTURL"Yellow
$CURL -s --header "Content-Type: text/plain" --request POST --data 56 "$OPENHABRESTURL"Cyan
$CURL -s --header "Content-Type: text/plain" --request POST --data 56 "$OPENHABRESTURL"Magenta

which is finally executed inline:

. $TEMPFILE

results can be seen in events.log:

17:18:01.501 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterStatus' received command Ok
17:18:01.501 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterStatus' received command Ok
17:18:01.512 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterStatusText' received command Bereit
17:18:01.518 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterStatusText' received command Bereit
17:18:01.528 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterBlack' received command 42
17:18:01.535 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterBlack' received command 44
17:18:01.545 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterYellow' received command 56
17:18:01.546 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterYellow' received command 56
17:18:01.557 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterCyan' received command 56
17:18:01.558 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterCyan' received command 56
17:18:01.563 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'DGOfficePrinterMagenta' received command 56
17:18:01.571 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'KGOfficePrinterMagenta' received command 56

My printers now show up in habpanel almost nice, but I still have to create something better:

3 Likes

I achieved this with a REGEX on the HTTP Binding. Should be safe to use, but not so nice as a XPath Transform.

UID: http:url:880e01939d
label: Brother MFC-J5730DW (HTTP)
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: false
  baseURL: http://brw30c9ab634f21.fritz.box/general/status.html
  delay: 0
  stateMethod: GET
  refresh: 30
  commandMethod: GET
  contentType: text/xml
  timeout: 3000
  bufferSize: 2048
location: Arbeitszimmer
channels:
  - id: restTonerMagenta
    channelTypeUID: http:number
    label: Resttoner Magenta
    description: ""
    configuration:
      mode: READONLY
      stateTransformation: REGEX:.*alt="Magenta" class="tonerremain" height="(\d+)".*
  - id: restTonerYellow
    channelTypeUID: http:number
    label: Resttoner Yellow
    description: ""
    configuration:
      mode: READONLY
      stateTransformation: REGEX:.*alt="Yellow" class="tonerremain" height="(\d+)".*
  - id: resttonerCyan
    channelTypeUID: http:number
    label: Resttoner Cyan
    description: ""
    configuration:
      mode: READONLY
      stateTransformation: REGEX:.*alt="Cyan" class="tonerremain" height="(\d+)".*
  - id: resttonerBlack
    channelTypeUID: http:number
    label: Resttoner Black
    description: ""
    configuration:
      mode: READONLY
      stateTransformation: REGEX:.*alt="Black" class="tonerremain" height="(\d+)".*

grafik