Lovelace: Bar Card

I would like to have a duration shown in the bar card. The problem is that I have a duration created with history_stats like this:

platform: history_stats
name: wz_tv_time_today
entity_id: media_player.tv
state: 'on'
type: time
start: '{{ now().replace(hour=0, minute=0, second=0, microsecond=0) }}'
end: '{{ now() }}'

When I display this entity with custom:bar-card like this:

    - type: custom:bar-card
      entities:
        - entity: sensor.wz_tv_time_today
          name: TV Zeit heute
          icon: mdi:television
          max: 12
          severity:
            - color: green
              from: 0
              to: 1
            - color: yellow
              from: 1
              to: 3
            - color: red
              from: 3
              to: 24
      height: 25px
      positions:
        icon: inside
        indicator: inside
      entity_row: true
      style: |
        bar-card-name { color: black}
        bar-card-iconbar { color: white }
        bar-card-value { padding-right: 10px; color: white; }
        bar-card-currentbar, bar-card-backgroundbar { border-radius: 0.5em; }
        bar-card-contentbar { font-size: 12px; }
        bar-card-indicator { display: none; }
        ha-card {
            --mdc-icon-size: 18px;
          }

I get this:

What I would like to get is not having a floating point value like 2.03, but 02:02 (0.03*60 = 1.8) instead. How can I achieve this? Is it possible to internally use the entity for calculation and then define something else to be displayed in the bar?

Your only option is using card-mod & “:after” pseudo class:

type: entities
entities:
  - entity: input_number.test_level_1
  - type: custom:bar-card
    entities:
      - entity: input_number.test_level_1
    positions:
      icon: off
      indicator: off
      value: inside
    entity_row: true
    style: |
      bar-card-value {
        font-size: 0px;
      }
      bar-card-value:after {
        content: "00:20:00";
        font-size: var(--mdc-typography-body1-font-size,1rem);
      }

изображение
and you need to specify an appropriate template inside the “content” value, like:

content: "{% set xyz = ... -%}
          {%- ... -%}
          {{ ... }}";

How do I hide the border?

image

Hello, everyone. I’m having difficulty with entities in the ‘unavailable’ state using ‘states(config.entity)’ in the style.

My code:

type: custom:auto-entities
card:
  title: Nível das Baterias
  type: entities
filter:
  template: |-
    {% for state in states.sensor -%}
      {%- if state.entity_id | regex_match("sensor.esp_kiwi_soil_sector_.*battery", ignorecase=False) -%}
        {{
          {
            'entity_row': true,
            'entity': state.entity_id,
            'name': state.attributes.friendly_name.replace('ESP - Kiwi Soil ', '').replace(' Battery', ''),
            'type': 'custom:bar-card',
            'height': '32px',
            'max': "100",
            'positions': {
              'name': 'inside',
              'icon': "inside",
              'value': 'inside',
              'indicator': "off",
            },
            'card_mod': {
              'style': 
                'bar-card-name, bar-card-value {
                  font-size: 14px !important;
                  font-weight: bold !important;
                  margin-right: 20px !important;
                }
                bar-card-currentbar, bar-card-targetbar, bar-card-backgroundbar {
                  border-radius: 10px !important;
                }
                bar-card-row {
                  margin-bottom: 2px !important;
                }
                bar-card-iconbar {
                  color: var(--bar-card-icon-color);
                }
                ha-card {
                  border: none !important;
                }
                ha-icon, bar-card-backgroundbar, bar-card-currentbar {
                  {% if states(config.entity) | int <= 10 %}
                    --card-mod-icon: mdi:battery-10 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 20 %}
                    --card-mod-icon: mdi:battery-20 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 30 %}
                    --card-mod-icon: mdi:battery-30 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 40 %}
                    --card-mod-icon: mdi:battery-40 !important;
                    --bar-color: #FF8E00 !important;
                  {% elif states(config.entity) | int <= 50 %}
                    --card-mod-icon: mdi:battery-50 !important;
                    --bar-color: #FF8E00 !important;
                  {% elif states(config.entity) | int <= 60 %}
                    --card-mod-icon: mdi:battery-60 !important;
                    --bar-color: #FFE400 !important;
                  {% elif states(config.entity) | int <= 70 %}
                    --card-mod-icon: mdi:battery-70 !important;
                    --bar-color: #FFE400 !important;
                  {% elif states(config.entity) | int <= 80 %}
                    --card-mod-icon: mdi:battery-80 !important;
                    --bar-color: #06FF00 !important;
                  {% elif states(config.entity) | int <= 90 %}
                    --card-mod-icon: mdi:battery-90 !important;
                    --bar-color: #06FF00 !important;
                  {% elif states(config.entity) | int <= 100 %}
                    --card-mod-icon: mdi:battery !important;
                    --bar-color: #06FF00 !important;
                  {% else %}
                    --card-mod-icon: mdi:battery-alert-variant !important;
                    --bar-color: #FF1700 !important;
                  {% endif %}
                }
              }'
            },
          }
        }},
      {%- endif -%}
    {%- endfor %}

