Bluebells in Smyrton Wood, reused from https://www.geograph.org.uk/photo/3977770

How do you know when you’ve run out of invisible ink?

Written by

in

,

So last week, I shared my Nagios script for checking the pizza orders around the Pentagon and the Whitehouse – and this week, I thought I’d share another of my customised Nagios plugins – again based on scraping the content of a webpage.

It came about because I needed to print something, and the shitty HP inkjet printer we’ve got (seriously, never buy an HP inkjet printer. Never) had run out of ink. You can check the ink levels on the printer LCD itself, or even on the HTTP web page that the printer allows you to scan from – or you can even install a custom HP application on your Windows PC to no doubt keep track of these things. But there’s no way I’m installing that HP bloatware, I’ve made that mistake previously and been inundated with special offers, adverts, sales, and other gumph. All I really care about is “can my printer print?”, so I spent a bit of time poking through the served pages to find if I could easily access the toner levels, and low and behold, I found it.

I now have a Nagios check for my printer ink levels, which works as well as the shitty Windows app they wanted me to install, and doesn’t try to force me into their bloody awful Instant Ink service. I have no idea if it will be of any use at all to anyone else, but on the off-chance it might be, knock yourself out:

#!/usr/bin/env bash

# check_hp_printer_cartridge.sh - Monitor HP inkjet printer cartidge levels
#
# -----------------------------------------------------------------------------
# Description:
#   This script checks the toner cartridge levels for my HP inkjet printer
#   (which is an "HP ENVY Inspire 7900e All-in-One Printer series", FWIW).
#
# Example usage:
#   ./check_hp_printer_cartridge.sh -H 192.168.0.2
# 
# -----------------------------------------------------------------------------
# Requirements:
#   • bash
#   • wget
#
# -----------------------------------------------------------------------------
# Author:		Phil Tanner <phil@philtanner.com>
# Created:		2026-08-29
# Last updated:	2026-08-29
#
# Licence: (MIT licence: https://mit-license.org/)
# Copyright © 2026 Phil Tanner
#
# Permission is hereby granted, free of charge,  to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
# in the Software without restriction,  including without limitation the rights
# to use, copy,  modify, merge,  publish, distribute,  sublicense,  and/or sell 
# copies of  the  Software,  and to  permit  persons to  whom  the  Software is
# furnished to do so, subject to the following conditions:
#
# The above  copyright notice  and this permission notice shall  be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED “AS IS”,  WITHOUT  WARRANTY OF ANY KIND,  EXPRESS OR
# IMPLIED,  INCLUDING  BUT NOT  LIMITED TO THE  WARRANTIES OF  MERCHANTABILITY,
# FITNESS FOR  A PARTICULAR PURPOSE  AND NONINFRINGEMENT.  IN  NO  EVENT  SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE  FOR ANY  CLAIM,  DAMAGES OR OTHER
# LIABILITY,  WHETHER IN  AN ACTION  OF CONTRACT,  TORT  OR OTHERWISE,  ARISING
# FROM,  OUT  OF  OR  IN  CONNECTION  WITH  THE  SOFTWARE OR THE  USE  OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# -----------------------------------------------------------------------------
# Version: 1.0.0
# -----------------------------------------------------------------------------
#
# -----------------------------------------------------------------------------
# TODO:
#   • Get the name of the cartridge from the XML, not assume 806XL
#   • Test for paper levels http://$HOST/DevMgmt/MediaHandlingDyn.xml
# 
# -----------------------------------------------------------------------------


# Nagios exit codes
NAGIOS_OK=0
NAGIOS_WARNING=1
NAGIOS_CRITICAL=2
NAGIOS_UNKNOWN=3

# Default thresholds
WARNING=20
CRITICAL=10

# Parse arguments
while getopts "w:c:H:" opt; do
  case $opt in
    w) WARNING="$OPTARG" ;;
    c) CRITICAL="$OPTARG" ;;
    H) HOST="$OPTARG" ;;
    *) echo "Usage: $0 -H <host> -w <warning> -c <critical>"; exit $NAGIOS_UNKNOWN ;;
  esac
done

if [ -z "$HOST" ]; then
  echo "UNKNOWN - Host not specified"
  exit 3
fi

URL="http://$HOST/DevMgmt/ConsumableConfigDyn.xml"

# Fetch and extract levels
LEVELS=$(wget -q -O - "$URL" | sed -n 's:.*<[^>]*ConsumablePercentageLevelRemaining>\([0-9]\+\)</[^>]*>.*:\1:p')

# Validate that we got at least two values
COUNT=$(echo "$LEVELS" | wc -l)
if [ "$COUNT" -lt 2 ]; then
  echo "UNKNOWN - Could not extract two ConsumablePercentageLevelRemaining values"
  exit $NAGIOS_UNKNOWN
fi

# Extract the first two levels
LEVEL1=$(echo "$LEVELS" | sed -n 1p)
LEVEL2=$(echo "$LEVELS" | sed -n 2p)

# Function to check if a value is a valid number
is_number() {
  echo "$1" | grep -qE '^[0-9]+$'
}

# Ensure both values are numbers
if ! is_number "$LEVEL1" || ! is_number "$LEVEL2"; then
  echo "UNKNOWN - Invalid numeric value(s) detected. Colour='$LEVEL1', Black='$LEVEL2'"
  exit $NAGIOS_UNKNOWN
fi

# Compare levels
STATUS="OK"
EXIT_CODE=$NAGIOS_OK

for LEVEL in "$LEVEL1" "$LEVEL2"; do
  if [ "$LEVEL" -le "$CRITICAL" ]; then
    STATUS="CRITICAL"
    EXIT_CODE=$NAGIOS_CRITICAL
  elif [ "$LEVEL" -le "$WARNING" ] && [ "$EXIT_CODE" -lt $NAGIOS_WARNING ]; then
    STATUS="WARNING"
    EXIT_CODE=$NAGIOS_WARNING
  fi
done

# Output
echo "$STATUS - 804XL Cartridge Levels: Colour ${LEVEL1}%, Black ${LEVEL2}% | Colour=${LEVEL1}%;$WARNING;$CRITICAL;0;100 Black=${LEVEL2}%;$WARNING;$CRITICAL;0;100"
exit $EXIT_CODE

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *