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

I have version 4.7.2, the latest version. This slider behaves strangely, with such a delay in determining its state. Standard sliders with HA don’t have this problem.

  - type: custom:service-call
    entries:
      - type: slider
        entity_id: media_player.sonos_woonkamer
        tap_action:
          action: perform-action
          target:
            entity_id: media_player.sonos_woonkamer
          perform_action: media_player.volume_set
          data:
            volume_level: "{{ value / 100 }}"
        range:
          - 0
          - 100
        step: 0
        haptics: true
        value_attribute: volume_level
        icon: null
        thumb: flat
        ticks: false
        label: "{{ value | float }}%"
        value_from_hass_delay: 1000
    styles: ""
type: custom:mushroom-template-card
primary: Sonos Woonkamer
icon: mdi:music
features_position: bottom
tap_action:
  action: navigate
  navigation_path: "#woonkamer"
secondary: >-
  Volume: {{ (state_attr('media_player.sonos_woonkamer', 'volume_level') | float
  * 100) | round }}%
grid_options:
  columns: 12
  rows: 2

This is my config. Im using mushroom though… But wit the custom feature row. Shouldnt make a difference right?

Media player volume is from 0 - 1, not 0 - 100. You may have changed the range of the slider and the value being set in the action, but you cannot change the actual value of the slider which is still from 0 - 1.

Change the range to [0, 1], step to 0.01 (or something less granular), and data.volume_level to “{{ value }}”. You can change the label and tooltip display using a template if that’s why you didn’t use the correct range.

:host {
  --tooltip-label: '{{ (value * 100) | int }}%';
}

But did you just install it or did you already have an older version installed? Because when I changed the name from Android TV Card to Universal Remote Card a lot of users got stuck on an old version due to it not being uninstalled by HACS when updating to a newer version.

I didn’t have the “Universal Remote Card” installed before. I just installed it for the first time, and it’s the current version, 4.7.2.

Thank you very much for the great custom card.

I have a question about your example 7 A read-only timer display …
I’m trying to make the time run backwards at the front (first button), e.g. from 5:00 to 0:00, and move the slider from completely filled to empty accordingly.

But I just can’t get it to work and would be grateful for any help.

Try these styles:

input,
.thumb {
  scale: -1 1;
}

Thank you very much! That works, and the slider now runs from full to empty. From left to right. Is there still a way to reverse the direction, from right to left?

And if you’ll allow me to ask a second question, the countdown in the first button called as label count down backwards, for example from 5:00 to 0:00?

Okay, with the following CSS styles for the slider, I managed to make the slider run from right to left:

:host {
  flex-basis: 1200%;
  height: 10px;
  --color: {{ "rgb(255, 193, 7)" if is_state(config.entity, 'active') else "rgb(158, 158, 158)" }};
  --thumb-width: 1px;
  direction: rtl;
}
input,
.thumb {
  transform: scale(-1);
}

Result:
IMB_7kqgYa

What I can’t figure out is how to make the time count down instead of up at the front. Like a countdown. Just like the tile card does with timers.

I need help here with how to calculate remaining from duration and elapsed.

This is the code for the front counter, as shown in Example 7 from the documentation.:

type: button
value_attribute: elapsed
styles: |-
  :host {
    overflow: visible;
    height: 12px;
    border-radius: 0px;
    --color: none;
  }
label: |-
  {% set minutes = (value / 60) | int %} 
  {% set seconds = (value - 60 * minutes) | int %} 
  {{ minutes }}:{{ 0 if seconds < 10 else "" }}{{ seconds | int }}
entity_id: timer.testtimer

2 Likes

I tried it hour after hour. It seems impossible; the label area obviously does not have proper access to the state and therefore cannot retrieve other attributes. So you can’t calculate duration minus elapsed. You can only access the value_attribute here, in this case elapsed. I may be overlooking something, but it looks that way.

Incorrect, the label has the same access as any other template in this card. You just have to do some parsing using the ha-nunjucks as_timedelta method provided by ts-pydatetime.

{% set t = as_timedelta(state_attr(config.entity, "duration")).seconds - value %}
{% set minutes = (t / 60) | int %}
{% set seconds = (t - 60 * minutes) | int %}
{{ minutes }}:{{ 0 if seconds < 10 else "" }}{{ seconds }}
1 Like

Wonderful! That works, thank you very much. I said that I was probably overlooking something. Templates aren’t that easy either. :sweat_smile:

