One way to read Epson Eco-Tank Levels

This might be the most redundant integration as you can just look at the ink levels in the semi opaque wells on the front of the printer, but there is a waste ink well (usually called a maintenance box) that will make the printer cease printing if it is full. The maintenance box level is visible through the UI on the printer, or at the web interface. My model is the ET-3760 (might be a made for Costco model), but if your web interface at:

http://your_printer_ip/PRESENTATION/HTML/TOP/PRTINFO.HTML

looks like this:

this method should work for you.

Using the HTTP binding, this is what my thing looks like:

version: 1
things:
  http:url:EpsonPrinter:
    label: Epson Printer
    config:
      baseURL: http://192.168.20.110
      refresh: 30
      timeout: 3000
      delay: 0
      bufferSize: 2048
      authMode: BASIC
      stateMethod: GET
      commandMethod: GET
      contentType: text/html
      ignoreSSLErrors: false
    channels:
      last-failure:
        type: request-date-time
        label: Last Failure
      last-success:
        type: request-date-time
        label: Last Success
      BlackInkLevel:
        type: string
        label: Black Ink Level
        description: ""
        config:
          stateExtension: /PRESENTATION/HTML/TOP/PRTINFO.HTML
          mode: READONLY
      CyanInkLevel:
        type: string
        label: Cyan Ink Level
        description: ""
        config:
          stateExtension: /PRESENTATION/HTML/TOP/PRTINFO.HTML
          mode: READONLY
      MagentaInkLevel:
        type: string
        label: Magenta Ink Level
        description: ""
        config:
          stateExtension: /PRESENTATION/HTML/TOP/PRTINFO.HTML
          mode: READONLY
      YellowInkLevel:
        type: string
        label: Yellow Ink Level
        description: ""
        config:
          stateExtension: /PRESENTATION/HTML/TOP/PRTINFO.HTML
          mode: READONLY
      WasteLevel:
        type: string
        label: Waste Level
        description: ""
        config:
          stateExtension: /PRESENTATION/HTML/TOP/PRTINFO.HTML
          mode: READONLY

As I was testing for Black Ink Level, I did not realize that I was painting myself into a corner using a very specific transformation. Maybe someone more proficient in JS could make this a little cleaner, but I ended up with 5 different transformations that look like this:

(function(input) {
    var match = input.match(/Ink_K\.PNG' height='(\d+)'/);
    if (match && match[1]) {
        var pixels = parseInt(match[1]);
        var maxPixels = 50;
        var percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input)
(function(input) {
    var match = input.match(/Ink_C\.PNG' height='(\d+)'/);
    if (match && match[1]) {
        var pixels = parseInt(match[1]);
        var maxPixels = 50;
        var percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input)
(function(input) {
    var match = input.match(/Ink_M\.PNG' height='(\d+)'/);
    if (match && match[1]) {
        var pixels = parseInt(match[1]);
        var maxPixels = 50;
        var percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input)
(function(input) {
    var match = input.match(/Ink_Waste\.PNG' height='(\d+)'/);
    if (match && match[1]) {
        var pixels = parseInt(match[1]);
        var maxPixels = 50;
        var percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input)
(function(input) {
    var match = input.match(/Ink_Y\.PNG' height='(\d+)'/);
    if (match && match[1]) {
        var pixels = parseInt(match[1]);
        var maxPixels = 50;
        var percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input)

with obviously the ink color as the only difference. The other variable was figuring out that the tank image on the page was roughly 50 pixels in height, then doing the math to get the % value. The rounding is likely not necessary as the page source on my printer shows an integer, but it’s there just in case. My JS is at novice level, but still working to make this one transformation (unless someone beats me to it).

Just add the transformation to the appropriate ink color/waste item.

You can pass arguments to transformations. See JavaScript Scripting - Automation | openHAB for details.

Using this you can pass the color into the transformation and just have the one transformation handle all the colors. Based on a quick scan it looks like there’s really only one letter difference between them all. But you’ll have to construct the regular expression differently.

So the code would look something like

(function(input, color) {
    const regex = new RegExp("Ink_" + color + "\.PNG' height='(\d+)'");
    const match = input.match(regex);
    if (match && match[1]) {
        const pixels = parseInt(match[1]);
        const maxPixels = 50;
        const percentage = Math.round((pixels / maxPixels) * 100);
        return percentage;
    }
    return null;
})(input, color)

and it works be called successfully like

JS:epsonColor.js?color=K

Now I just typed these in from my phone, there may be errors but this should be close enough to get you there.

2 Likes

Thanks for this. I got so wrapped around the axle on pixel height and REGEX solution, I didn’t even recognize the Ink_ pattern. I have other transformations using similar logic, so I should have seen it. Thanks for the help.