Lovelace: Button card

I think I found a solution:

type: custom:button-card
show_state: false
entity: light.obk613fbff1_64
variables:
  lock_enabled: |
    [[[ return ['on'].includes(states['input_boolean.test'].state) ]]]
lock:
  enabled: |
    [[[ return variables.lock_enabled ]]]

Here is an error.
Must be:

      enabled: '[[[ return (entity.state === "on"); ]]]'

or

      enabled: >-
        [[[ return (entity.state === 'on'); ]]]

or

      enabled: >-
        [[[ return (entity.state === "on"); ]]]
1 Like

Hi,

What am i doing wrong?

Regards,
Vincent

Start with fixing an indentation - either add an indentation for the 1st line or remove indentations for other lines.

Iā€™m trying to use this awesome control, but I canā€™t get the Javascript part to work. Consider this example:

          - type: 'custom:button-card'
            entity: media_player.denon_avr_S660H
            name: >
              [[[
                return ("custom_label");
              ]]]
            show_name: true

In the above example the button renders correclty with custom_label as its label.

In the next example the button doesnā€™t render at all, no errors oin the log or in the browser:

          - type: 'custom:button-card'
            entity: media_player.denon_avr_S660H
            name: >
              [[[
                return (states["media_player.denon_avr_S660H"].state);
              ]]]
            show_name: true

I tried it with different browsers/machines/OSs, but all have the same result.

Any idea what is going on?

Check again, works in my setup:

1 Like

Indeed, it works. It seems to be late as I simply made a typo in the entity nameā€¦ Correcting that resolved my issueā€¦

Good day.

Looking for some guidance. How to prevent the icon background from spilling outside the card?

I tried - overflow: hidden !important unsuccesfully.

Thank you

Edit: sorted.
The overflow: hidden needs to be added to the card style. I was mistakenly adding it to the img_cell.

is it possible to disable the button after power on?
I tried this code but it doesnā€™t work.
I turn on a NAS with wake on lan and when it turns off the ā€œturn offā€ is sent via HTTP from the NAS itself.

Thanks

entity: switch.nas
type: custom:button-card
template: xxxxxx
name: NAS
icon: mdi:laptop
state:

  • value: ā€˜onā€™
    tap_action:
    action: none
  • value: ā€˜offā€™
    tap_action:
    action: toggle

It is possible to spin/blink icons under custom_fields?

How do I turn this beauty :innocent:

with this code:

type: custom:button-card
aspect_ratio: 4/1
entity: input_boolean.dusche_automation
show_state: false
icon: mdi:thermometer-plus
name: Bad vorheizen
state:
  - value: 'on'
    color: teal
  - value: 'off'
    color: grey
custom_fields:
    card:
      type: custom:button-card
      entity: timer.2h_heizung_bad_timer
      show_state: true
      show_name: false
      size: 30px
      margin-right: -30px

into something like this?

The button triggers the helper, which triggers an automation to pre-heat my bathroom. When the button isnā€™t active, the timer shouldnā€™t run.

The button & automation logic works, however I am unable to add the timer to work & look nice on the button.

Any help for someone who cannot code at all would be really cool.

Thanks much! I am happy to share my final result.

not sure if you every received a reaction for this - this is one of the best and most consistent designs I have seen so far. Amazing work!

1 Like

Not sure why but text keeps getting cut and only half of it shows up in running line. Padding is set to 0 in ā€œNameā€ and ā€œCardā€ tabs.

Screen_Recording_20230110_145429_Home Assistant

Anyone haveidea how I can extend line so whole text shows up without decreasing font size?

type: custom:button-card
template: header_red
name: |
  [[[
   return "Today is " + states['sensor.currentweek'].state + ",  " + states['sensor.currentmonth'].state + " Bla bla bla";
  ]]]
styles:
  card:
    - padding: 0%
  name:
    - animation: myA 6s linear 0s infinite normal both
    - padding: 0%
    - font-familly: Raleway
    - font-size: 200%
extra_styles: |
  @keyframes myA {
      0% {
          transform: translate(450px, 0px);
      }


      100% {
          transform: translate(-500px, 0px);
      }
  }

Thank you.

Hi,

I am trying to get a timer added to a lock button as a notification. I had alot of issues getting the timer to show up in realtime. I found a couple of posts to make the timer work - but only with the built-in formatting. I would like to display a timer as seconds only, not the hh:mm:ss format.

Below is the template I have for button cards that have a timer. If I remove the state_display part it display the timer in realtime counting down, but it does not work if I keep it in.

@RomRider : Perhaps you have a solution?

Here is the partial template relevant to the timer (the main template for the rest of the button shouldnā€™t be needed to helpā€“but lmk).

