Fun with custom:button-card

Hi Guys,

I’ve made this button which has a temperature in the top right and a flashing motion detection symbol when it detects motion. That all works fine.

I’m now trying to add a a second icon, an (mdi:fan) icon when entity: light.ensuite_fan_light is ‘on’. I understood the way to do this was with custom fields? Not having any luck though, getting this [object Object] message. Welcome any insight into what I’m doing wrong, thanks in advance…
image

type: custom:button-card
entity: sensor.ensuite_sensor_temperature
name: Ensuite
label: Ensuite
layout: icon_state
icon: >
  [[[ return states['binary_sensor.ensuite_sensor_presence_sensor_1'].state ===
  'on' ? 'mdi:motion-sensor' : 'nul';
   ]]]
show_state: true
show_name: false
show_label: true
show_icon: true
size: 1.5em
custom_fields:
  fan:
    - icon: >

        [[[ if (states["light.ensuite_fan_light"].state == "off") return
        "mdi:fan"; ]]]
styles:
  fan:
    - padding-bottom: '-16px'
  grid:
    - grid-template-columns: 100%
    - grid-template-rows: 1fr
    - grid-template-areas: '"i" "fan" "l"'
    - font-size: 7px
  card:
    - height: 60px
    - background-image: |
        [[[
          if (states['light.ensuite'].state == "on" )
            return 'url(/local/spot.png)';
        ]]]
    - background-color: |
        [[[
          if (states['light.ensuite'].state == "on" )
            return 'black' ;
        ]]]
    - background-position: '-35px'
    - background-size: 157% 97%;
    - background-repeat: no-repeat
    - overflow: hidden
    - padding-bottom: 1px
  state:
    - padding-bottom: 37px
    - position: absolute
    - right: '-10px'
    - font-size: 11px
    - color: '#CCCCCC'
  icon:
    - top: 12px
    - left: 33px
    - width: 24px
    - color: '#0096FF'
    - animation: blink 2s linear infinite;
  label:
    - font-size: 13px
    - color: |
        [[[
        if (states['light.ensuite'].state === "on")
          return "yellow";
        else if (states['light.ensuite'].state === "off")
          return "white";
        ]]]
tap_action:
  action: toggle
  entity: light.ensuite

I’d would use a second button card inside your main button card by using this

custom_fields:
  fan:
    card:
      type: custom:button-card
      entity: fan.bedroom_fan
      icon: >
       [[[ return states['fan.bedroom_fan'].state === 'on' ?
         'mdi:fan' : 'mdi:fan-off';
            ]]]
      tap_action: none
      show_state: false
      show_name: false
      show_icon: true
      styles:
        card:
          - border: none
          - background: transparent
        icon:
          - color: |
             [[[ return states['fan.bedroom_fan'].state === 'on' ?
             'red' : 'grey';
               ]]]
styles:
  custom_fields:
    fan:
      - position: absolute
      - left: 50%
      - top: 3%
      - height: 33px
      - width: 60px
      - z-index: 1
  grid:
1 Like

Weird, I have 3 members in this household.
2 on iPhone one on Android, the Android is staying grey.

1 Like

Those state colors come from this entity in the card

image

1 Like

I know, this is the card that ignores the colouring.

type: custom:button-card
entity: sensor.munchkin_battery_state
show_name: true
name: |
  [[[
    if (states['sensor.munchkin_battery_state'].state =='charging') { 
    return `${states['sensor.munchkin_battery_state'].state}`;
    } else {
      return `${states['sensor.munchkin_battery_level'].state}`;
    }
  ]]]
show_icon: true
icon: |
  [[[
    const batteryLevel = states['sensor.munchkin_battery_level'].state;
    
    if (states['sensor.munchkin_battery_state'].state =='Charging') { 
      return ``;
    }
     if (batteryLevel <= 10) {
      return 'mdi:battery-10';
    }
     if (batteryLevel <= 20) {
      return 'mdi:battery-20';
    }
     if (batteryLevel <= 30) {
      return 'mdi:battery-30';
    }
     if (batteryLevel <= 40) {
      return 'mdi:battery-40';
    }
     if (batteryLevel <= 50) {
      return 'mdi:battery-50';
    }
     if (batteryLevel <= 60) {
      return 'mdi:battery-60';
    }
     if (batteryLevel <= 70) {
      return 'mdi:battery-70';
    }
     if (batteryLevel <= 80) {
      return 'mdi:battery-80';
    }
     if (batteryLevel <= 90) {
      return 'mdi:battery-90';
    } else {
      return `mdi:battery`;
    }
  ]]]
