[WIP] New Google Home style cards

Hey all. I’m pretty new to this all but I’m enjoying making some Google Home app style cards for HA. I hope you get some use out of them and maybe others even want to chip in and improve on what I’m doing. Still playing around with the sizing, padding, scaling etc but so far it is coming along nicely. To start with I have the home/away status, light group that can be toggled to show the other lights in it and thermostat. I’d like to add browser mod pop ups for everything but I haven’t gotten there yet. Anyways enough talking here is the code and what it looks like.

google home ha

Home/away card

type: custom:mushroom-template-card
primary: Home
secondary: ''
icon: |-
  {% if is_state ('YOUR_ENTITY_HERE', 'home') %}
  fapro:location_home
  {% else %}
  fapro:location_away
  {% endif %}
entity: YOUR_ENTITY_HERE
icon_color: '#0056cf'
card_mod:
  style: |
    ha-card {
      pointer-events: none;
      --card-primary-font-size: 24px;
      --primary-text-color: #1f1f1f;
      --card-primary-font-weight: 400;
    }
    mushroom-shape-icon {
      --shape-color: #d9e2ff !important;
      --icon-symbol-size: 22px;
      --icon-size: 32px;
    }

Light Group Card

type: custom:button-card
entity: YOUR_ENTITY_HERE
name: Living room
label: |
  [[[ if (entity.state == 'on')
    return (states['SENSOR_COUNT_TEMPLATE'].state) + ' On • ' + Math.round(entity.attributes.brightness/2.55) + '%';
    return entity.state;
  ]]]
icon: |
  [[[
    if (entity.state == 'on')
      return "fapro:light-group-fill";
      return "fapro:light-group";
  ]]]
size: 26px
show_name: true
show_label: true
custom_fields:
  slider:
    card:
      type: custom:my-slider-v2
      entity: YOUR_ENTITY_HERE
      allowTapping: true
      styles:
        card:
          - height: 100%
        container:
          - width: 100%
          - height: 100%
          - overflow: hidden
          - border-radius: 35px
        track:
          - width: 100%
          - height: 100%
          - background: |
              [[[
                if (entity.state == "on") return "#ffefc9";
                else return "#f2f6fc";
              ]]]
        progress:
          - height: 100%
          - postion: absolute
          - background: '#ffe082'
        thumb:
          - background: none
  button:
    card:
      type: custom:mushroom-chips-card
      chips:
        - type: template
          icon: |-
            {% if is_state(entity, 'off') %}
              mdi:chevron-down 
            {% elif is_state(entity, 'on') %}   
              mdi:chevron-up    
            {% endif %}
          tap_action:
            action: toggle
          entity: INPUT_BOOLEAN
          icon_color: |-
            {% if is_state('YOUR_ENTITY_HERE', 'off') %}
              31,31,31
            {% elif is_state('YOUR_ENTITY_HERE', 'on') %}   
              115,92,0
            {% endif %}
          card_mod:
            style: |
              ha-card {
               --chip-icon-size: 0.7em;
               --chip-padding: 0px 6px;
               --chip-height: 40px;
               --chip-border-radius: 100px;
              }  
styles:
  grid:
    - grid-template-areas: |
        "i n button"
        "i l button"
    - grid-template-rows: 1fr 1fr
    - grid-template-columns: 14% min-content 2fr
  card:
    - height: 100px
    - border-radius: 35px
    - background-color: |
        [[[
          if (entity.state == 'on')
          return "#ffefc9";
          return "#f2f6fc";
        ]]]
  icon:
    - z-index: 1
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]   
  name:
    - z-index: 1
    - pointer-events: none
    - justify-self: start
    - font-weight: 500
    - font-size: 14px
    - margin: 20px 0px 0px 0px
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]  
  label:
    - z-index: 1
    - pointer-events: none
    - justify-self: start
    - text-transform: capitalize
    - font-weight: 500
    - font-size: 13px
    - margin: 0px 0px 17px 0px
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]  
  custom_fields:
    button:
      - z-index: 1
      - justify-self: end
      - padding-right: 24px
    slider:
      - z-index: 0
      - position: absolute
      - top: '-10px'
      - width: 100%
      - height: 120%

Single Light

type: custom:button-card
entity: YOUR_ENTITY_HERE
name: Dining light
label: |
  [[[ if (entity.state == 'on')
    return 'On • ' + Math.round(entity.attributes.brightness/2.55) + '%';
    return entity.state;
  ]]]
icon: |
  [[[
    if (entity.state == 'on')
      return "fapro:lightbulb-google-fill";
      return "fapro:lightbulb-google";
  ]]]
size: 26px
show_name: true
show_label: true
custom_fields:
  slider:
    card:
      type: custom:my-slider-v2
      entity: YOUR_ENTITY_HERE
      allowTapping: true
      styles:
        card:
          - height: 100%
        container:
          - width: 100%
          - height: 100%
          - position: relative
          - overflow: hidden
          - border-radius: 35px
        track:
          - width: 100%
          - height: 100%
          - position: relative
          - background: |
              [[[
                if (entity.state == "on") return "#ffefc9";
                else return "#f2f6fc";
              ]]]
        progress:
          - height: 100%
          - background: '#ffe082'
          - position: absolute
        thumb:
          - background: none
