HP printer toner level

This plugin provides a text string showing the percentage left of each toner cartridge on HP networked printers, like this:

Black 6 %
Cyan 30 %
Magenta 35 %
Yellow 14 %

Since there are 100s of HP models, it would be impossible to confirm compatibility with each. So trying it would be the best way to see if it works with your model. The only input it needs is the printer ip.

Technical note: the plugin loops through an xml file. I tried pulling specific elements by their name instead, but didn’t find the right syntax for a namespace.

plugin.Name = "HP";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = 3600000;
plugin.DefaultSettings = {};

var http = new HTTPClient();

function onChangeRequest(device, attribute, value) {}

function onConnect() {
    console.log("connected");
}

function onDisconnect() {
    console.log("disconnected");
}

function onPoll() {
    var out = "";
    console.log("polling");
    var response = http.get("http://"+ plugin.Settings["ip"]+"/DevMgmt/ProductUsageDyn.xml");
    var json = response.data;  
    var xml = XML.parse(json);
    xml.elements.forEach(function (node) {
    var id = node.name;
     if (id == "pudyn:ConsumableSubunit")
    {
    node.elements.forEach(function (node2) {
         node2.elements.forEach(function (node3) {
          var id3 = node3.name;
          if ((id3 == "dd:MarkerColor") || (id3 == "dd:ConsumableRawPercentageLevelRemaining"))
          {
            out += node3.text+' ';
           }           
         });
         out += "%\r";
    });
    }
      });          
  var mainDevice = plugin.Devices["hp"];
   mainDevice.status = out;
}

function onSynchronizeDevices() {
}
2 Likes

How does one provide the printer IP when using this plugin?

In the plugin settings.

@torontonian If you were to include “ip” in the DefaultSettings, it would automatically prompt @Murpburgulars for the “ip” when he imports your plugin.

plugin.DefaultSettings = { "ip": "192.168.1.100" }; 
1 Like

Thank you. How do you get the device to show up under the Plugin node? My node “HP” has nothing underneath it, ie: no device. When I try to bind a control to get the value from the plugin, the HP plugin isn’t listed as an available option. There are only choices from my tuner and from THR itself.

What step am I missing?

Screenshot 2021-09-29 211123

With the original code from @torontonian you’ll need to manually create it by right-clicking the plugin. You’ll also need to manually add the “status” attribute to the object & assign it an Id of “hp”. However, in the code below I implemented the onSynchronizeDevices function which will automatically create the object for you when you import the plugin. Here’s the complete code if you want to delete your current plugin & re-import it.

plugin.Name = "HP";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = 3600000;
plugin.DefaultSettings = { "ip": "192.168.1.100" };

var http = new HTTPClient();

function onChangeRequest(device, attribute, value) { }

function onConnect() {
    console.log("connected");
}

function onDisconnect() {
    console.log("disconnected");
}

function onPoll() {
    var out = "";
    console.log("polling");
    var response = http.get("http://" + plugin.Settings["ip"] + "/DevMgmt/ProductUsageDyn.xml");
    var json = response.data;
    var xml = XML.parse(json);
    xml.elements.forEach(function (node) {
        var id = node.name;
        if (id == "pudyn:ConsumableSubunit") {
            node.elements.forEach(function (node2) {
                node2.elements.forEach(function (node3) {
                    var id3 = node3.name;
                    if ((id3 == "dd:MarkerColor") || (id3 == "dd:ConsumableRawPercentageLevelRemaining")) {
                        out += node3.text + ' ';
                    }
                });
                out += "%\r";
            });
        }
    });
    var mainDevice = plugin.Devices["hp"];
    mainDevice.status = out;
}

function onSynchronizeDevices() {
    var printerDevice = new Device();
    printerDevice.Id = "hp";
    printerDevice.DisplayName = "HP Printer";
    printerDevice.Capabilities = [];
    printerDevice.Attributes = ["status"];
    plugin.Devices[printerDevice.Id] = printerDevice;
}
1 Like

Thanks, @bill . Sorry my code was incomplete.

Thank you for your help, I got it working now.
Screenshot 2021-09-30 105132

(and yes, it’s time for a new toner cartridge) :grinning:

1 Like

Glad.
One suggestion: setup the printer to static IP instead of DHCP. Otherwise one day it may land on a different address and your plugin won’t be able to find it.

Always a good suggestion. I have my printer on a static IP. Alternately, I would imagine a hostname could be substituted in for the IP field.

Hello, I installed the plugin. Enter the printer IP. What do I have to do so that I can display the values ​​on my dashboard?
Maybe someone can show an example. Thanks

Greetings Astra

Does nobody have an idea?
Which TileTemplate can I use? Or which triggers do I have to create so that the values ​​are displayed to me?

The plugin just gives you a text string.
Are you sure you have the right IP?
does the printer show an XML at that IP /DevMgmt/ProductUsageDyn.xml ?
does the XML have the nodes the plugin looks for?
You can log the output to the console until you are sure it works fine, before working on sending it to the dashboard.
Hope this helps.

Hello, thank you for the answer. yes I get an answer when I enter IP /DevMgmt/ProductUsageDyn.xml. I think that’s where the answers are after the plugin is looking.
But how do I create the corresponding data or event triggers so that I can display them?

Hello, I made it.
I’ve created the 2 corresponding data triggers and it’s working. Thanks

1 Like