state:
  - value: batteryLevel <= 99
    styles:
      icon:
        - color: green
  - value: batteryLevel <= 75
    styles:
      icon:
        - color: lightgreen
  - value: batteryLevel <= 50
    styles:
      icon:
        - color: yellow
  - value: batteryLevel <= 30
    styles:
      icon:
        - color: orange
  - value: batteryLevel <= 20
    styles:
      icon:
        - color: red
styles:
  card:
    - box-shadow: none
    - border-radius: 0
    - padding: 10%
    - font-size: 12px
    - text-shadow: 0px 0px 0px black
    - text-transform: capitalize
  icon:
    - height: 30px
    - width: 30px

Was just providing information. Shouldn’t it be sensor.munchkin_battery_level not state in that entity field?

Didn’t want to sound harsh, sorry for that.
I checked it, and changed it, this was the only card with the state

This is what I use to define the batteryLevel. it’s ignored.

const batteryLevel = states['sensor.munchkin_battery_level'].state;

edit: I just noticed that the icon’s that use the same function are not updating according to my settings

where did you find that dashboard… which I also looked around for, I really like it

I want it to be associated with a button to start an automation and I would like a loading that runs until the automation has finished

image

Team,
I’m trying to create a very compact overview of temperatures in my house. The temperature color changes to RED if WARMER than Outside. (i.e.: open a window!)

This layout was created with the grid feature and it works fine,
except for 1 thing that is not possible:
click a room to see the history chart (to see if the trend is up or down)

Code:

type: custom:button-card
name: null
variables:
  fontsize: 22
styles:
  card:
    - height: 170px
    - width: 180%
  grid:
    - grid-template-areas: >-
        ". sens-attic sens-office .""sens-outside sens-bed1 sens-bed ."". .
        sens-living sens-garage"
    - grid-template-columns: 25% 25% 25% 25%
    - grid-template-rows: 1fr 1fr 1fr
    - font-weight: normal
    - font-size: 13px
    - align-self: start
    - justify-self: middle
  icon:
    - width: 30%
    - left: 30%
    - align-self: end
    - justify-self: end
    - color: grey
  name:
    - color: grey
  img_cell:
    - justify-content: start
    - align-items: start
  custom_fields:
    sens-attic:
      - entity: sensor.temp_rfx_atticfront_temperature
      - tap_action: null
        action: more-info
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_atticfront_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-office:
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_office_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-bed1:
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_bed1_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-bed:
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_bedroom_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-living:
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_living_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-garage:
      - '--text-color-sensor': >-
          [[[ if (states["sensor.temp_rfx_garage_temperature"].state >
          states["sensor.helper_temperature_outside_average"].state) return
          "orange"; return "lightgreen" ]]]
    sens-outside:
      - '--text-color-sensor': lightblue
custom_fields:
  sens-outside: |
    [[[
      return `<font color=grey>OUTSIDE</font><br><span style="font-size: ${variables.fontsize}px;color: var(--text-color-sensor);">${states['sensor.helper_temperature_outside_average'].state}</span>` ;  
    ]]]
  sens-attic: |
    [[[
      return `ATTIC<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_atticfront_temperature'].state}</span>` ;  
    ]]]
  sens-office: |
    [[[
      return `OFFICE<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_office_temperature'].state}</span>` ;  
    ]]]
  sens-bed1: |
    [[[
      return `BED1<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_bed1_temperature'].state}</span>` ;  
    ]]]
  sens-bed: |
    [[[
      return `BED<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_bedroom_temperature'].state}</span>` ;  
    ]]]
  sens-living: |
    [[[
      return `LIVING<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_living_temperature'].state}</span>` ;  
    ]]]
  sens-garage: |
    [[[
      return `Garage<br><span style="font-size: ${variables.fontsize}px;font-weight: bold; color: var(--text-color-sensor);">${states['sensor.temp_rfx_garage_temperature'].state}</span>` ;  
    ]]]

Any idea if it is possible to achieve something similar with a method other than a grid?

Fixed the state colour.

The problem was

- value: batteryLevel <= 99

I just needed to change it :slight_smile:

state:
  - value: 75
    operator: '>='
    styles:
      icon:
        - color: green
  - value: 50
    operator: '>='
    styles:
      icon:
        - color: lightgreen
  - value: 30
    operator: '>='
    styles:
      icon:
        - color: yellow
  - value: 20
    operator: '>='
    styles:
      icon:
        - color: orange
  - value: 0
    operator: '>='
    styles:
      icon:
        - color: red