styles:
  grid:
    - grid-template-areas: |
        "i n"
        "i l"
    - grid-template-rows: 1fr 1fr
    - grid-template-columns: 26% min-content
  card:
    - height: 100px
    - border-radius: 35px
    - background-color: |
        [[[
          if (entity.state == 'on')
          return "#ffefc9";
          return "#f2f6fc";
        ]]]
  icon:
    - z-index: 1
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]   
  name:
    - z-index: 1
    - pointer-events: none
    - justify-self: start
    - font-weight: 500
    - font-size: 14px
    - margin: 28px 0px 0px 0px
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]  
  label:
    - z-index: 1
    - pointer-events: none
    - justify-self: start
    - text-transform: capitalize
    - font-weight: 500
    - font-size: 13px
    - margin: 0px 0px 25px 0px
    - color: |
        [[[
          if (entity.state == 'on')
          return "#735c00";
          return "#1f1f1f";
        ]]]  
  custom_fields:
    slider:
      - z-index: 0
      - position: absolute
      - top: '-10px'
      - width: 100%
      - height: 120%

Thermostat

type: custom:button-card
entity: YOUR_ENTITY_HERE
name: Thermostat
label: |
  [[[ 
    if (entity.attributes.hvac_action =='idle') {
      return 'Indoor ' + (entity.attributes.current_temperature);
    } else if (entity.attributes.hvac_action =='heating' || 'cooling') {
      return (entity.state)+ 'ing' + ' ● ' + (entity.attributes.temperature);
    }
  ]]]
icon: |
  [[[
    if (entity.attributes.hvac_action == 'idle') {
      return "fapro:thermometer-empty";
    } else if (entity.attributes.hvac_action =='heating' || 'cooling') {
      return "fapro:thermometer-google";
    }
  ]]]
size: 26px
show_name: true
show_label: true
custom_fields:
  chip:
    card:
      type: custom:mushroom-chips-card
      chips:
        - type: template
          icon: mdi:chevron-right
          icon_color: >-
            {% if state_attr('climate.hallway_thermostat', 'hvac_action') ==
            'cooling' %}
              41,97,150
            {% elif state_attr('climate.hallway_thermostat', 'hvac_action') ==
            'heating' %}   
              169,56,0
            {% else %}
              31,31,31
            {% endif %}
          card_mod:
            style: |
              ha-card {
              --chip-icon-size: 0.7em;
              --chip-padding: 0px 6px;
              --chip-height: 40px;
              --chip-background: none;
              --chip-border-radius: 100px;
              }  
styles:
  grid:
    - grid-template-areas: |
        "i n chip"
        "i l chip"
    - grid-template-rows: 1fr 1fr
    - grid-template-columns: 26% min-content 2fr
  card:
    - height: 100px
    - border-radius: 35px
    - background-color: |
        [[[
          if (entity.attributes.hvac_action =='idle') {
            return "#f2f6fc";
          }else if (entity.attributes.hvac_action =='cooling') {
            return "#e9f2fe";
          }else if (entity.attributes.hvac_action =='heating') {
            return "#ffdbcd";
          }
        ]]]  
  icon:
    - color: |
        [[[
          if (entity.attributes.hvac_action =='idle') {
            return "#1f1f1f";
          }else if (entity.attributes.hvac_action =='cooling') {
            return "#296096";
          }else if (entity.attributes.hvac_action =='heating') {
            return "#a93800";
          }
        ]]]  
  name:
    - justify-self: start
    - font-weight: 500
    - font-size: 14px
    - margin: 28px 0px 0px 0px
    - color: |
        [[[
          if (entity.attributes.hvac_action =='idle') {
            return "#1f1f1f";
          }else if (entity.attributes.hvac_action =='cooling') {
            return "#296096";
          }else if (entity.attributes.hvac_action =='heating') {
            return "#a93800";
          }
        ]]]  
  label:
    - justify-self: start
    - text-transform: capitalize
    - font-weight: 500
    - font-size: 13px
    - margin: 0px 0px 25px 0px
    - color: |
        [[[
          if (entity.attributes.hvac_action =='idle') {
            return "#1f1f1f";
          }else if (entity.attributes.hvac_action =='cooling') {
            return "#296096";
          }else if (entity.attributes.hvac_action =='heating') {
            return "#a93800";
          }
        ]]]
  custom_fields:
    chip:
      - justify-self: end
      - padding-right: 9px

There you have it. I put things in ALL CAPS that you need to replace with your own entities/sensors/templates/whatever. If you have any issues ask and I will try and help out. Icons are from fonts.google.com.

5 Likes

Theses are great! I’ll be checking them out this week!

I played around with these a litter earlier. Somethings I need to add in.

  • Hold for more info pop-up.
  • some kind of slider delay like big-slider card has so they don’t slide while you’re scrolling on mobile.
  • Theme, so they work well with all themes and not just a light theme. I’ve been using noctis lately.

I also modified it so it would function with lights that don’t have brightness, only on and off. I changed the progress bar to the same color as the “on” background and removed the percentage from the state formula. Works great.

Great work on this. Has a lot of potential! Thank you!