Custom Component for printer ink levels

Thanks for sharing this. Working fine for my HP Envy 4526.
Was using this MQTT solution, but your solution is way easier and also has the page count :grinning:

1 Like

no probs - happy to share

There is lots of info on those xml pages, you can grab whatever you want :wink:

1 Like

I think it’s even possible without a python script, just a template sensor, that parses xml?

Didn’t think you could parse XML with the scrape sensor, have you an example ?

not sure, i just did a seach on community
this for example :

      - platform: scrape
        resource: http://USERNAME:PASSWORD@IP:PORT/xml/ix.xml
        select: "ds2"
        value_template: '{{ (value | int) / 10 }}'
        unit_of_measurement: "°C"
        name: Zgoraj-T

copy pasted from here : Scrape Sensor - XML reading

Great thanks, sure I tried a while back and couldn’t get it working, I’ll have another look

@hijinx, looks amazing i tried using the card, and i get the following :


              - type: custom:vertical-stack-in-card
                title: HP OfficeJet 3830
                  - type: custom:bar-card
                    columns: 3
                    direction: up
                      - color: Black
                        entity: sensor.ink_black_level
                      - color: Color
                        entity: sensor.ink_color_level
                      - color: Gold
                        entity: sensor.pagecount
                      - color: Black
                        # entity: sensor.canon_mg5300_black_ink_level
                      # - color: Black
                        # entity: sensor.canon_mg5300_photoblack_ink_level
                    height: 200px
                    max: 100
                    min: 0
                    padding: 2px
                    target: 20
                    title_position: bottom
                    icon_position: inside
                    unit_of_measurement: '%'
                    width: 100%

in lovelace:

Any idea?

need to comment the last - color: Black I think

1 Like

Let us know how you get on with using scrape to do it. Would be great to get rid of the python script if we don’t need it.

The challenge may be that you have the two different values with the same element name. From that example I read, it assumes the name is unique.

I’m trying to get this working for my color laser jet m175nw and I keep getting “remote end closed connection without response” even from the command line (not just through HA) . It seems to have all the exact pages and title/heading names as the other printers so I thought it would work… any ideas why it might be refusing the connection through urllib?

(homeassistant) homeassistant@hassnuc:~/.homeassistant$ python3 ./
Traceback (most recent call last):
  File "./", line 8, in <module>
    id_req1 = urllib.request.urlopen('')
  File "/usr/local/lib/python3.7/urllib/", line 222, in urlopen
    return, data, timeout)
  File "/usr/local/lib/python3.7/urllib/", line 525, in open
    response = self._open(req, data)
  File "/usr/local/lib/python3.7/urllib/", line 543, in _open
    '_open', req)
  File "/usr/local/lib/python3.7/urllib/", line 503, in _call_chain
    result = func(*args)
  File "/usr/local/lib/python3.7/urllib/", line 1345, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/local/lib/python3.7/urllib/", line 1320, in do_open
    r = h.getresponse()
  File "/usr/local/lib/python3.7/http/", line 1321, in getresponse
  File "/usr/local/lib/python3.7/http/", line 296, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.7/http/", line 265, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

this happens with the version with the 3rd request for page count also (i thought maybe the 3 requests were coming too quickly and it was some sort of connection/rate limit)

It could be that this script doesn’t work for your laser printer - it’s dependant on the availability of some XML flles which it parses.

Easiest way to check - is to use your browser - and enter the following url:

Do you get a XML output? If you get an error message - then the printer either doesn’t have them or something else doesn’t allow you.

Simple other question - is your Raspberry PI on the same subnet?

Yes, in a browser I get an xml file at all 3 of those pages referenced, with fields named the same for product status, consumable percentage, etc. (don’t have the exact names off hand on mobile now, but they matched)

Yes they are on the same subnet.

you changed IP addresses in that .py file?

Yes I did you can see that in the error message also.


So stepping back a bit - are you running a Hassio instance of Home Assistant, or something else?

Also - from a quick skim using Google - are you experiencing any network issues on your network?

Do you have Wireless Isolation set on your router? Does that make a difference?


Home Assistant in a Venv
All on same network/router
And no network issues that I’m aware of… here is a screenshot from my HA machine opening that url directly from browser. Excuse the mobile screenshot I’m at work…

Messing around a little last night I get a curl command to return the xml file so i thought maybe urllib was out of date but I updated it with no change to result

Yeah - regarding the URLLib bit - that’s where my head was at, but you are on Python 3.7 - so assumed you were up to date.

I originally wrote a script which used Curl & xmllint and then used bash to pull it all together. But when I ran it through HA, it couldn’t find the Curl / xmllint at run time - so I moved it to Python instead.

So I suppose that could be another way of doing it?

Also… I’ve noticed that the namespaces you have for the XML file are subtly different, so the script would need to be updated as well. But, I don’t think that error message (which is on the urlopen) would cause that problem.

This is when I tried using scrape and command line with XML and failed:

Thats what I got, which forced my hand to switch to Python.