lock_button_timer:
    template: lock_button
    variables:
      timer: null
    styles:
      custom_fields:
        notification:
          - position: absolute
          - left: 65%
          - top: 10%
    custom_fields:
      notification:
        card:
          type: custom:button-card
          name: Timer
          entity: '[[[ return variables.timer ]]]'
          show_name: false
          show_icon: false
          show_state: true
          state_display: >
            [[[
              if (!variables.timer || states[variables.timer].state == 'idle') return ' ';

              let remainString = variables.timer ? states[variables.timer].attributes.remaining : null;
              if (!remainString) {
                return ' ';
              }
              let remainAr = remainString.split(':');
              return (+remainAr[0]) * 60 * 60 + (+remainAr[1]) * 60 + (+remainAr[2]);
            ]]]
          state:
            - value: 'idle'
              styles:
                card:
                  - background: none
                  - border: none
          styles: 
            card:
              - font-size: 14px
              - background-color: '#FF9800'
              - height: 28px
              - width: 28px
              - border-radius: 50%
              - font-size: 14px
              - line-height: 26px
            state:
              - color: black
              - font-weight: 500

I know there is some custom javascript in the custom:button-card to handle timers specifically, but canā€™t figure out how to refer/access the functionality (the typescript has it as private functions, so doubtful).

Here is what it looks like now with 1 min and 13 seconds, when I remove the templated state_display codeā€“the example is cut off, but it displays as 1:13:
Screen Shot 2023-01-10 at 6.50.37 PM

Here is what I want it to look like:
Screen Shot 2023-01-10 at 6.51.01 PM

1 Like

Hi All,

I put together a set of Button Card templates that require minimal config but have some great features and still allow further customisation with any of the button-card properties youā€™re already using. As we all know, Button Card is incredible but itā€™s a Swiss Army Knife. I created these templates for when you just need a simple bread knife but wouldnā€™t mind being able to turn it into a Swiss Army Knife if the situation calls for it.

And so, without any further bad knife analogies, please check out the post here and your feedback is welcome.

Creative Button Card Templates for Lovelace Dashboards

cbc-samples-animated

Samples above are in the default dark theme but the templates should work with just about any theme. I use Noctis, thereā€™s a sample of one of my dashboards in the post.

2 Likes

Answering my own question ā€“ I found a hacky way to get this working. Iā€™d prefer a more direct method, so still open for a better way to achieve the ability to modify the format of the entity state and still have the per-second update.

I am utilizing the ___timeRemaining property (thatā€™s populated specifically to handle timer entities in custom:button-card) on the timer button-card object. Because itā€™s a nested button-card, I also had to pull out the nested card into its own template. Seems to be working now:

  timer:
    show_name: false
    show_icon: false
    show_state: true
    state_display: >
      [[[
        if (!entity || entity.state == 'idle') {
          return ' ';
        }
        return Math.ceil(this.___timeRemaining)
      ]]]
    state:
      - value: 'idle'
        styles:
          card:
            - background: none
            - border: none
    styles: 
      card:
        - font-size: 14px
        - background-color: '#FF9800'
        - height: 28px
        - width: 28px
        - border-radius: 50%
        - font-size: 14px
        - line-height: 26px
      state:
        - color: black
        - font-weight: 500
  lock_button_timer:
    template: lock_button
    variables:
      timer: null
    styles:
      custom_fields:
        notification:
          - position: absolute
          - left: 65%
          - top: 10%
    custom_fields:
      notification:
        card:
          type: custom:button-card
          template: timer
          entity: '[[[ return variables.timer ]]]'

Hi again All,

Sorry if Iā€™m spamming the thread here. I just finally got around to releasing all this stuff.

So if youā€™re building Button Cards in VS Code (likely if you run your dashboards in YAML mode) and, like me, having debugging and code quality issues because thereā€™s no syntax highlighting for Javascript templates in triple square brackets ([[[ ā€¦ ]]]) then hopefully this improves your experience as much as it did mine!

Just search for ā€œButton Cardā€ in VS Code* extensions panel or marketplace.
*Also published to Open VSX so it can be found in code-server versions of VSCode such as the one you can install in Home Assistant

Button Card Javascript Syntax Highlighting for VSCode

  • Syntax highlighting provided using built-in Javascript grammar
  • ā€œDouble quotedā€ and block YAML strings supported
  • Works with the standard YAML language and the home-assistant YAML language created by the Home Assistant Config Helper plugin.

I made this while I was working on Creative Button Card Templates and could not handle writing any more JS without syntax highlighting. Hopefully it gives someone else the same relief it gave me.

Preview

4 Likes

@wjf Amaizing!!! Thank you!

I think that one or the other will be able to do something with it.

1 Like

This is awesome! Thank you so much!

1 Like

Iā€™m curious, is there a way to target specific attributes from a sensor template?
Iā€™ve managed to set up a sensor template which will create the texts I need.
One of the two is a ā€œNameā€ attribute, and the other a ā€œStateā€ attribute :

