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

@Nerwyn do you have any examples of using card mod to change the colour of the maon tile icon. im playing around with the below, but jjst not finding the right combo

type: tile
entity: climate.izone_beaus_bedroom_ac_zone
icon_tap_action:
  action: toggle
tap_action:
  action: none
name: Beaus
card_mod:
  style: |
    :host {
      {% if states('climate.izone_ac_controller_dining_room') == 'heat' %}
        --tile-color: orange !important;
      {% elif states('climate.izone_ac_controller_dining_room') == 'cool' %}
        --tile-color: red !important;
      {% elif states('climate.izone_ac_controller_dining_room') == 'dry' %}
        --tile-color: green !important;
      {% else %}
        --tile-color: disabled !important;
      {% endif %}
    }

Try changing value_attribute to fan_mode. Attribute fan_modes is a list of possible fan modes, not the current fan mode of the entity.

Try this:

type: tile
entity: climate.izone_beaus_bedroom_ac_zone
icon_tap_action:
  action: toggle
tap_action:
  action: none
name: Beaus
card_mod:
  style: |
    ha-tile-icon {
      {% if states('climate.izone_ac_controller_dining_room') == 'heat' %}
        --tile-icon-color: var(--orange-color) !important;
      {% elif states('climate.izone_ac_controller_dining_room') == 'cool' %}
        --tile-icon-color: var(--red-color) !important;
      {% elif states('climate.izone_ac_controller_dining_room') == 'dry' %}
        --tile-icon-color: var(--green-color) !important;
      {% else %}
        --tile-icon-color: var(--disabled-color) !important;
      {% endif %}
    }

nice thanks~!

4.1.0 has been released!

This version implements a massive overhaul of the templating system. Almost all of the Home Assistant templating extensions have been implemented into ha-nunjucks, my instantaneous synchronous frontend only alternative templating system for Home Assistant. This includes Pythonic datetimes! See the ha-nunjucks README for more information on all of the new templating functions, filters, and tests.

This version also adds a new action - Evaluate JS. If you know how to write JavaScript, you can now do so as an action. Just be careful that you don’t break anything!

1 Like

Hi everyone, i’m stuck with a problem about colors for selector. My aim is to keep the selected button coloured if the automation is ON (and the automation has started by the selector button) and the other button if OFF.
The problem is that i can only change the hover color!

This is my actual code

features:
  - type: custom:service-call
    entries:
      - type: selector
        entity_id: automation.alarma_casa
        options:
          - entity_id: automation.alarma_casa
            tap_action:
              action: perform-action
              perform_action: automation.turn_on
              target:
                entity_id:
                  - automation.alarma_casa
              data: {}
            value_attribute: current
            icon: mdi:shield-lock-outline
            type: button
            styles: |-
              :host {
                {% if is_state("automation.alarma_casa", "on") %}
                --color: red !important;
                {% else %}
                --color: initial;
                {% endif %}
                flex-basis: 200%;
              }
            haptics: false
          - entity_id: automation.alarma_casa
            tap_action:
              action: perform-action
              perform_action: automation.turn_off
              confirmation:
                text: |-
                  Seguro que quieres apagar la alarma?  {{ 'on' if
                   is_state('automation.alarma_casa', 'off') else '' }}
              target:
                entity_id:
                  - automation.alarma_casa
              data: {}
            icon: mdi:shield-off-outline
            type: button
            styles: ''
        styles: |-
          :host  {
            --color: green;
            --icon-color: white;
            --background: grey;
            --background-opacity: 0.1;
            --hover-opacity: 0.8;
            flex-basis:200%
          }
type: tile
entity: automation.alarma_casa
icon: mdi:shield-home-outline
show_entity_picture: false
vertical: false
color: green
hide_state: false

If you see the attached imaged, the hover is working but since the automation is ON, the left button should be coloured too. 
What am i missing?

