Custom Component for printer ink levels

Hi, I also found snmp doesn’t provide you with the ink levels on the OfficeJet 3830.

Not sure how reliable it is at the moment, but I found that the ink percentage levels are exposed in an xml file which can be found on the printer:

ip_address_of_printer/DevMgmt/ConsumableConfigDyn.xml

You’ll find two entries (one for each cartridge)… and it looks something like:

<dd:ConsumablePercentageLevelRemaining>20</dd:ConsumablePercentageLevelRemaining>

In the end, I crudely wrote a python script to query the xml file and pull the values back via a sensor.

config i made in my sensors.yaml:

- platform: command_line
  name: HP Printer Status
  json_attributes:
    - CartridgeLevel0
    - CartridgeLevel1
    - CartridgeColour0
    - CartridgeColour1
  command: 'python3 /config/get_hp_info.py'
  value_template: '{{ value_json.state }}'
  scan_interval: 300

The script I created was (this needs to be put in a file called get_hp_info.py and potentially given execute permissions via chmod). The file needs to be stored in the folder /config/.

#!/usr/bin/python3

import urllib.request
import urllib.parse 
import xml.etree.ElementTree as ET 
from urllib import request 

id_req1 = urllib.request.urlopen('http://xxx.xxx.xxx.xxx/DevMgmt/ConsumableConfigDyn.xml')
id_req2 = urllib.request.urlopen('http://xxx.xxx.xxx.xxx/DevMgmt/ProductStatusDyn.xml')

id_req1_content = id_req1.read()
id_req2_content = id_req2.read()

output = ""

#
# Gather PRODUCT related information i.e. status
#

root2 = ET.fromstring(id_req2_content)

ns2='http://www.hp.com/schemas/imaging/con/ledm/productstatuscategories/2007/10/31'

for index, i in enumerate( root2.findall('.//{%s}StatusCategory' % ns2)):
    if index == 1:
        output = "{ \"state\":\"" + i.text + "\", "
#        print( index,i.text)


#
# Gather CONSUMABLES related information i.e. cartridges (logic below assumes 2 cartridges - otherwise JSON will be badly formatted with missing ,'s)
#

root1 = ET.fromstring(id_req1_content)

ns1='http://www.hp.com/schemas/imaging/con/dictionaries/1.0/'

for index, i in enumerate( root1.findall('.//{%s}ConsumablePercentageLevelRemaining' % ns1)):
    output += "\"CartridgeLevel"+str(index)+"\":\"" + i.text + "\", "
#    print( index, i.text)
for index, i in enumerate( root1.findall('.//{%s}ConsumableLabelCode' % ns1)):
    output += "\"CartridgeColour"+str(index)+"\":\"" + i.text + "\""
    if index == 0:
        output += ", "
#    print( index, i.text)

output += "}"

print(output)

Hope thats useful, I know it’s a hack! :slight_smile:

1 Like