Skip to main content

Fix one of IT support's biggest pain points with a simple HUD.

One of the biggest pain points in working IT is the end user not reporting issues until it is an immediate issue. Printers are particularly a pain, and the software that monitors them is either unnecessarily expensive or tied to their hardware, despite most of those programs simply using SNMP to capture the information you are looking for.

The simplest solution is to use SNMP and output to an email periodically- or as a heads up display to reference as needed. I personally find myself overrun with email- too much distraction while working through other issues, so a Heads Up Display seems like the best route for me. SNMP is fairly consistent where it matters most, and from the hardware I can test (Samsung, Ricoh, Savin, Kyocera) works across multiple manufacturers.

The hardest part is identifying SNMP variables and what they are referencing- once you have that the rest is easy. I was not able to find documentation on it, so this was sorted out by trial and error while referencing the printers' control panels.

Applications you may need to install are:

  • snmpwalk (for retrieving SNMP)
  • bc (for calculating percentages)

This is my bash script to periodically check the status of multiple printers and display them on a table in the terminal. I have it sleep for 5 minutes after scanning completes, just to keep network traffic to a minimum. SNMP isn't a terribly quick protocol, so the more printers you have the longer it takes to run.

#!/usr/bin/env bash

## Purpose: Create a Heads Up Display (HUD) for printer statuses
while :
do
  TABLE=
  if [ "$1" = "location1" ]
  then
    PRINTERS=(\\
      DOC-PRNTR1,192.168.42.11\\
    )
  fi
  if [ "$1" = "location2" ]
    then
    PRINTERS=(\\
      COLOR-PRNTR,192.168.4.11\\
      DOC-PRNTR2,192.168.4.12\\
      )
  fi
  
  # the colors, Duke, the colors!
  red="\\e[0;91m"
  blue="\\e[0;94m"
  green="\\e[0;92m"
  white="\\e[0;97m"
  yellow="\\e[0;33m"
  bold="\\e[1m"
  uline="\\e[4m"
  # I'm color blind, kid.
  reset="\\e[0m"

  for n in ${PRINTERS[@]};
  do
    # break down the variable to basic information needed
    PRINTER=$(echo $n |cut -d"," -f1)
    IP=$(echo $n |cut -d"," -f2)
    # is the printer alive?
    ping -c 1 -W 1 $IP > /dev/null
    if [ ! $? -eq 0 ]
    then
      PRINTER_ALIVE=${blue}
      ModelOID=
      STATUS=
      ALERTS=
      BOTTLE=
      CARTRIDGE=
      CYAN=
      MAGENTA=
      YELLOW=
      BLACK=
      WASTE=
    else
      SNMP=$(snmpwalk -mAll -v1 -On -cpublic $IP)
      PRINTER_ALIVE=${green}
      STATUS=$(echo "$SNMP" |grep ".1.3.6.1.2.1.25.3.2.1.5.1 ="|cut -d":" -f2)
      if [ $(echo $STATUS |grep "warning") ]
      then
        PRINTER_ALIVE=${yellow}
      fi
      if [ $(echo "$STATUS" |grep "error\\|down") ]
      then
        PRINTER_ALIVE=${red}
      fi
      CYAN=
      MAGENTA=
      YELLOW=
      BLACK=
      WASTE=
      for n in $(seq 1 5)
      do
        BOTTLE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n" | cut -d":" -f2 |sed "s/\\"//g;s/^\\ //g")
        CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.12.1.1.4.1.$n" | cut -d":" -f2 |sed "s/\\"//g;s/^\\ //g")
        if [ "$BOTTLE" = "Waste Toner Box" ] || [ "$BOTTLE" = "Waste Toner" ]
        then
          # Waste toner bottle
          WASTE_CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n"|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
          WASTE_CURRENT=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.9.1.$n"|cut -d ":" -f2)
          WASTE_MAX=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.8.1.$n"|cut -d ":" -f2)
          WASTE_LVL=$(echo "scale=0;100*$WASTE_CURRENT/$WASTE_MAX" |bc -s)
          [ "$WASTE_LVL" -lt "11" ] && WASTE=$(echo ${red}$WASTE_LVL ${PRINTER_ALIVE}) || WASTE=$(echo $WASTE_LVL${PRINTER_ALIVE})    
        fi
        if [ "${CARTRIDGE,,}" = "black" ]
        then
          # Black cartridge
          BLACK_CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n"|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
          BLACK_CURRENT=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.9.1.$n"|cut -d ":" -f2)
          BLACK_MAX=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.8.1.$n"|cut -d ":" -f2)
          BLACK_LVL=$(echo "scale=0;100*$BLACK_CURRENT/$BLACK_MAX" |bc -s)
          [ "$BLACK_LVL" -lt "11" ] && BLACK=$(echo ${red}$BLACK_LVL $BLACK_CARTRIDGE ${PRINTER_ALIVE}) || BLACK=$(echo $BLACK_LVL $BLACK_CARTRIDGE ${PRINTER_ALIVE})
        fi
        if [ "${CARTRIDGE,,}" = "yellow" ]
        then
          # Yellow cartridge
          YELLOW_CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n"|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
          YELLOW_CURRENT=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.9.1.$n"|cut -d ":" -f2)
          YELLOW_MAX=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.8.1.$n"|cut -d ":" -f2)
          YELLOW_LVL=$(echo "scale=0;100*$YELLOW_CURRENT/$YELLOW_MAX" |bc -s)
          [ "$YELLOW_LVL" -lt "11" ] && YELLOW=$(echo ${red}$YELLOW_LVL $YELLOW_CARTRIDGE ${PRINTER_ALIVE}) || YELLOW=$(echo $YELLOW_LVL $YELLOW_CARTRIDGE ${PRINTER_ALIVE})
        fi
        if [ "${CARTRIDGE,,}" = "magenta" ]
        then
          # Magenta cartridge
          MAGENTA_CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n"|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
          MAGENTA_CURRENT=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.9.1.$n"|cut -d ":" -f2)
          MAGENTA_MAX=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.8.1.$n"|cut -d ":" -f2)
          MAGENTA_LVL=$(echo "scale=0;100*$MAGENTA_CURRENT/$MAGENTA_MAX" |bc -s)
          [ "$MAGENTA_LVL" -lt "11" ] && MAGENTA=$(echo ${red}$MAGENTA_LVL $MAGENTA_CARTRIDGE ${PRINTER_ALIVE}) || MAGENTA=$(echo $MAGENTA_LVL $MAGENTA_CARTRIDGE ${PRINTER_ALIVE})
        fi
        if [ "${CARTRIDGE,,}" = "cyan" ]
        then
          # Cyan cartridge
          CYAN_CARTRIDGE=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.6.1.$n"|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
          CYAN_CURRENT=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.9.1.$n"|cut -d ":" -f2)
          CYAN_MAX=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.11.1.1.8.1.$n"|cut -d ":" -f2)
          CYAN_LVL=$(echo "scale=0;100*$CYAN_CURRENT/$CYAN_MAX" |bc -s)
          [ "$CYAN_LVL" -lt "11" ] && CYAN=$(echo ${red}$CYAN_LVL $CYAN_CARTRIDGE ${PRINTER_ALIVE}) || CYAN=$(echo $CYAN_LVL $CYAN_CARTRIDGE ${PRINTER_ALIVE})
        fi
      done
  
      ModelOID=$(echo "$SNMP" |grep ".1.3.6.1.2.1.25.3.2.1.3.1 ="|cut -d":" -f2 |sed 's/^\\ //g')
      ALERTS=$(echo "$SNMP" |grep ".1.3.6.1.2.1.43.16.5.1.2.1.1 ="|cut -d":" -f2 |sed 's/^\\ //g;s/\\"//g')
    fi
    TABLE=$(printf "${TABLE}\\n${reset}$PRINTER$PRINTER_ALIVE|$IP|$ModelOID|$CYAN|$MAGENTA|$YELLOW|$BLACK|$WASTE|$STATUS|$ALERTS" |sort)
  done
  
  clear
  # Print the HUD table
  date
  printf "${reset}${uline}${bold}Printer|IP Address|Model|Cyan|Magenta|Yellow|Key|Waste|Status|Alerts${reset}\\n$TABLE${reset}" |column -s '|' -t -T 3,4,5,6,7,8,9,10
  TABLE= 
  sleep 300
done
exit $?

As you can see it is broken down into multiple locations, which I do so if the list gets too long it can be broken down across multiple terminal windows and displays, and for a visual means to sort what I am looking at.

Running printer_hud.sh location1 gives us the output for the printers in the location1 array, printer_hud.sh location2 for location2.

Putting this on a Heads Up display gives me details at a glance if I need to address impending or immediate issues before the end user decides to put in a ticket. Colors are set so I can see from a distance, without needing to read, what I will be looking at for the issue.

Red is error or urgent, yellow is non-urgent or warning, blue is offline, and green is good. This has no printer history- no cache file putting wear on your SSD- so if a printer is offline you won't see the last status.

Example Output:

What do you think of this script? How would you improve it, or has it helped you at work at all? Leave a comment below, or email me if you’d like to discuss more!

graphic that says Adam and shows an exclamation point

Adam Anderson

Systems Administrator by day; ronin illustrator by night. I promote learning the tools in your computer system to complete your work in a more effective way, meanwhile agonizing for hours over an A3 sheet of bristol paper with a 0.03mm pen.