If I remove this part of the code, the style already works:

                ha-icon, bar-card-backgroundbar, bar-card-currentbar {
                  {% if states(config.entity) | int <= 10 %}
                    --card-mod-icon: mdi:battery-10 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 20 %}
                    --card-mod-icon: mdi:battery-20 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 30 %}
                    --card-mod-icon: mdi:battery-30 !important;
                    --bar-color: #FF1700 !important;
                  {% elif states(config.entity) | int <= 40 %}
                    --card-mod-icon: mdi:battery-40 !important;
                    --bar-color: #FF8E00 !important;
                  {% elif states(config.entity) | int <= 50 %}
                    --card-mod-icon: mdi:battery-50 !important;
                    --bar-color: #FF8E00 !important;
                  {% elif states(config.entity) | int <= 60 %}
                    --card-mod-icon: mdi:battery-60 !important;
                    --bar-color: #FFE400 !important;
                  {% elif states(config.entity) | int <= 70 %}
                    --card-mod-icon: mdi:battery-70 !important;
                    --bar-color: #FFE400 !important;
                  {% elif states(config.entity) | int <= 80 %}
                    --card-mod-icon: mdi:battery-80 !important;
                    --bar-color: #06FF00 !important;
                  {% elif states(config.entity) | int <= 90 %}
                    --card-mod-icon: mdi:battery-90 !important;
                    --bar-color: #06FF00 !important;
                  {% elif states(config.entity) | int <= 100 %}
                    --card-mod-icon: mdi:battery !important;
                    --bar-color: #06FF00 !important;
                  {% else %}
                    --card-mod-icon: mdi:battery-alert-variant !important;
                    --bar-color: #FF1700 !important;
                  {% endif %}
                }

Try to use this:

ha-card {
  border: none !important;
}
1 Like

Do you want unavailable to even be shown? if not i would just filter them out in your initial for state bit:

    {% for state in states.sensor
      | rejectattr('state','in',['unavailable','unknown']) %}

if you have to/want to show them add a default to your int conversion as that is what is failing - cant convert unknown/unavailable/none/undefined, etc. to an int.

                    {% if states(config.entity) | int(default=0) <= 10 %}
                      --card-mod-icon: mdi:battery-10 !important;
                      --bar-color: #FF1700 !important;
                    {% elif states(config.entity) | int(default=0) <= 20 %}
                      --card-mod-icon: mdi:battery-20 !important;
                      --bar-color: #FF1700 !important;
                    {% elif states(config.entity) | int(default=0) <= 30 %}
                      --card-mod-icon: mdi:battery-30 !important;
                      --bar-color: #FF1700 !important;
                    {% elif states(config.entity) | int(default=0) <= 40 %}
                      --card-mod-icon: mdi:battery-40 !important;
                      --bar-color: #FF8E00 !important;
                    {% elif states(config.entity) | int(default=0) <= 50 %}
                      --card-mod-icon: mdi:battery-50 !important;
                      --bar-color: #FF8E00 !important;
                    {% elif states(config.entity) | int(default=0) <= 60 %}
                      --card-mod-icon: mdi:battery-60 !important;
                      --bar-color: #FFE400 !important;
                    {% elif states(config.entity) | int(default=0) <= 70 %}
                      --card-mod-icon: mdi:battery-70 !important;
                      --bar-color: #FFE400 !important;
                    {% elif states(config.entity) | int(default=0) <= 80 %}
                      --card-mod-icon: mdi:battery-80 !important;
                      --bar-color: #06FF00 !important;
                    {% elif states(config.entity) | int(default=0) <= 90 %}
                      --card-mod-icon: mdi:battery-90 !important;
                      --bar-color: #06FF00 !important;
                    {% elif states(config.entity) | int(default=0) <= 100 %}
                      --card-mod-icon: mdi:battery !important;
                      --bar-color: #06FF00 !important;
                    {% else %}
                      --card-mod-icon: mdi:battery-alert-variant !important;
                      --bar-color: #FF1700 !important;
                    {% endif %}

