Custom Features for Home Assistant Cards - Buttons, Sliders, Selectors, and Spinboxes

Finally got around to looking at this. #dedede is indeed in the inversion of the primary-text-color #212121 from that theme. The next release has a way to set icon and label colors to explicit value rather than just inverting it.

I’ve just released version 3 of Service Call Tile Feature. This release adds jinja2-like templating using nunjucks, and makes some changes to the style options to give the user more control of how styles are set. It also deprecates the icon and label options in favor of more customizable filter options, and completely removes the old string interpolation system (which you’ll have to replace with templates, sorry!).

Because this uses nunjucks to recreate Home Assistant templating, I have to reimplement some of its functions as described in the Home Assistant templating documentation. So far the following functions are implemented:

  • states
  • is_state
  • state_attr
  • is_state_attr
  • has_value
  • iif
  • match_media

Here’s some examples of using templates with this card:

icon: |
  {% if is_state("light.chandelier", "on") %}
    mdi:ceiling-light
  {% else %}
    mdi:ceiling-light-outline
  {% endif %}
label: '{{ (100*state_attr("light.sunroom_ceiling", "brightness")/255) | round or '' }}'
style:
  '--background': |
    {% if is_state("light.chandelier", "on") %}
      rgb({{ state_attr("light.chandelier", "rgb_color") }})
    {% else %}
      initial
    {% endif %}
  '--label-filter': >-
    {{ "invert(1)" if (state_attr("light.chandelier", "rgb_color")
    or []).join(',') == '255,0,0' }}
  '--icon-color': '{{ "var(--disabled-color)" if is_state("input_select.test_select", "C") }}'

Note: You still need to use VALUE for service call data, like in sliders. Trying to grab an entity’s state or attribute using a template will grab a stale value and not the new value you are trying to input.

Looks really nice.
Is there a chance you could add something like this to the buttons, even if its not a service call?

tap_action:
  action: navigate
  navigation_path: /lovelace/

I try to restart an addon (ssh as example).

  - type: custom:service-call
    entries:
      - type: button
        icon: mdi:reload
        label: Addon
        service: hassio.addon_restart
        data:
          addon: a0d7b954_ssh

this doesnt work due to not allowed entity_id in data, using autofill_entity_id: false the button disappears.

The slider doesnt look as nice as the original one. I cannot use the regular one as i need two of them.

  - type: numeric-input
    style: slider
  - type: custom:service-call
    entries:
      - type: slider
        service: input_number.set_value
        entity: input_number.batterie_high
        data:
          value: VALUE

slider

I’m working on adding action support to my other project, and will port the code over after.

It’s entity_id, not entity. Try providing the button with an entity_id (but not in the data/target field). I’m also not sure why it looks so different, which browser are you using?

I changed it, now it shows current value, but same design.

Have you an idea to the disappearing button on autofill_entity_id: false problem?

I use a current firefox.

could you make this default for input number?

      - type: slider
        service: input_number.set_value
        entity_id: input_number.number
        range:
          - '{{ state_attr("input_number.number", "min") }}'
          - '{{ state_attr("input_number.number", "max") }}'
        step: '{{ state_attr("input_number.number", "step") }}'

It would be nice to have some “full” examples per feature type. I had to read this thread and github several times to put it together, as the examples are very complex, omit default values and f.e. input_numbers.
Thats something i miss in a lot of documentation.
Most have a minimum yaml example, but not one including all options, which you can copy and delete the lines you dont need rather then picking all the options out of several tables.

Nevertheless - thank you for your work! :clap:

Have you an idea to the disappearing button on autofill_entity_id: false problem?

Can you make a bug issue for this on the repository? While buttons don’t really need an entity and value but with the way my current logic works it must be throwing an error if it doesn’t have one.

I use a current firefox.

That explains it. Can you make a second separate bug issue for this on the repository? I need to do more development/testing in Firefox. I normally use Brave or the Android app but Firefox is popular enough that it warrants spot testing too.

could you make this default for input number?

Please make a feature issue for this on the repo so I don’t forget!

It would be nice to have some “full” examples per feature type. I had to read this thread and github several times to put it together, as the examples are very complex, omit default values and f.e. input_numbers.

I should add more inline examples for the different configuration sections. It is all very confusing since I’m trying to make it as configurable as possible and have been neglecting learning how to make an actual configuration UI for it. Please make a feature request on the repo for this too?