1 Like

Hi again guys, do you know how can I make the label on the right side and left align all like the mushroom cards? Thank you!

download

Please provide your card code.

- show_name: false
        show_icon: true
        label: Aquecer
        show_label: true
        type: custom:button-card
        tap_action:
          action: toggle
        icon: mdi:kettle-steam
        entity: switch.kettle_start
        hold_action:
          action: more-info
        styles:
          label:
            - font-size: 14px
            - padding: 5px 0px 0px
            - font-weight: bold;
          icon:
            - width: 21px
            - height: 21px
            - color: '#44739E'
            - padding: 10.5px
            - border-radius: 100%
            - background: rgba(68,115,158,0.2)
          name:
            - font-size: 14px
            - padding-top: 10px
            - color: white
            - font-weight: bold
            - color: '#e1e1e1'
          state:
            - font-size: 12px
            - padding-top: 10px
            - padding-bottom: 5px
            - color: '#9b9b9b'
            - font-weight: bold
        state:
          - value: 'on'
            icon: mdi:kettle-steam
            label: Parar
            styles:
              icon:
                - color: '#4CAF50'
                - background: rgba(76,175,80,0.2)
        card_mod:
          style: |
            ha-card {
               border: none;
            }

I have to say, that after learning to use and modify the custom:button-card, i finally get stuff how i want.

My latest project is a card showing the electricity price the same way tibber does :slight_smile:

tibber_screenshot

The bar changes with the electricity price state and uses min and max for the calculation of the border :slight_smile:

3 Likes

Hi, very cool. Can you share the code?

You can find it here: GitHub - BerrisNO/HA-Custom-Cards: My custom cards for Home Assistant :grinning:

Hi, I want to disable the ripple effect when you touch the button but only works on the HA app for me, in my tablet with fully kiosk do not work.

I’m using:

  - '--mdc-ripple-color': transparent
  - '--mdc-ripple-press-opacity': 0

As I say in the app works well. Any help will be appreciated

Hi there,
I have tried to make these as small as yours but don’t seem to be able to, are you able to help with what you did?

I also tried adding AQI and VOC and put them to the right of the temp and humidity (also on two levels), but don’t seem to be able to get this to work. Would you be able to help? I will use an iPad in landscape mode in the end.