Now everything is working perfectly and as desired. Thanks again.:pray:t2:

Version 4.7.0 is for Material Design fans! Buttons and selectors now have new Material Design 3 variants. Like the Material Design 3 variants of other features, they work best with (shameless plug) Material You Theme and Utilities but should work with any theme.

4 Likes

Can we have feature added to mimic the stacked bar, as one used in disk metrics statistics?


I believe this is functionally lots of people search for and I’ve never seen a real solution to this…

Hello,

Is it possible to change the text size and color independently per line?
I saw that there’s “.label,” but that applies the changes to the entire content of the label.

type: tile
grid_options:
  columns: full
entity: sensor.micro_onde_fonctionnement_daily
name: Micro-onde
color: light-blue
vertical: false
features:
  - type: custom:service-call
    entries:
      - type: button
        entity_id: sensor.micro_onde_fonctionnement_daily
        label: |-
          {{ states('sensor.cout_journalier_micro_onde') }} €  
          {{ states('sensor.consommation_journaliere_micro_onde') }} kWh
        styles: |-
          .label {
            text-align: center;
          }
        haptics: false
        value_attribute: status
features_position: inline


Do something like this:

You can add labels with different designs using CSS before and after pseudo-elements. This issue has a great example of how to do so:

.label {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 1.1em;
  line-height: 1;
  position: relative;
}

.label::before {
  content: "Heute";
  font-size: 0.75em;
  color: #888;
  margin-bottom: 0.3em;
}

.label::after {
  content: "kWh";
  font-size: 0.65em;
  color: #888;
  margin-top: 0.2em;
}

Thank you very much, it works!! I couldn’t do what I wanted with multiple-entity-row, with your card it will make my task much easier.

type: tile
grid_options:
  columns: full
entity: binary_sensor.micro_onde_activation
name: Micro-onde
icon: mdi:microwave
color: light-blue
hide_state: false
vertical: false
features:
  - type: custom:service-call
    entries:
      - type: button
        entity_id: sensor.micro_onde_fonctionnement_daily
        label: |+

        styles: |-
          .label {
            display: flex;
            flex-direction: column;
            align-items: center;
            font-size: 1.1em;
            line-height: 1;
            position: relative;
          }

          .label::before {
            content: "{{ states('sensor.nombre_d_activations_micro_onde_aujourd_hui') }} fois"  ;
            font-size: 0.75em;
            color: #888;
            margin-bottom: 0.3em;
          }

          .label::after {
            content: "{{ states('sensor.duree_totale_micro_onde_formatee_jour') }}";
            font-size: 0.80em;
            color: #2196f3;
            margin-top: 0.2em;
          }
        haptics: false
        value_attribute: status
      - type: button
        entity_id: sensor.micro_onde_fonctionnement_daily
        label: |+

        styles: |-
          .label {
            display: flex;
            flex-direction: column;
            align-items: center;
            font-size: 1.1em;
            line-height: 1;
            position: relative;
          }

          .label::before {
            content: "{{ states('sensor.cout_journalier_micro_onde') }} €"  ;
            font-size: 0.75em;
            color: #888;
            margin-bottom: 0.3em;
          }

          .label::after {
            content: "{{ states('sensor.consommation_journaliere_micro_onde') }} kWh";
            font-size: 0.80em;
            color: #2196f3;
            margin-top: 0.2em;
          }
        haptics: false
        value_attribute: status
features_position: inline

Thank you very much again !

1 Like

Hello,

How can I remove decimals from the input?

type: input
entity_id: input_number.volet_parental_offset_sunset
tap_action:
  action: perform-action
  perform_action: input_number.set_value
  data:
    value: '{{ value | float }}'
  target:
    entity_id: input_number.volet_parental_offset_sunset
range:
  - -200
  - 200
styles: ':host {flex-basis: 200px;}'
unit_of_measurement: min
thumb: number
step: 1

and here is my input_number in my file conf.yaml :

input_number:
  volet_parental_offset_sunset:
    name: Décalage volet parental coucher soleil (minutes)
    min: -200
    max: 200
    step: 1
    unit_of_measurement: "min"

Copie d'écran_20251029_122204

Thanks.

That’s a bug, it shouldn’t appear when step size is an integer. I’ll fix it in the next patch.

1 Like

Great, I thought I missed an option! Now the number is displayed as expected, thank you again for your work and your speed fix bug.

1 Like