THanks! 
![Screenshot 2024-10-15 181916|354x283]
![Screenshot 2024-10-15 181916|354x283](upload://fDgg8omNK9BzHtUNQTai25WeFVS.png)


https://streamable.com/sea4h6

Your selector options are missing the option field. You aren’t supposed to style the colors like that based on states, the selector does it for you. You need to set the option field for each selector option (it’s in the configuration UI!) to match the state of the parent entity when you want it highlighted. In your case the first selector option should be on and the second one should be off. I think it should be something like this:

features:
  - type: custom:service-call
    entries:
      - type: selector
        entity_id: automation.alarma_casa
        options:
          - entity_id: automation.alarma_casa
            option: on
            tap_action:
              action: perform-action
              perform_action: automation.turn_on
              target:
                entity_id:
                  - automation.alarma_casa
              data: {}
            value_attribute: current
            icon: mdi:shield-lock-outline
            type: button
            styles: |-
              :host {
                --color: red !important;
                flex-basis: 200%;
              }
            haptics: false
          - entity_id: automation.alarma_casa
            option: off
            tap_action:
              action: perform-action
              perform_action: automation.turn_off
              confirmation:
                text: |-
                  Seguro que quieres apagar la alarma?  {{ 'on' if
                   is_state('automation.alarma_casa', 'off') else '' }}
              target:
                entity_id:
                  - automation.alarma_casa
              data: {}
            icon: mdi:shield-off-outline
            type: button
            styles: ''
        styles: |-
          :host  {
            --color: green;
            --icon-color: white;
            --background: grey;
            --background-opacity: 0.1;
            --hover-opacity: 0.8;
            flex-basis:200%
          }
type: tile
entity: automation.alarma_casa
icon: mdi:shield-home-outline
show_entity_picture: false
vertical: false
color: green
hide_state: false

Also, you accidentally included your screenshots and video in the code block, so we can’t see them.

Hi, Im having problem using fire-dom-event. Using that code in the fire-dom-event on the popup results on error when slider is used, see bellow, but if I use same code on the regular card, works just fine. Seems like the {{ value }} is not picking up correctly.

As a test, If I use {{ value }} as the label on the pop-up, I get " off ", even though the shade is open. If I do the same in the regular card, I get the cover position.

Failed to perform the action cover/set_cover_position. expected int for dictionary value @ data[‘position’]

            tap_action:
              action: fire-dom-event
              browser_mod:
                service: browser_mod.popup
                data:
                  title: Individual Master Shades
                  content:
                    cards:
                      - type: tile
                        entity: cover.master_shades
                        vertical: true
                        features:
                          - type: custom:service-call
                            entries:
                              - type: slider
                                entity_id: cover.master_shades
                                value_attribute: current_position
                                unit_of_measurement: "%"
                                tap_action:
                                  action: perform-action
                                  perform_action: cover.set_cover_position
                                  data:
                                    position: "{{ VALUE }}"
                                  target:
                                    entity_id: cover.master_shades

It seems to be working for me, but I also had to modify your config to remove cards and make the tile card config an object under content instead of a list.

show_name: false
show_icon: true
type: button
icon: mdi:curtains
tap_action:
  action: fire-dom-event
  browser_mod:
    service: browser_mod.popup
    data:
      title: Individual Master Shades
      content:
        type: tile
        entity: cover.master_shades
        vertical: true
        features:
          - type: custom:service-call
            entries:
              - type: slider
                entity_id: cover.master_shades
                value_attribute: current_position
                label: "{{ value }}"
                unit_of_measurement: "%"
                tap_action:
                  action: perform-action
                  perform_action: cover.set_cover_position
                  data:
                    position: "{{ value }}"
                  target:
                    entity_id: cover.master_shades

Yours also work for me. Doing more investigation, on mine the button is nested on the tile. Button with fire-dom works, but once I place under the tile, stop working.

Works:

type: button
show_name: false
show_icon: true
icon: mdi:curtains
tap_action:
  action: fire-dom-event
  browser_mod:
    service: browser_mod.popup
    data:
      title: Individual Master Shades
      content:
        cards:
          - type: tile
            entity: cover.master_shades
            vertical: true
            features:
              - type: custom:service-call
                entries:
                  - type: slider
                    entity_id: cover.master_shades
                    value_attribute: current_position
                    unit_of_measurement: "%"
                    label: "{{ VALUE }}"
                    tap_action:
                      action: perform-action
                      perform_action: cover.set_cover_position
                      data:
                        position: "{{ VALUE }}"
                      target:
                        entity_id: cover.master_shades
            tap_action:
              action: none
            icon_tap_action:
              action: none
        card_mod:
          style: |
            :host {
              --ha-card-border-width: 0px;
              }
        show_header_toggle: false
        type: custom:stack-in-card
        mode: vertical

Doesn’t work:

type: tile
entity: cover.master_shades
tap_action:
  action: none
features:
  - type: custom:service-call
    entries:
      - type: button
        show_name: false
        show_icon: true
        icon: mdi:curtains
        tap_action:
          action: fire-dom-event
          browser_mod:
            service: browser_mod.popup
            data:
              title: Individual Master Shades
              content:
                cards:
                  - type: tile
                    entity: cover.master_shades
                    vertical: true
                    features:
                      - type: custom:service-call
                        entries:
                          - type: slider
                            entity_id: cover.master_shades
                            value_attribute: current_position
                            unit_of_measurement: "%"
                            label: "{{ VALUE }}"
                            tap_action:
                              action: perform-action
                              perform_action: cover.set_cover_position
                              data:
                                position: "{{ VALUE }}"
                              target:
                                entity_id: cover.master_shades
                    tap_action:
                      action: none
                    icon_tap_action:
                      action: none
                card_mod:
                  style: |
                    :host {
                      --ha-card-border-width: 0px;
                      }
                show_header_toggle: false
                type: custom:stack-in-card
                mode: vertical

I also just noticed the {{ value }} is coming from the type: button entity_id, on the nested version. If I add entity_id for the button, that’s what shows in the {{ value }}

Ah I see. It’s because the templates in your fire-dom-event popup config gets rendered beforehand with the values from the parent tile, not the one in the popup.

For browser mod popups, it’s better to place the popup in a separate custom:popup-card, assign it an entity ID, and then use the more-info service targeting that entity ID.

That all being said I’d recommend switching to bubble card for popups as it’s newer, better supported, and it’s popups can be accessed directly from a URL hash which is great for mobile app shortcuts.

1 Like

Thank you! That fixes the problem.