this should do it :slight_smile: default = 0 just means that if an error occurs in the template it will default the if to be 0. so false, so it will be false all the way down until it reaches the else.

ran into the same problem when making my battery card too :slight_smile:

need to update the post with the solution :slight_smile:

1 Like

Thanks for your help it’s working now with a little bug. :crazy_face:

The else statement does not work as expected…

{% else %}
  --card-mod-icon: mdi:battery-alert-variant !important;
  --bar-color: #61677A !important;

The color and the icon not change the entities unavailable

It’s using the other statements in the code in this case:

{% if states(config.entity) | int(default=0) <= 10 %}
  --card-mod-icon: mdi:battery-10 !important;
  --bar-color: #FF1700 !important;

yes. my mistake i have misunderstood how the default works. you set a default and then you can test for that default so the default you can set to something like:

(default=unknown)

and then your very first if statement should be:

{% if states(config.entity) | int(default=unknown) == unknown %}
  --card-mod-icon: mdi:battery-alert-variant !important;
  --bar-color: #FF1700 !important;

you can then do the rest if your elifs without the default :slight_smile:

the default sets a default value rather than the default result of the if statement, i had misunderstood that bit :slight_smile:

it just so happened that i had my error check at the top rather than at the bottom like you did.

1 Like

Thanks very much for your help, it’s working flawless!

1 Like

I’m almost finishing, and I have anothers obstacles.

  • Customizing the name ‘unavailable’ to something different, for example, ‘n/a.’ using bar-card-value

  • Adding another value from diferent entities.

In this code, it filters the entities of the batteries with their percentage values, and I have other entities that mention the voltage of the batteries. I would like to combine the values so that they appear on each bar. For example, on the right side of the bar, it should mention ‘100% - 4.2V’

type: custom:auto-entities
card:
  title: Baterias
  type: entities
filter:
  template: |-
    {% for state in states.sensor -%}
      {%- if state.entity_id | regex_match("sensor.esp_kiwi_soil_sector_.*battery", ignorecase=False) -%}
        {{
          {
            'entity_row': true,
            'entity': state.entity_id,
            'name': state.attributes.friendly_name.replace('ESP - Kiwi Soil ', '').replace(' Battery', ''),
            'type': 'custom:bar-card',
            'height': '34px',
            'max': '100',
            'positions': {
              'name': 'inside',
              'icon': 'inside',
              'value': 'inside',
              'indicator': 'off',
            },
            'card_mod': {
              'style': 
                'bar-card-name, bar-card-value {
                  font-size: 14px !important;
                  font-weight: bold !important;
                  margin-right: 20px !important;
                  #text-shadow: 0px 0px 6px black;
                }
                bar-card-currentbar, bar-card-targetbar, bar-card-backgroundbar {
                  border-radius: 10px !important;
                }
                bar-card-row {
                  margin-bottom: 2px !important;
                }
                bar-card-iconbar {
                  color: var(--bar-card-icon-color);
                }
                ha-card {
                  border: none !important;
                }
                ha-icon, bar-card-backgroundbar, bar-card-currentbar {
                  {% if states(config.entity) | int(default=unknown) == unknown %}
                    --card-mod-icon: mdi:alert-circle-outline !important;
                    --bar-color: #9E9E9E !important;
                  {% elif states(config.entity) | int(default=0) <= 10 %}
                    --card-mod-icon: mdi:battery-off-outline !important;
                    --bar-color: #E74C3C !important;
                  {% elif states(config.entity) | int(default=0) <= 20 %}
                    --card-mod-icon: mdi:battery-20 !important;
                    --bar-color: #E74C3C !important;
                  {% elif states(config.entity) | int(default=0) <= 30 %}
                    --card-mod-icon: mdi:battery-30 !important;
                    --bar-color: #FF9800 !important;
                  {% elif states(config.entity) | int(default=0) <= 40 %}
                    --card-mod-icon: mdi:battery-40 !important;
                    --bar-color: #FF9800 !important;
                  {% elif states(config.entity) | int(default=0) <= 50 %}
                    --card-mod-icon: mdi:battery-50 !important;
                    --bar-color: #FFEB3B !important;
                  {% elif states(config.entity) | int(default=0) <= 60 %}
                    --card-mod-icon: mdi:battery-60 !important;
                    --bar-color: #FFEB3B !important;
                  {% elif states(config.entity) | int(default=0) <= 70 %}
                    --card-mod-icon: mdi:battery-70 !important;
                    --bar-color: #4CAF50 !important;
                  {% elif states(config.entity) | int(default=0) <= 80 %}
                    --card-mod-icon: mdi:battery-80 !important;
                    --bar-color: #4CAF50 !important;
                  {% elif states(config.entity) | int(default=0) <= 90 %}
                    --card-mod-icon: mdi:battery-90 !important;
                    --bar-color: #4CAF50 !important;
                  {% elif states(config.entity) | int(default=0) <= 100 %}
                    --card-mod-icon: mdi:battery !important;
                    --bar-color: #4CAF50 !important;
                  {% endif %}
                }
              }'
            },
          }
        }},
      {%- endif -%}
    {%- endfor %}

