Lovelace: Flexible Horseshoe Card (Donut graph, flexible layout, multiple entities, actions & animations), including next-gen experimental examples

If you put it inside a grid then it will auto resize to that cell. This is the only way i got it working.

Thanks. My full tablet code is here Full config for my Home Assistant photo frame dashboard · GitHub

1 Like

I’m certain your code is good. Further reading in the forum here reveals others having the problem I have. Prior to your code, I had the card not configured error. Now I just get a blank card, as others have had. I think it is not installed properly, and unable to draw the card from the python script.

You may be right. Best to try fresh and reinstall again. The card wouldn’t load for me too with the different apostrophe you had; weird. Good luck, report back when you get it going and how you fixed it. :+1:

All entities must exist else the card is not drawn. I think it also only reads states not attributes.

Got it working with Card-mod plugin.

https://community.home-assistant.io/t/card-mod-add-css-styles-to-any-lovelace-card/120744

type: 'custom:flex-horseshoe-card'
style: |
  ha-card {
    height: 90px !important;
  }
entities:
  - entity: sensor.family_room_temperature
    decimals: 1
    name: Family Room
    area: ''
    unit: °C
    tap_action:
      action: more-info
  - entity: switch.family_room
    name: ' '
    icon: 'mdi:lightbulb'
    tap_action:
      action: call-service
      service: switch.toggle
      service_data:
        entity_id: switch.family_room
  - entity: sensor.family_room_humidity
    attribute: humidity
    decimals: 0
    unit: '%'
    icon: 'mdi:water-percent'
    tap_action:
      action: more-info
  - entity: sensor.family_room_temp_battery
    attribute: battery
    decimals: 0
    unit: '%'
    icon: 'mdi:battery'
    tap_action:
      action: more-info
animations:
  entity.1:
    - state: 'on'
      circles:
        - animation_id: 11
          styles:
            - fill: var(--secondary-text-color);
            - opacity: 0.9;
            - animation: jello 1s ease-in-out both;
            - transform-origin: center;
      icons:
        - animation_id: 0
          styles:
            - fill: white;
    - state: 'off'
      circles:
        - animation_id: 11
          reuse: true
          styles:
            - transform-origin: center;
            - animation: zoomOut 1s ease-out both;
      icons:
        - animation_id: 0
          styles:
            - fill: var(--primary-text-color);
show:
  horseshoe_style: lineargradient
layout:
  states:
    - id: 0
      entity_index: 0
      xpos: 50
      ypos: 25
      uom_font_size: 1.5
      styles:
        - font-size: 1.9em;
        - opacity: 0.9;
    - id: 2
      entity_index: 2
      xpos: 25
      ypos: 43
      uom_font_size: 1.5
      styles:
        - font-size: 1.9em;
        - opacity: 0.9;
    - id: 3
      entity_index: 3
      xpos: 77
      ypos: 43
      uom_font_size: 1.5
      styles:
        - font-size: 1.9em;
        - opacity: 0.9;
  names:
    - id: 0
      entity_index: 0
      xpos: 50
      ypos: 95
      styles:
        - font-size: 1.5em;
        - opacity: 0.7;
  icons:
    - id: 0
      animation_id: 0
      xpos: 50
      ypos: 75
      entity_index: 1
      icon_size: 4
      styles:
        - color: var(--primary-text-color);
    - id: 2
      entity_index: 2
      xpos: 35
      ypos: 57
      align: end
      icon_size: 2.9
      styles:
        - color: orange
    - id: 3
      entity_index: 3
      xpos: 85
      ypos: 57
      align: end
      icon_size: 2.9
      styles:
        - color: orange
      color: orange
  circles:
    - id: 0
      animation_id: 0
      xpos: 50
      ypos: 70
      radius: 35
      styles:
        - fill: var(--primary-background-color);
    - id: 1
      animation_id: 11
      xpos: 50
      ypos: 70
      radius: 25
      entity_index: 1
      styles:
        - fill: var(--primary-background-color);
horseshoe_scale:
  min: 0
  max: 40
  width: 2
  color: var(--primary-background-color)
horseshoe_state:
  width: 2
  color: '#FFF6E3'
color_stops:
  '0': '#FFF6E3'
  '10': '#FFE9B9'
  '20': '#FFDA8A'
  '30': '#FFCB5B'
  '40': '#FFBF37'
  '50': '#ffb414'
  '60': '#FFAD12'
  '70': '#FFA40E'
  '80': '#FF9C0B'
  '90': '#FF8C06'

1 Like

Awesome! Thank you so much. Very nice multi-use gauge now.

I copied your code and changed the entities to some I have, and it worked! Thank you. But all I see is the small gauge on the right. Is this right? Is the code not there for the gauge on the left? I can steal code and modify it, but I really don’t know what I’m doing. If you don’t mind and if I’m right that the left gauge code isn’t there, could you provide it so I have something to work with? Thanks

Add this card thru HACS.

https://github.com/custom-cards/canvas-gauge-card

