Xerox printer monitoring over SNMP

I have a Xerox WorkCentre 6027 printer, and I decided it’d be fun to be able to monitor it in Hass. I’d toyed with scraping its web interface and then decided SNMP would be simpler. I mean it’s the SIMPLE network monitoring protocol, right? Yah, so simple. Well, five hours and I don’t know how many restarts later, here it is, mostly: it’s properly reporting all four toner levels and the printer’s total page count. I’m going to update it tomorrow with such niceties as the printer’s current status.

sensors.yaml:

- platform: snmp
  name: 'page_count'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.4.1.253.8.53.13.2.1.6.1.20.1
  accept_errors: true
  unit_of_measurement: 'pages'

- platform: snmp
  name: 'prncyanlvl'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.9.1.1
  accept_errors: true

- platform: snmp
  name: 'prncyancap'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.8.1.1
  accept_errors: true

- platform: snmp
  name: 'prnmagentalvl'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.9.1.2
  accept_errors: true

- platform: snmp
  name: 'prnmagentacap'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.8.1.2
  accept_errors: true

- platform: snmp
  name: 'prnyellowlvl'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.9.1.3
  accept_errors: true

- platform: snmp
  name: 'prnyellowcap'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.8.1.3
  accept_errors: true

- platform: snmp
  name: 'prnblacklvl'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.9.1.4
  accept_errors: true

- platform: snmp
  name: 'prnblackcap'
  host: !secret xerox_printer_ip
  baseoid: 1.3.6.1.2.1.43.11.1.1.8.1.4
  accept_errors: true

- platform: template
  sensors:
    cyan_toner_level:
      friendly_name: 'Cyan Toner Level'
      unit_of_measurement: '%'
      value_template: '{{ ((states.sensor.prncyanlvl.state | float) / (states.sensor.prncyancap.state | float)) * 100 | round(1) }}'
    magenta_toner_level:
      friendly_name: 'Magenta Toner Level'
      unit_of_measurement: '%'
      value_template: '{{ ((states.sensor.prnmagentalvl.state | float) / (states.sensor.prnmagentacap.state | float)) * 100 | round(1) }}'
    yellow_toner_level:
      friendly_name: 'Yellow Toner Level'
      unit_of_measurement: '%'
      value_template: '{{ ((states.sensor.prnyellowlvl.state | float) / (states.sensor.prnyellowcap.state | float)) * 100 | round(1) }}'
    black_toner_level:
      friendly_name: 'Black Toner Level'
      unit_of_measurement: '%'
      value_template: '{{ ((states.sensor.prnblacklvl.state | float) / (states.sensor.prnblackcap.state | float)) * 100 | round(1) }}'

and groups.yaml:

  printer:
    name: Printer Status
    entities:
      - sensor.page_count
      - sensor.cyan_toner_level
      - sensor.yellow_toner_level
      - sensor.magenta_toner_level
      - sensor.black_toner_level

and how I customized the icons…is there a better representation of page count and toner levels out there?

  customize:
    sensor.page_count:
      icon: mdi:image-filter-none
    sensor.cyan_toner_level:
      icon: mdi:water
    sensor.yellow_toner_level:
      icon: mdi:water
    sensor.magenta_toner_level:
      icon: mdi:water
    sensor.black_toner_level:
      icon: mdi:water

and the result:
Screenshot_20180902_032354
I believe that these SNMP OIDs should work with any color laser printer, though I’m not completely certain, and I’m equally (un)sure that the black values should work with any monochrome laser printer. I think. Maybe.

6 Likes

I’ve been wanting to do something like this for the longest time, I just didn’t understand SNMP/baseoids.
Thanks for figuring it out!

The page count gives me a really weird number in the ten thousands, but I chalk that up to my printer being a much older model.

I threw them into some Custom-UI tiles.

3 Likes

I dig it! I haven’t taken the plunge into the custom UI yet, nor Lovelace for that matter…gotta get off my duff already.

If you’re on a Linux system, you can do

sudo apt install snmp

and then

snmpbulkwalk -v 2c -c public 192.168.1.183

(replace that IP with your printer’s) and it’ll spew forth every OID that your printer supports. It’s a massive pile, but you could go to the printer’s control panel and get the page count and search through the spewage to find an OID that reports that value. That’s basically how I deciphered what mine was telling me. Replace the ‘iso’ at the beginning with 1 and you’re golden.

Does your page_count value retain if the printer is turned off when HA is restarted, thus the SNMP read fails?