Inserting the below should do this.

                {% if states(config.entity) == "unavailable" %}
                bar-card-value {
                  color: transparent !important;
                }
                bar-card-value::after {
                  content: "n/a";
                  color: var(--primary-text-color) !important;
                }
                {% endif %}

For this i would highly recommend you create a new template sensor that has the 2 states as attributes instead and then do your auto entities based on the new template sensors. You can then just combine the attributes of the same already filtered entity rather than trying to apply the state of one entity with the other (which will be almost impossible to do dynamically.)

To be clear the main state of your new template sensor should be your battery percentage, but it could have as an attribute the voltage as per your other entity.

1 Like

It works! The issue is that I use the Shadow configuration in the “name” and “value” text :stuck_out_tongue_closed_eyes:

just overwrite it for the ones that are unavailable then :slight_smile:

                {% if states(config.entity) == "unavailable" %}
                bar-card-value {
                  color: transparent !important;
                  #text-shadow: 0px 0px 6px transparent;
                }
                bar-card-value::after {
                  content: "n/a";
                  color: var(--primary-text-color) !important;
                  #text-shadow: 0px 0px 6px black;
                }
                {% endif %}
1 Like

With a bit of research and using the structure of your code, I arrived at this solution. Thank you!

{% if states(config.entity) == "unavailable" %}
  bar-card-value {
	visibility: hidden !important;
  }
  bar-card-value::after {
	visibility: visible;
	content: "n/a";
  }
{% endif %}
1 Like

Hi,
I’m revisiting this post even though it’s old.
I would like to try using the gradient color but it displays it correctly, it colors the entire bar without considering the sensor percentage which is 63%.
image

I wonder if it is possible to share the card to understand how you did it.
thank you very much

You have to add the clip-path:

Hi Guys,
Can image be used as indicator?
to get something similar:

images

  1. This card is for displaying a bar, not a slider control.
  2. Indicator is a “arrow-like” image, it is not a mark of the current value.

i´d like to know, how you reduced the height of the rows, including the gaps between them.

Sorry for the late answer, I just solved the problem with the gaps for myself with this string:

  bar-card-row {margin-bottom: -20px !important; margin-top: -10px !important;}

inside the style section

1 Like

Hi,
I managed to do something that I like but I find that my code is complicated for several entities. Do you have an idea to reduce it?