type: custom:stack-in-card
cards:
  - type: custom:button-card
    entity: sensor.0x30fb10fffedae512_temperature
    icon: '[[[ return entity.attributes.icon ]]]'
    show_icon: false
    name: Living Room
    tap_action:
      action: navigate
      navigation_path: /lovelace/living-room
      haptic: medium
    styles:
      card:
        - background: var(--contrast2)
        - padding: 12px
        - '--mdc-ripple-press-opacity': 0
      icon_cells:
        - justify-self: start
        - margin-top: 15px
        - margin-left: 15px
        - animation: |
            [[[
              var state = states['sensor.0x30fb10fffedae512_temperature'].state;
              return state === 'on' ? 'bounce 2s infinite' : 'none';
            ]]]
      img_cell:
        - justify-self: start
        - width: 24px
      custom_fields:
        temp:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 5px 0 0px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        hum:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 5px 0 15px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        aqi:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 1px 0 15px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        voc:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 1px 0 12px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        graph:
          - padding-top: 0%
          - width: 100%
          - height: 100%
        icon_cells:
          - width: 24px
          - height: 24px
          - color: var(--contrast8)
          - animation: |
              [[[
                var state = states['sensor.0x30fb10fffedae512_temperature'].state;
                return state === 'on' ? 'bounce 2s infinite' : 'none';
              ]]]
      name:
        - justify-self: start
        - font-size: 15px
        - overflow: visible
        - margin: 5px 0 1px 0
        - color: |
            [[[
              var state = states['sensor.0x30fb10fffedae512_temperature'].state;
              return state === 'on' ? 'white' : 'grey';
            ]]]
        - font-family: Montserrat
        - font-weight: 600
      grid:
        - grid-template-areas: '"icon_cells slider temp" "n slider hum"'
        - grid-template-columns: 2fr min-content 2fr
        - grid-template-rows: 1fr min-content min-content
    custom_fields:
      icon_cells: |
        [[[
         var state = states['sensor.0x30fb10fffedae512_temperature'].state;
         if(state == "on")
          return `<ha-icon
          icon="mdi:sofa"
          style="width: 25px; height: 25px; color: yellow;">
          </ha-icon>
          `;
         else 
          return `<ha-icon
          icon="mdi:sofa-outline"
          style="width: 25px; height: 25px; color: grey;">
          </ha-icon>
          `;
        ]]]
      temp: |
        [[[
          return `<ha-icon
          icon="mdi:thermometer"
          style="width: 18px; height: 18px; color: var(--orange);">
          </ha-icon><span>${parseFloat(states['sensor.0x30fb10fffedae512_temperature'].state).toFixed(0)}°C</span>`
        ]]]
      hum: |
        [[[
          return `<ha-icon
          icon="mdi:water-percent"
          style="width: 18px; height: 18px; color: var(--blue);">
          </ha-icon> <span>${parseFloat(states['sensor.0x30fb10fffedae512_humidity'].state).toFixed(0)}%</span>`
        ]]]
      aqi: |
        [[[
          return `<ha-icon
          icon="mdi:flower-pollen"
          style="width: 18px; height: 18px; color: var(--blue);">
          </ha-icon> <span>${parseFloat(states['sensor.0x30fb10fffedae512_humidity'].state).toFixed(0)}%</span>`
        ]]]
      voc: |
        [[[
          return `<ha-icon
          icon="mdi:pencil-box-multiple-outline"
          style="width: 18px; height: 18px; color: var(--blue);">
          </ha-icon> <span>${parseFloat(states['sensor.0x30fb10fffedae512_humidity'].state).toFixed(0)}%</span>`
        ]]]
    card_mod:
      style: |
        ha-card {
          z-index: 1;
          height: 70px;
        }
    extra_styles: |
      @keyframes bounce {
        0% { transform: scale3d(1, 1, 1); }
        7% { transform: scale3d(1.25, 0.75, 1); }
        10% { transform: scale3d(0.75, 1.25, 1); }
        12% { transform: scale3d(1.15, 0.85, 1); }
        16% { transform: scale3d(0.95, 1.05, 1); }
        19% { transform: scale3d(1.05, 0.95, 1); }
        25% { transform: scale3d(1, 1, 1); }
      }
  - type: custom:mini-graph-card
    tap_action:
      action: navigate
      navigation_path: /lovelace/living-room
      haptic: medium
    entities:
      - entity: sensor.0x30fb10fffedae512_temperature
        name: Temperature
        color: '#ff8c00'
        show_points: false
        legend: false
      - entity: sensor.0x30fb10fffedae512_humidity
        name: Humidity
        color: '#3399ff'
        y_axis: secondary
        show_points: false
        legend: false
      - entity: sensor.0x30fb10fffedae512_pm25
        name: AQI
        color: '#3399ff'
        y_axis: secondary
        show_points: false
        legend: false
      - entity: sensor.0x30fb10fffedae512_voc_index
        name: VOC
        color: '#3399ff'
        y_axis: secondary
        show_points: false
        legend: false
    height: 40
    hours_to_show: 12
    line_width: 1
    font_size: 50
    show:
      name: false
      icon: false
      state: false
      legend: false
      animate: true
      labels: false
      labels_secondary: false
    card_mod:
      style: |
        ha-card {
          position: absolute;
          height: 100%;
          width: 100%;
          top: 0px;
          --ha-card-border-width: 0;
        }
        ha-card:after {
          content: "";
          position: absolute;
          width: 100%;
          height: 100%;
        }```

How to decrease card size?

image

I have tried using the code below, but the second card didn’t increase along with:

image

Code:

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        icon: mdi:arrow-left
        template: common_style
        tap_action:
          action: none
        extra_styles: |
          :host,ha-card {
            width: 30%!important;
          }
      - type: custom:button-card
        color_type: label-card
        name: Persianas
        template: common_style
        extra_styles: |
          :host,ha-card{height:100%!important}

how can i get the name to wrap to 2x lines , ie for it to not be truncated with the three dots?

i saw some one mention:
white-space: preserve

but i can only get that work if i manually set it via firefox dev-tool inspector, im not clear where to add it on my button.
thanks

              - type: custom:button-card
                entity: input_boolean.enableaxisspeakersmutingshellscript
                name: Axis Speaker OFF
                color_type: card
                aspect_ratio: 1/0.8
                show_icon: true
                action: toggle
                color: red
                icon: mdi:speaker-off
                show_state: false
                confirmation:
                  text: >-
                    [[[ return `Are you sure you want to toggle
                    ${entity.attributes.friendly_name}?` ]]]
                state:
                  - value: 'on'
                    styles:
                      card:
                        - animation: blink 1.5s ease 5s infinite

(the buttons on the right side, ie how they are truncated with … ):

image