Is there a way to show the current value when moving a slider? The normal input_number shows this.

Currently I can move the slider and show the chosen value when releasing the slider, but then it is always a guess if you stopped at the correct position that you wanted.

If you make an enhancement issue on the repo I can look into this at a later time.

I try to use buttons for switches, but no matter, what i am trying it dont show the switch on/off colors on the button. How do i need to define them (default colors would be fine)?
The icon changes, but not the colors.

  - type: button
    service: input_boolean.toggle
    target:
      entity_id: input_boolean.full_charge
    entity_id: input_boolean.full_charge
    icon: >-
      {{ iif(is_state("input_boolean.full_charge", "on"),
      "mdi:battery-charging-100", "mdi:battery-charging-50") }}
    style:
      '--color': >-
        {{ iif(is_state("input_boolean.full_charge", "on"), 
        "var(--state-input_boolean-on-color)",
        "var(--state-input_boolean-off-color)") }}
      '--icon-color': >-
        {{ iif(is_state("input_boolean.full_charge", "on"),
        "var(--state-icon-active-color)", "var(--state-icon-inactive-color)") }}

state-input_boolean-on/off-color and state-icon-active/inactive-color probably aren’t defined in your theme. They aren’t in mine (if they don’t exist in a specific theme file the original Home Assistant theme values are used). Using --red-color and --blue-color to test made it work for me.

Merry Christmas! :christmas_tree:

I’ve just released version 3.1.0, which adds actions support. Buttons can now have separate tap, double tap, and hold actions. In addition to service calls most Home Assistant actions are now also supported, like navigate, url, assist, and more-info. See the README in the repo to learn how. While the syntax of configurations has changed to support these new features, old configs should continue to work.

2 Likes

Happy new year :champagne:

Really love this add-on, i always try to stay vanilla, but the tile card missing some functions. So just want to say thanks for your contribution @Nerwyn

2 Likes

Nice! Thanks for this feature!
Is it possible, instead of choosing a mdi logo to a button, to insert a local png picture? I’d like to add radio station buttons with the station logo to my player tile.

Use the built in style options to set the background to an image.

entities:
  - type: button
    tap_action:
      action: more-info
      target:
        entity_id: sensor.fordpass_elveh
    style:
      background-image: url('http://homeassistant.local:8123/local/ford_mme.png')
      background-size: contain
      background-repeat: no-repeat
      background-position: center
      opacity: 1
1 Like

Here the result: Buttons for radio stations including dimmed background for inactive radio stations

type: custom:service-call
entries:
  - type: button
    service: script.beatsradio
    style:
      background-image: url('/local/pictures/beats_radio_breit.png')
      background-size: 120px
      background-repeat: no-repeat
      background-position: center
      mix-blend-mode: >
        {% if is_state_attr('media_player.heos', 'media_station', 'Beats Radio')
        and is_state('media_player.heos', 'playing') %}
          normal
        {% else %} 
          luminosity
        {% endif %}       
      opacity: >
        {% if is_state_attr('media_player.heos', 'media_station', 'Beats Radio')
        and is_state('media_player.heos', 'playing') %}
          1
        {% else %} 
          0.2
        {% endif %}
4 Likes

Great work on this, I can see many uses for it already. Thanks a lot.
Starting out with a simple format but I found I need to include a letter in the label to get this working. Is this intended, did I do something wrong or is it a bug?

type: tile
entity: sun.sun
features:
  - type: custom:service-call
    entries:
      - type: button
        icon: mdi:sun-angle
        label: Q{{state_attr("sun.sun", "elevation")}}

missed comma between flow collection entries (8:51) without the ‘Q’.

For single line templates, you need to wrap the entire thing in quotes, otherwise it gets treated as a malformed object. Adding Q makes it a string instead, which the quotes also do.

1 Like

Mmm, the quotes didn’t work for me.
But in your examples on github I found the solution in adding the >-

type: custom:service-call
entries:
  - type: button
    icon: mdi:sun-angle
    label: >-
      {{ state_attr("sun.sun", "elevation") }}

In the editor this was now changed to single quotes which worked also.

type: custom:service-call
entries:
  - type: button
    icon: mdi:sun-angle
    label: '{{ state_attr("sun.sun", "elevation") }}'

So I should not use the double quotes but the single quotes in this case. Hopefullt this helps someone struggling with the same problem.