And here’s the code.

entity: sensor.family_room_temperature
font_size: 1em
gauge:
  animatedValue: true
  borders: true
  colorBorderInner: '#111'
  colorBorderInnerEnd: '#333'
  colorBorderMiddle: '#222'
  colorBorderMiddleEnd: '#111'
  colorBorderOuter: '#333'
  colorBorderOuterEnd: '#111'
  colorNumbers: '#ccc'
  colorPlate: ''
  colorTitle: '#f5f5f5'
  colorUnits: '#f5f5f5'
  height: 200
  highlights:
    - color: 'rgba(0, 68, 255, .75)'
      from: 0
      to: 5
    - color: 'rgba(74, 123, 180, .75)'
      from: 5
      to: 15
    - color: 'rgba(4, 205, 24, .75)'
      from: 15
      to: 25
    - color: 'rgba(239, 93, 13, .75)'
      from: 25
      to: 40
  majorTicks:
    - '0'
    - '5'
    - '10'
    - '15'
    - '20'
    - '25'
    - '30'
    - '35'
    - '40'
  maxValue: 40
  minValue: 0
  minorTicks: 5
  startAngle: 45
  strokeTicks: true
  ticksAngle: 270
  title: Family Room
  type: radial-gauge
  units: °C
  valueBox: true
  valueDec: 1
  valueInt: 2
  width: 205
type: 'custom:canvas-gauge-card'

2 Likes

Thank you. I now have 2 custom cards to play with. Thanks again.

1 Like

Is there a way to call a popup on this card?

something like this for example:

                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    command: toast
                    message: Hello

Hi,
any idea regarding this misalignment on android APP HA?
It is aligned on the browser…
The xpos: of the icon and of the circle is the same (50)!

icons:
- id: 0
  animation_id: 0
  xpos: 50
  ypos: 75
  
  
circles:
- id: 0
  animation_id: 0
  xpos: 50
  ypos: 70
  radius: 35			  

Thanks


I have the same problem and I never worked it out. Looks fine in chrome or any other browser.

How do you configure that background?

By(t)e

Hi, any possibility to show “last_changed” in this card?

How do I achieve this? Cant find any example code on this? Want to make my gauge being only a half circle.

image

Hi,

Is it possible to set a width for the card itself ?

Kr,

Bart

Logger: frontend.js.latest.202204050
Source: components/system_log/__init__.py:190
First occurred: 18:26:52 (4 occurrences)
Last logged: 18:26:55

https://xxxxxx.duckdns.org:8123/hacsfiles/flex-horseshoe-card/flex-horseshoe-card.js?hacstag=2427790308781368:1609:26 Uncaught TypeError: Cannot read properties of undefined (reading 'action')

I have a problem since update to 2022.6.0 with the companion app. It’s working fine with browser version and worked in the app before.
Pushing the now “invisible” fan button in mobile app gives me the following error:

Logger: frontend.js.latest.202206010
Source: components/system_log/__init__.py:190
First occurred: 08:54:06 (1 occurrences)
Last logged: 08:54:06

https://xxxxxxxxxxx.duckdns.org:8123/hacsfiles/flex-horseshoe-card/flex-horseshoe-card.js?hacstag=1111111111:222:333 Uncaught TypeError: Cannot read properties of undefined (reading 'action')

Mobile app:
mobile

Browser:
mobile

Lovelace configuration:

type: custom:mod-card
card_mod:
  style: |
    restriction-card {
      --lock-margin-left: 88%;
    }
card:
  type: custom:restriction-card
  restrictions:
    block: true
  condition:
    entity: sensor.i3s_120_remaining_battery_percent
    value: 30
    operator: <
  card:
    type: custom:flex-horseshoe-card
    entities:
      - entity: sensor.i3s_location_temp
        decimals: 1
        name: ' '
        tap_action:
          action: more-info
      - entity: input_boolean.virtual_i3s_climate
        icon: mdi:fan
        tap_action:
          action: call-service
          service: input_boolean.toggle
          service_data:
            entity_id: input_boolean.virtual_i3s_climate
      - entity: switch.virtual_i3s_climate
      - entity: sensor.i3s_loc
        tap_action:
          action: more-info
    animations:
      entity.1:
        - state: 'on'
          icons:
            - animation_id: 0
              styles:
                - color: var(--paper-item-icon-active-color);
        - state: 'off'
          icons:
            - animation_id: 0
              styles:
                - color: var(--primary-text-color);
      entity.2:
        - state: 'on'
          icons:
            - animation_id: 0
              styles:
                - color: var(--text-primary-color);
          circles:
            - animation_id: 1
              styles:
                - fill: var(--cool-blue);
        - state: 'off'
          circles:
            - animation_id: 1
              styles:
                - fill: var(--primary-background-color);
    show:
      horseshoe_style: colorstopgradient
    layout:
      states:
        - id: 0
          entity_index: 0
          xpos: 50
          ypos: 42
          styles:
            - font-size: 3.5em;
            - text-transform: none;
            - font-weight: 500;
        - id: 1
          entity_index: 3
          xpos: 50
          ypos: 95
          styles:
            - text-transform: lowercase;
            - font-size: 1.6em;
            - font-weight: 500;
            - letter-spacing: inherit;
      hlines:
        - id: 0
          xpos: 50
          ypos: 51
          length: 50
          styles:
            - stroke: var(--primary-text-color);
            - stroke-width: 5;
            - stroke-linecap: round;
            - opacity: 0.7;
      names:
        - id: 0
          entity_index: 0
          xpos: 50
          ypos: 95
          styles:
            - text-transform: lowercase;
            - font-size: 1.6em;
            - font-weight: 500;
            - letter-spacing: inherit;
      icons:
        - id: 0
          entity_index: 1
          animation_id: 0
          xpos: 50
          ypos: 74
          icon_size: 3.8
      circles:
        - id: 0
          entity_index: 2
          animation_id: 1
          xpos: 50
          ypos: 68.5
          radius: 25
    horseshoe_scale:
      min: -20
      max: 60
      width: 10
    horseshoe_state:
      width: 14
    color_stops:
      '10': orange
      '18': var(--cool-blue)
      '25': orange
      '35': red
      '-20': red
    card_mod:
      style: |
        ha-card {
          padding: 12px !important;
        }