Yes, that value is the printer’s lifetime total page count.

I understand that, but what value is displayed in HA if at HA restart time the printer is switched off (thus the snmp value cannot be read)?

Oh… Lifetime page count? It was right then, lol

I just tested it by taking the printer offline and restarting Hass; it pretty much barfed all over the place and returned a bunch of “unknown” results and divide by zero errors in the log. So it’ll need a little tweaking and error handling before I’d consider it really ready for prime time. The good news is that once I brought the printer back up it did gracefully reconnect and start reporting good values. I’m thinking a ping sensor pointed at the printer and every sensor returns ‘offline’ instead of random junk if the ping shows it’s offline. Ideas?

Also, for some odd reason the printer only reports its status on one OID when it’s awake and on another OID when it’s in standby. Really weird. I’ll have to do some logic in a sensor to return an actual status based on those two OIDs rather than just directly displaying one. Different brands and probably different models most likely behave differently in this regard so I’m sure it’ll be a lot of trial and error.

My latest version in on my GitHub, https://github.com/danbowkley/homeassistant-config if you want to follow along.

Read this blog on the topic HP Printer In Error State 36, I am sure you will get your solution from this blog. I had also the similar issue and through this blog I have resolved my issue.

Nice work!
Do you mind if you could share the code?

It’s mostly on my GitHub, I do need to go in there and update it though.

Solved the lifetime pagecount issue by an automation that triggers on page count change (ignoring unknown when printer is not reachable) pushing the new page count over to a dedicated MQTT topic with retain flag.The sensor displaying the the valid lifetime pagecount subscribes to this dedicated MQTT topic.

Kudos, Cut, Paste, Save, Reboot, Done!

Copy, paste, done… but I get for 1 entity no roudup to 1, the code is exactly as above… why is that?

image

I wish I knew, it sometimes does that to me as well.

It was the order of operation in the template… solved here:

  - platform: template
    sensors:
      cyan_toner_level:
        friendly_name: 'Cyan Toner Level'
        unit_of_measurement: '%'
        value_template: '{{ (((states.sensor.prncyanlvl.state | float) / (states.sensor.prncyancap.state | float)) * 100) | round(1) }}'
        #value_template: "{{ ( states('sensor.prncyanlvl')|float / (states('sensor.prncyancap')|float * 100) )|round(1) }}"
      magenta_toner_level:
        friendly_name: 'Magenta Toner Level'
        unit_of_measurement: '%'
        value_template: '{{ (((states.sensor.prnmagentalvl.state | float) / (states.sensor.prnmagentacap.state | float)) * 100) | round(1) }}'
        #value_template: "{{ ( states('sensor.prnmagentalvl')|float / (states('sensor.prnmagentacap')|float * 100) )|round(1) }}"
        #value_template: "{{ '{:.1%}'.format( states('sensor.prnmagentalvl')|float / (states('sensor.prnmagentacap')|float * 100) ) }}"
      yellow_toner_level:
        friendly_name: 'Yellow Toner Level'
        unit_of_measurement: '%'
        value_template: '{{ (((states.sensor.prnyellowlvl.state | float) / (states.sensor.prnyellowcap.state | float)) * 100) | round(1) }}'
      black_toner_level:
        friendly_name: 'Black Toner Level'
        unit_of_measurement: '%'
        value_template: '{{ (((states.sensor.prnblacklvl.state | float) / (states.sensor.prnblackcap.state | float)) * 100) | round(1) }}'

@Dan_Bowkley I know I’m bumping an old thread, but I just had to say this. I’m no stranger to IT and tech in general (and I’m proficient in YAML too!!), but I am pretty new to Home Assistant.

I haven’t bought any Z-Wave gear or anything, but I just happen to own a Xerox laser printer, so finding this thread made it a perfect test bed for integrating with HA. Fast forward to 2 days later, and I’ve already subscribed to HA Cloud and added more devices to my instance! And now I’m already using your instructions above to sniff the SNMP data on my HP printer too! :joy:

Your post here (as well as your repo on GitHub) was extremely helpful in getting me going with the basics of configuring HA, so thank you!! :grinning:

1 Like

Thank you for sharing your codes here to integrate a Xerox printer. I’ve been able to get the following results with your codes.

Again many thanks for your contribution.

Lovelace code for the printer sections is given 2 posts after.

2 Likes

Cool, can ypu share the lovelace code?

Yes sure I will share it in few mins when i’ll be home.