sensor:
  - unique_id: greet
    state: template
    attributes:
      name: >
        {% set time = now().hour %}
        {% if time <= 1 %} Good night 
        {% elif time <= 3 %} Good night 
        {% elif time <= 5 %} Good night 
        {% elif time <= 7 %} Good morning 
        {% elif time <= 9 %} Good morning 
        {% elif time <= 10 %} Good morning 
        {% elif time <= 13 %} Good afternoon 
        {% elif time <= 15 %} Good afternoon 
        {% elif time <= 17 %} Good afternoon 
        {% elif time <= 19 %} Good evening 
        {% elif time <= 22 %} Good evening 
        {% elif time <= 23 %} Good evening
        {% else %} Good evening
        {% endif %}
      state: >
        
        {% set entity_id = 'alarm_control_panel.master' %}
        {% if is_state(entity_id, 'disarmed') %}
          Alarm system is: <font color='red'>{{ states("alarm_control_panel.master") }}</font>.
        {% else %}
          Alarm system is: <font color='green'>{{ states("alarm_control_panel.master") }}</font>.
        {% endif %}

And they show up perfectly!
However, they only apply the styles for the ā€œCardā€ and the ā€œNameā€

  name: >
    [[[
      if (entity) {
        let attr = [];
        for (let [k, value] of Object.entries(entity.attributes))
          window.navigator.userAgent.match(/iPhone/i)
            ? k !== 'time' && k !== 'date' && value !== false && (attr += `<p>${k === 'greet' ? `<span class="iphone">${value}</span>` : `${value}`}</p>`)
            : value !== false && (attr += `<p>${value}</p>`);
        return attr;
      }
    ]]]
  styles:
    card:
      - background: none
      - border: none
      - box-shadow: none
      - padding: "1em"
    name:
      - justify-self: "start"
      - font-size: "3.5rem"
      - font-weight: "100"
      - font-family: "Merriweather"
      - line-height: 10%
    state:
      - font-size: "1rem"
      - font-family: "Raleway"

the state style is not applied as the second line of text should be much smaller and a different font:

Did I miss something, or we canā€™t target attributes of a sensor?

EDIT
I found the solution:

Sensor:

sensor:
  - unique_id: greet
    state: template
    attributes:
      name: >
        {% set time = now().hour %}
        {% if time <= 1 %} Good night 
        {% elif time <= 3 %} Good night 
        {% elif time <= 5 %} Good night 
        {% elif time <= 7 %} Good morning 
        {% elif time <= 9 %} Good morning 
        {% elif time <= 10 %} Good morning 
        {% elif time <= 13 %} Good afternoon 
        {% elif time <= 15 %} Good afternoon 
        {% elif time <= 17 %} Good afternoon 
        {% elif time <= 19 %} Good evening 
        {% elif time <= 22 %} Good evening 
        {% elif time <= 23 %} Good evening
        {% else %} Good evening
        {% endif %}
  - unique_id: alarm_state
    state: Measuring
    attributes:
      name: >
        {% set entity_id = 'alarm_control_panel.master' %}
        {% if is_state(entity_id, 'disarmed') %}
          Alarm system is: <font color='red'>{{ states("alarm_control_panel.master") }}</font>.
        {% else %}
          Alarm system is: <font color='green'>{{ states("alarm_control_panel.master") }}</font>.
        {% endif %}

Button-card Template:

sidebar:
  variables:
    alarm_state_entity: 
    weather_state_entity: 
  show_state: false
  show_icon: false
  tap_action:
    action: none
  styles:
    grid:
      - grid-template-areas: |
          "n"
          "alarm_state"
      - grid-template-rows: auto repeat(2, min-content)
      - align-items: start
      - will-change: transform
    card:
      - background: none
      - border: none
      - box-shadow: none
      - padding: 1em
    name:
      - justify-self: "start"
      - font-size: "3.5rem"
      - font-weight: "100"
      - font-family: "Merriweather"
      - line-height: 10%
      - white-space: "inherit"
    custom_fields:
      alarm_state:
        - line-height: 80%
        - justify-self: "start"
        - font-size: "1rem"
        - font-family: "Raleway"

  name: >
    [[[
      if (entity) {
        let attr = [];
        for (let [k, value] of Object.entries(entity.attributes))
          window.navigator.userAgent.match(/iPhone/i)
            ? k !== 'time' && k !== 'date' && value !== false && (attr += `<p>${k === 'greet' ? `<span class="iphone">${value}</span>` : `${value}`}</p>`)
            : value !== false && (attr += `<p>${value}</p>`);
        return attr;
      }
    ]]]
  custom_fields:
    alarm_state: >
      [[[ 
        var ent_alarm = states[variables.alarm_state_entity].attributes.name
        return ent_alarm; 
        ]]]

The name piece came from matt8707ā€™s sidebar

And lastly in my home.yaml:

  - type: vertical-stack
    view_layout:
      grid-area: header
    cards:
      - type: custom:button-card
        entity: sensor.template_greet
        variables:
          alarm_state_entity: sensor.template_alarm_state
        template: 
        - sidebar
      - type: custom:mod-card
        card:
          show_current: true
          icon: none
          show_forecast: false
          type: weather-forecast
          entity: weather.buienradar
          secondary_info_attribute: temperature
      - !include repeaters/menu.yaml

Which all results inā€¦
image

Next up figuring out how to change the style of the weather card through the button-cards :stuck_out_tongue:

2 Likes