Hello I try to change Icon Color with the fill option for the light and the blind, but nothing change code are accepted but if light change from on to off or inverse or blind change from closed to open nothing chance can you help me
here my code

type: custom:flex-horseshoe-card
entities:
  - entity: sensor.station_sdj_co2_ambient
    attribute: CO2
    decimals: 0
    name: SDJ
    unit: ppm
    icon: mdi:molecule-co2
  - entity: sensor.sation_sdj_temperature_ambiante
    attribute: temperature
    decimals: 1
    name: SDJ
    unit: °C
    icon: mdi:thermometer
  - entity: sensor.salle_de_jeux_humidity
    attribute: humidity
    decimals: 0
    unit: '%'
    icon: mdi:water-percent
  - entity: switch.nspanel_sdj_relay_2
    icon: mdi:lightbulb-outline
    tap_action:
      action: call-service
      service: switch.toggle
      service_data:
        entity_id: switch.nspanel_sdj_relay_2
  - entity: cover.store
    icon: mdi:blinds-horizontal
animations:
  entitiy.3:
    - state: 'on'
      icons:
        - animation_id: 10
          styles:
            - fill: yellow;
    - state: 'off'
      icons:
        - animation_id: 10
          styles:
            - fill: black;
  entitiy.4:
    - state: open
      icons:
        - animation_id: 11
          styles:
            - fill: blue;
    - state: closed
      icons:
        - animation_id: 11
          styles:
            - fill: black;
show:
  horseshoe_style: lineargradient
layout:
  hlines:
    - id: 0
      xpos: 50
      ypos: 42
      length: 40
      styles:
        - stroke: var(--primary-text-color);
        - stroke-width: 5;
        - stroke-linecap: round;
        - opacity: 0.7;
  states:
    - id: 0
      entity_index: 0
      animation_id: 0
      xpos: 55
      ypos: 34
      styles:
        - font-size: 3em;
    - id: 1
      entity_index: 1
      animation_id: 0
      xpos: 30
      ypos: 57
      styles:
        - text-anchor: start;
        - font-size: 1em;
    - id: 2
      entity_index: 2
      animation_id: 0
      xpos: 30
      ypos: 72
      styles:
        - text-anchor: start;
        - font-size: 1em;
    - id: 3
      entity_index: 3
      animation_id: 0
      xpos: 70
      ypos: 57
      styles:
        - text-anchor: start;
        - font-size: 1em;
    - id: 4
      entity_index: 4
      animation_id: 0
      xpos: 70
      ypos: 72
      styles:
        - text-anchor: start;
        - font-size: 1em;
  icons:
    - id: 0
      entity_index: 1
      xpos: 30
      ypos: 57
      align: end
      size: 1
    - id: 1
      entity_index: 2
      xpos: 30
      ypos: 72
      align: end
      size: 1
    - id: 2
      entity_index: 3
      animation_id: 10
      xpos: 68
      ypos: 57
      align: end
      size: 1
      styles:
        - color: var(--primary-text-color);;
    - id: 3
      entity_index: 4
      animation_id: 11
      xpos: 68
      ypos: 72
      align: end
      size: 1
      styles:
        - color: blue
  names:
    - id: 0
      entity_index: 0
      xpos: 50
      ypos: 95
horseshoe_scale:
  min: 400
  max: 2500
color_stops:
  '16': '#29c5f6'
  '17': lime
  '18': '#86DC3D'
  '19': '#C5E90B'
  '20': '#ff8b3d'
  '21': '#ff6600'
  '22': '#f94001'
  '23': red
  '24': '#FF9C0B'
  '25': '#FF8C06'