IPP printer sensors with custom button-card

I agree :slight_smile:

I would do it but my CSS is not so proficient as yours. If you add it please let me know :smile:

With the possibility of having more than one printer, I tried to create a template based on your printer card (so there wouldn’t be so much duplicated code). Either I lack the necessary skills at abstraction (a distinct possibility) or Lovelace/JavaScript/CSS/HTML is allergic to “entity inception.” Whatever the case, I couldn’t get the sub-entities (ink level sensors) to work through a card calling a printer-tile template which in turn calls an inkwell template.
So, instead of your very elegant code for inkwells, I went with a more basic text color coding. The result you can see below, nestled snugly within my UI (which you have been instrumental in helping me create).
tiles

Here's the coding:
  printer-tile:
    color_type: card
    aspect_ratio: 3/2
    variables:
      m1_entity: sensor.epson_wf_3820_series_black_ink
      m2_entity: sensor.epson_wf_3820_series_cyan_ink
      m3_entity: sensor.epson_wf_3820_series_magenta_ink
      m4_entity: sensor.epson_wf_3820_series_yellow_ink
    styles:
      card:
        - background-color: |
            [[[
              if (entity.state == 'idle') return 'grey';
              else return 'yellow';
            ]]]
        - border-radius: 0%
        - padding: 1%
        - color: ivory
        - font-size: 10px
        - text-transform: capitalize
      grid:
        - grid-template-areas: '"n n n m1 m1" "i i i m2 m2" "i i i m3 m3" "stat stat stat m4 m4"'
        - grid-template-columns: 1fr 1fr 1fr 1fr 1fr
        - grid-template-rows: 1fr 1fr 1fr 1fr
      name:
        - font-weight: bold
        - font-size: 13px
        - color: white
        - align-self: middle
        - justify-self: start
        - padding-bottom: 0px
      img_cell:
        - justify-content: start
        - align-items: start
        - margin: 0%
      icon:
        - color: darkSlateGrey
        - width: 70%
        - margin-top: 0%
      custom_fields:
        stat:
          - font-size: 13px
          - align-self: middle
          - width: 70%
          - justify-self: middle
        m1:
          - align-self: middle
          - justify-self: start
        m2:
          - align-self: middle
          - justify-self: start
        m3:
          - align-self: middle
          - justify-self: start
        m4:
          - align-self: middle
          - justify-self: start
    custom_fields:
      stat: '[[[ return `<span>${entity.state}</span>` ]]]'
      m1: |
        [[[
          var level = states[variables.m1_entity].state;
          var color = 'crimson';
          if (level > 10) color = 'yellow';
          if (level > 25) color = 'lightGreen';
          if (level > 50) color = 'white';
          return `<ha-icon icon="mdi:water"
          style="width: 14px; height: 14px; color: black;">
          </ha-icon><span style="color: ${color};">${level}%</span>`
        ]]]
      m2: |
        [[[
          var level = states[variables.m2_entity].state;
          var color = 'crimson';
          if (level > 10) color = 'yellow';
          if (level > 25) color = 'lightGreen';
          if (level > 50) color = 'white';
          return `<ha-icon icon="mdi:water"
          style="width: 14px; height: 14px; color: cyan;">
          </ha-icon><span style="color: ${color};">${level}%</span>`
        ]]]
      m3: |
        [[[
          var level = states[variables.m3_entity].state;
          var color = 'crimson';
          if (level > 10) color = 'yellow';
          if (level > 25) color = 'lightGreen';
          if (level > 50) color = 'white';
          return `<ha-icon icon="mdi:water"
          style="width: 14px; height: 14px; color: magenta;">
          </ha-icon><span style="color: ${color};">${level}%</span>`
        ]]]
      m4: |
        [[[
          var level = states[variables.m4_entity].state;
          var color = 'crimson';
          if (level > 10) color = 'yellow';
          if (level > 25) color = 'lightGreen';
          if (level > 50) color = 'white';
          return `<ha-icon icon="mdi:water"
          style="width: 14px; height: 14px; color: yellow;">
          </ha-icon><span style="color: ${color};">${level}%</span>`
        ]]]

…and here’s how it’s used as a card:

                  - entity: sensor.epson_wf_3820_series
                    name: WF-3820
                    template: printer-tile
                    type: 'custom:button-card'
                    variables:
                      m1_entity: sensor.epson_wf_3820_series_black_ink
                      m2_entity: sensor.epson_wf_3820_series_cyan_ink
                      m3_entity: sensor.epson_wf_3820_series_magenta_ink
                      m4_entity: sensor.epson_wf_3820_series_yellow_ink
2 Likes

That’s a nice looking compact printer display :+1:

I may have to add that to my templates :blush:

Looks absolutely great, to have it in this “small footprint”.
After some “fumbling around” I got the version on the original post working, but think I am missing some “vital hints” to get this minimal version running.

Because if I take the “easy route” and just copy/paste it into the “raw editor” it clearly states that it is not really happy.

Would it be possible to add couple of hints for the newbie I am :wink:

Thanks,

Well, this card also requires the custom:button-card add-on (but if you have the original post working, you already have that). To be more clear on the two segments of code, the first is pasted in very early on in your raw configuration. It could be right after the “button_card_templates:” line or later, but before the

title: Home
views:
  - title: Main

part. (Your config might have a different title or view title.)
The second part goes into one of your views.
As an example, it might look like this:

title: Home
swipe_nav:
  wrap: true
  animate: swipe