type: vertical-stack
cards:
  - type: custom:auto-entities
    card:
      type: custom:bar-card
      align: split
      columns: 1
      height: 2px
      width: 70%
      icon: mdi:lightning-bolt
      animation:
        state: 'on'
        speed: 2
      attribute: null
      color: white
      decimal: 0
      direction: right
      style: "ha-card { --paper-item-icon-color: rgb(47,186,229); border-radius: 2.5px; border-width: 0px !important; background: none; border: none;height: 38px; }\nha-icon\t { margin-top: -40px; padding-right: 25px; }  bar-card-indicator\t { margin-top: -10px; padding-right: 0px; }  bar-card-name\t { margin-top: 0px; padding-left: 0px; }  bar-card-backgroundbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-currentbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-targetbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-animationbar\t { margin-top: 12px;  padding-right: 0px; } bar-card-targetmarker\t { margin-top: 40px; border-radius: 2.5px; } bar-card-value\t { margin-top: 0px; padding-left: 5px; } bar-card-row {margin-bottom: 0px !important; margin-top: -10px !important;}  bar-card-backgroundbar { background: linear-gradient(to right, green 5%, orange 50%, red 75%); border-radius: 25px; } bar-card-currentbar { background: linear-gradient(to right, green 5%, yellow 25%, orange 50%, red 75%); clip-path: polygon(0 0, var(--bar-percent) 0, var(--bar-percent) 100%, 0 100%); border-radius: 25px; } bar-card-contentbar  { font-size: 12px; color: white; } bar-card-value  { font-size: 16px; color: white; }"
      positions:
        icon: 'off'
        indicator: inside
        name: inside
        minmax: 'off'
        value: inside
      unit_of_measurement: W
      max: 300
      min: 0
      severity:
        - color: Green
          from: 0
          to: 25
        - color: Orange
          from: 26
          to: 300
        - color: Red
          from: 51
          to: 300
    entities: []
    sort:
      methode: state
      numeric: true
      reverse: true
    filter:
      include:
        - entity_id: sensor.pompe_a_chaleur_power
  - type: custom:auto-entities
    card:
      type: custom:bar-card
      align: split
      columns: 1
      height: 2px
      width: 70%
      icon: mdi:lightning-bolt
      animation:
        state: 'on'
        speed: 2
      attribute: null
      color: white
      decimal: 0
      direction: right
      style: "ha-card { --paper-item-icon-color: rgb(47,186,229); border-radius: 2.5px; border-width: 0px !important; background: none; border: none;height: 38px; }\nha-icon\t { margin-top: -40px; padding-right: 25px; }  bar-card-indicator\t { margin-top: -10px; padding-right: 0px; }  bar-card-name\t { margin-top: 0px; padding-left: 0px; }  bar-card-backgroundbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-currentbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-targetbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-animationbar\t { margin-top: 12px;  padding-right: 0px; } bar-card-targetmarker\t { margin-top: 40px; border-radius: 2.5px; } bar-card-value\t { margin-top: 0px; padding-left: 5px; } bar-card-row {margin-bottom: 0px !important; margin-top: -10px !important;} bar-card-backgroundbar { background: linear-gradient(to right, green 5%, orange 50%, red 75%); border-radius: 25px; } bar-card-currentbar { background: linear-gradient(to right, green 5%, yellow 25%, orange 50%, red 75%); clip-path: polygon(0 0, var(--bar-percent) 0, var(--bar-percent) 100%, 0 100%); border-radius: 25px; } bar-card-contentbar  { font-size: 12px; color: white; } bar-card-value  { font-size: 16px; color: white; }"
      positions:
        icon: 'off'
        indicator: inside
        name: inside
        minmax: 'off'
        value: inside
      unit_of_measurement: W
      max: 300
      min: 0
      severity:
        - color: Green
          from: 0
          to: 25
        - color: Orange
          from: 26
          to: 300
        - color: Red
          from: 51
          to: 300
    entities: []
    sort:
      methode: state
      numeric: true
      reverse: true
    filter:
      include:
        - entity_id: sensor.informatique_bureau_power
  - type: custom:auto-entities
    card:
      type: custom:bar-card
      align: split
      columns: 1
      height: 2px
      width: 70%
      icon: mdi:lightning-bolt
      animation:
        state: 'on'
        speed: 2
      attribute: null
      color: white
      decimal: 0
      direction: right
      style: "ha-card { --paper-item-icon-color: rgb(47,186,229); border-radius: 2.5px; border-width: 0px !important; background: none; border: none;height: 38px; }\nha-icon\t { margin-top: -40px; padding-right: 25px; }  bar-card-indicator\t { margin-top: -10px; padding-right: 0px; }  bar-card-name\t { margin-top: 0px; padding-left: 0px; }  bar-card-backgroundbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-currentbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-targetbar\t { margin-top: 12px; border-radius: 2.5px; } bar-card-animationbar\t { margin-top: 12px;  padding-right: 0px; } bar-card-targetmarker\t { margin-top: 40px; border-radius: 2.5px; } bar-card-value\t { margin-top: 0px; padding-left: 5px; } bar-card-row {margin-bottom: 0px !important; margin-top: -10px !important;} bar-card-backgroundbar { background: linear-gradient(to right, green 5%, orange 50%, red 75%); border-radius: 25px; } bar-card-currentbar { background: linear-gradient(to right, green 5%, yellow 25%, orange 50%, red 75%); clip-path: polygon(0 0, var(--bar-percent) 0, var(--bar-percent) 100%, 0 100%); border-radius: 25px; } bar-card-contentbar  { font-size: 12px; color: white; } bar-card-value  { font-size: 16px; color: white; }"
      positions:
        icon: 'off'
        indicator: inside
        name: inside
        minmax: 'off'
        value: inside
      unit_of_measurement: W
      max: 300
      min: 0
      severity:
        - color: Green
          from: 0
          to: 25
        - color: Orange
          from: 26
          to: 300
        - color: Red
          from: 51
          to: 300
    entities: []
    sort:
      methode: state
      numeric: true
      reverse: true
    filter:
      include:
        - entity_id: sensor.informatique_salon_power

yes, there are quite a few things to remove (severity duplicates with “background: linear gradient”)

image