views:
  - title: Main
    path: main
    badges: []
    cards:
      - type: grid
        columns: 1
        square: false
        cards:
          - type: grid
            columns: 3
            square: false
            cards:
              - entity: sensor.epson_wf_3829_series
                    name: WF-3820
                    template: printer-tile
                    type: 'custom:button-card'
                    variables:
                      m1_entity: sensor.epson_wf_3820_series_black_ink
                      m2_entity: sensor.epson_wf_3820_series_cyan_ink
                      m3_entity: sensor.epson_wf_3820_series_magenta_ink
                      m4_entity: sensor.epson_wf_3820_series_yellow_ink

The “grid” bits are because my UI has a “phone screen” aspect to it so I put everything into a single vertical box and then parse out the rows in 2, 3, or 4 subdivisions but the point here is that that second bit of code goes into one of your Lovelace views as a card. Let me know if that helps.

Maybe a stupid question but how did you sqeeze them and get the name in it.

First I set up the row as having two columns and then subdivide the first of those into two more columns. That forces the width to 1/4 of the total. Then I set the aspect ratio so that the height matches the other elements in the row. (You’ll see that I do the same thing except with three columns in the first row.)
The way cards work (at least currently) is that the fill the available space so, if I didn’t divide and subdivide like I do, that card would be full width and huge.

Thanks I gonna play with this info.

In some ways, I wish the “container” template would take an aspect ratio (I’ve tried it. It doesn’t.) so I could set the ratio to 2/1, 3/1, or 4/1 based on the number of card I had inside and have the height stay the same. As it is, containers just expand the width to the space you give it, so a 3-container row needs a different aspect ratio on the cards to have the same height as a 4-container row (or a two-container row). I have used 3-container rows, but the cards within those containers look horizontally “squished.” So, instead, I make a 3-card container into a 4-card container with a blank space. (Hint: If you use a grid, you don’t even have to specify a blank card if it’s the last card. It just leaves the extra space. Of course, if you want a “separator” blank card between two visible cards, you have to put it in.)

Thanks for this. I combined it with the conditional card, so that the status and colours are only displayed when it is online.

type: vertical-stack
cards:
  - type: picture-elements
    elements:
      - type: conditional
        conditions:
          - entity: sensor.printer
            state_not: unavailable
        elements:
          - type: state-badge
            entity: sensor.printer
            style:
              top: 24%
              left: 89%
      - type: state-badge
        entity: switch.printer_switch
        style:
          top: 89%
          left: 89%
    image: /local/hp.jpg
  - type: conditional
    conditions:
      - entity: sensor.printer
        state_not: unavailable
    card:
      direction: up
      entities:
        - color: MediumTurquoise
          entity: sensor.printer_cyan_cartridge_hp_cf411x
          name: Cyan CF411x
        - color: MediumOrchid
          entity: sensor.printer_magenta_cartridge_hp_cf413a
          name: Magenta CF413a
        - color: Gold
          entity: sensor.printer_yellow_cartridge_hp_cf412a
          name: Yellow CF412a
        - color: Black
          entity: sensor.printer_black_cartridge_hp_cf410a
          name: Black CF410a
      height: 200px
      positions:
        icon: inside
        title: outside
      max: 100
      min: 0
      padding: 2px
      target: '5'
      type: 'custom:bar-card'
      unit_of_measurement: '%'
      stack: horizontal
      title: HP Color LaserJet MFP M477fdw
      style: |-
        bar-card-title {
          text-shadow: 1px 1px 5px black;
        }
        bar-card-value {
          text-shadow: 1px 1px 5px black;
        } 
1 Like

@quadhammer that looks nice. I hadn’t considered pairing the ink levels with a picture of the printer. It gives me an idea to overlay the ink levels at the bottom of a picture of my printer.

Please post it if you do. I think that would look good with it overlaid down the bottom.

Unfortunately I have a lot going on personally right now, so I’m unlikely to get to it. Feel free to give it a try :slight_smile:

Really like the card. Thanks for sharing. I’ve read about a few people disabling the card when the printer is off. I’ve come up with a different solution:

Add HACS ‘variable’ integration.

Add the following code to configuration.yaml for each cartridge. This way the last known value gets displayed.

var:
  printer_black:
    friendly_name: "Printer Ink Black"
    initial_value: 0
    value_template: >-
      {% if is_state('sensor.canon_ts8000_series_black_bk', 'unknown') -%}
        {{ (states('var.printer_black')) }}
      {%- else -%}
        {{ (states('sensor.canon_ts8000_series_black_bk')) }}
      {%- endif %}
    tracked_entity_id:
      - sensor.canon_ts8000_series_black_bk

Then change the printer card to display var.printer_black.

4 Likes

I have a question about the main card where it says template: inkwell (My question being a novice at this is, where is the actual template: Inkwell stored at for it to know what the code is)

Thank you in advanced.

@FinestDice17, these two posts earlier in the thread should help:

I know this is a bit old, but I love the card.
Can you fill me in on what that switch entity is that dictates the on/off circle in the lower-right of your picture-elements card? I see only 5 entities in the IPP integration: 1 for the printer itself (the idle in your image) and 4 for each of the ink cartridges. Is that switch actually an entity of the printer device or do you have the printer plugged into a separate switch (like a separate zigbee outlet or something)?

@LCMilstein, I assume you are referring to the card @quadhammer posted. I’m just replying to @-mention so they’ll see the question.

1 Like

Yes. Thank you!

Yes, it’s the latter: a Z-Wave switch that my printer is plugged into. So just get rid of the following entity, if you don’t have an automated physical switch that the printer plugs into: