šŸ”¹ Auto-entities - Automatically fill cards with entities

Hey all, I have the default template and automations configured to add a notification to Home Assistant via the package file. I’d love to have it only show devices that have been unavailable for maybe 10 minutes or longer but I can’t see where I’d add that. Any suggestions? Thanks!

I have a card which shows anything unavailable or unknown, and if there is nothing to show the card just disappears. I think everyone has items which are unavailable or unknown - that they don’t care about - and this also allows you to hide those as well (note the exclude section). Here is the YAML for that card. If you want to use it, just create an auto-entities card and go into the YAML for it and paste the below there, removing all of the things I excluded - and then adding yours so you can cutomize for your specific setup.

With regards to the 10 minute delay - why bother? If I have things that I know will go away I just ignore them and check back later - (?). Either way, when you fill out that exclude section you might be able to add logic on the 10 minute timeout. If not, then another workaround to get that to work - and maybe you would want to do this for only the items for which you want the 10 minute timeout, not everything - is to create a template sensor for those showing what you want (the 10 minute logic could be in there) and exclude each related sensor - then the template sensors would show up there as expected and you would rely upon those instead, in this card - ?

type: custom:auto-entities
show_empty: false
card:
  type: entities
  show_header_toggle: false
  title: "Sensor / Connectivity Issues:"
  state_color: true
filter:
  include:
    - state: unknown
    - state: unavailable
  exclude:
    - name: /Reboot/
    - name: /device_tracker/
    - name: /kruse_s_s23/
    - name: /[fF]ile editor/
    - name: /holding until/
    - name: /firmware/
    - name: /Identify/
    - name: /Clear hold/
    - name: /Clear Hold/
    - name: /Cloud/
    - name: /Reload/
    - name: /Restart/
    - name: /Room/
    - name: /Kruse/
    - name: /Away Mode/
    - name: /Ludington Ridgewood/
    - name: /hold duration/
    - name: /Ding Dong/
    - name: /Last Ding/
    - name: /Pressed/
    - name: /BasementWaterMeter/
    - entity_id: switch.front_door_ring_doorbell_event_stream
    - entity_id: select.front_door_ring_doorbell_event_select
    - entity_id: sensor.den_archer_ax10_in_wap_mode_external_ip
    - entity_id: sensor.alarmfob_1_battery
    - entity_id: media_player.basement_google_nest_hub_max
    - entity_id: binary_sensor.den_archer_ax10_in_wap_mode_wan_status
    - entity_id: button.front_door_ring_doorbell_take_snapshot
    - entity_id: select.dining_room_ecobee_thermostat_current_mode
    - entity_id: climate.den_room
    - entity_id: climate.dining_room_room
    - entity_id: sensor.basement_right_railing_esp8266_ws2812b_estimated_current
    - entity_id: sensor.basement_left_railing_esp8266_ws2812b_estimated_current
    - entity_id: sensor.airnow_pm10
    - entity_id: select.basement_left_railing_esp8266_ws2812b_playlist
    - entity_id: select.basement_left_railing_esp8266_ws2812b_preset
    - entity_id: button.basement_left_railing_esp8266_ws2812b_restart
    - entity_id: select.basement_right_railing_esp8266_ws2812b_playlist
    - entity_id: select.basement_right_railing_esp8266_ws2812b_preset
    - entity_id: button.basement_right_railing_esp8266_ws2812b_restart
    - entity_id: select.bedroom_1_activity_status
    - entity_id: select.bedroom_2_activity_status
    - entity_id: select.bedroom_3_activity_status
    - entity_id: select.den_activity_status
    - entity_id: climate.bedroom_1_room
    - entity_id: climate.bedroom_2_room
    - entity_id: climate.bedroom_3_room
    - entity_id: button.master_controller_start_wlan_optimization
    - entity_id: button.ignore_all_issues
    - entity_id: button.unignore_all_issues
    - entity_id: sensor.basement_right_railing_esp8266_ws2812b_max_current
    - entity_id: sensor.basement_left_railing_esp8266_ws2812b_max_current
    - entity_id: device_tracker.*
    - entity_id: button.*
    - entity_id: sensor.backup_last_attempted_automatic_backup
    - entity_id: sensor.backup_last_successful_automatic_backup
    - entity_id: sensor.backup_next_scheduled_automatic_backup
sort:
  method: name
  reverse: false

I do have exclusions setup. What becomes unavailable can vary so I can’t just ignore them, but I don’t want the notification if it’s something that has only been gone for 1 minute or so. Looking at the documentation I see that there’s logic for that but I don’t quite know how to incorporate it in to the automations.

1 Like

Fortunately I do not have devices that come and go from the list on a regular basis, is that what you are running into? Possibly a networking issue which you might not want to throw $ right now to fix (if that is the case I’ve been there many a time!)?

Assuming the following attribute list:

effect_list:
  - blink
#<snipped for brevity>
  - stop_hue_effect
supported_color_modes:
  - brightness
friendly_name: Loft 1
supported_features: 44
effect: null
color_mode: null
brightness: null
last_seen: 1752857506303
linkquality: 207
power_on_behavior: "on"
update:
  installed_version: 16786690
  latest_version: 16787202
  progress: 9.06
  remaining: 2247
  state: updating
update_available: false

How would I go about filtering for lights with the update.state of ā€œupdatingā€ only? Either code editor or display editor answers are fine.

I’m less worried about how to display the information, as I’'ve gotten that to work.

Is there any way to use templating in the area filter rule? I almost have the perfect solution for my attempt at a dynamic light solution but I can’t seem to find a way of getting the below code to work. Hardcoding area (e.g. area: office) works, but that would require me to build static cards and I would prefer not doing that.

Any thoughts or ideas?

- type: custom:auto-entities
  card:
    type: entities
    icon: mdi:star
    show_header_toggle: false
  filter:
    include:
      - group: light.favourite_lights
        options:
          type: custom:layout-card
          layout_type: custom:grid-layout
          layout:
            grid-auto-flow: column
            margin: 0
            padding: 0
            card_margin: 0
          cards:
            - type: custom:expander-card
              padding: 0
              clear: true
              title-card-button-overlay: true
              title-card-clickable: false
              expanded: false
              title-card:
                type: vertical-stack
                cards:
                  - type: custom:mushroom-light-card
                    entity: this.entity_id
                    use_light_color: true
                    show_brightness_control: true
                    show_color_temp_control: true
                    show_color_control: true
                    collapsible_controls: true
                    layout: horizontal
                    fill_container: true
              cards:
                - type: custom:auto-entities
                  card:
                    type: grid
                    rows: 1
                    square: false
                  card_param: cards
                  filter:
                    include:
                      - domain: scene
                        area: "{{ area_id('this.entity_id') }}"
                        options:
                          type: custom:mushroom-template-card
                          entity: this.entity_id
                          primary: "{{ states.this.entity_id.attributes.icon_color  | default('#FFC143') }}"
                          icon: "{{ states.this.entity_id.attributes.icon }}"
                          icon_color: "{{ states.this.entity_id.attributes.icon_color  | default('#FFC143') }}"
                          use_light_color: false
                    exclude: []
                  show_empty: true

Hi all

I have written a small python script ā€œHƶrspiel Catcherā€ that scrapes the last five episodes of my favorite audio play from Spotify, e.g. in this case ā€œDie drei ???ā€ and sends it via MQTT to Home Assistant.

I use ā€œauto-entitiesā€ to set up one entities card per audio play:

type: custom:auto-entities
card:
  type: entities
  title: Die drei ???
  show_header_toggle: false
filter:
  include:
    - options:
        type: custom:template-entity-row
        name: "{{ state_attr('this.entity_id', 'title') }}"
        state: >
          {% set date = state_attr('this.entity_id', 'release_date') %} {{ date
          | regex_replace('^(\\d{4})-(\\d{2})-(\\d{2})$', '\\3.\\2.\\1') }}
        entity_picture: "{{ state_attr(this.entity_id, 'entity_picture') }}"
      entity_id: /horspiel_catcher_/
sort:
  method: attribute
  attribute: release_date
  reverse: true

That is the easy and working part though. Now the pain begins. I try to use tap-action to call the play_media service and start the album on a single Sonos Speaker.

        tap_action:
          action: call-service
          service: media_player.play_media
          target:
            entity_id: media_player.unnamed_room
          data:
            media_content_type: music
            media_content_id: "{{ state_attr('this.entity_id', 'spotify_uri') }}"
            enqueue: replace

Tapping the entry results in the following error:

Die Aktion media_player/play_media konnte nicht ausgeführt werden. Error calling SonosMediaPlayerEntity._play_media on media_player.unnamed_room: UPnP Error 714 received: Illegal MIME-Type from 10.0.0.55

I have tried so many different solutions back and forth, that i do not know what else I can try.
From what I understand, the tap_action part has to be (???) in a template part in the filter? At the moment the spotify_uri seems not to be resolved and is just text sended to the Sonos speaker, when I insert a hardcoded one, the action just works and in the dev tools too:

action: media_player.play_media
target:
  entity_id:
    - media_player.unnamed_room
data:
  media_content_type: music
  media_content_id: spotify:album:0qZ0R61AqoD2i8GnzUk91C

What am I doing wrong here / do not get?
Thanks in advance an have I nice weekend!

1 Like

@Rav
You might have a look at the SpotifyPlus Integration, which allows you to easily retrieve the recently played list. You can then build a sensor with the details, populate a dashboard of tiles with cover art and song title, then use the Player Media Play Tracks service to play a selected tile via tap-action.

I do something similar to the above by creating a Spotify Queue Info List Dashboard, which could easily be modified to display the Spotify Recently Played items instead of the Player Queue info.

There is also a SpotifyPlus Card user-interface that allows you to view recently played items, control the player, manage your Spotify favorites, as well as search the Spotify catalog. You have to install the SpotifyPlus integration first though, and get it configured before you can use the SpotifyPlus Card.

You could just enabled the Recently Played section of the card, if all you want is recently played. This would be the easiest to do, with minimal configuration.

Hope it helps!

Could just be quoting. i.e. For actions single line templates need to be quoted. However by the time auto-entities has done processing, media_content_id may not be quoted. So you may need to play around with your quoting.

Is it possible to auto-generate cards from an input list with templates?

I have a WLED display module and would like to generate a screen full of custom:button-card for every preset that is listed from WLED. The list is contained in select.wled and if I change the select value, the display shows the selected preset. And I would like to add a preview image of every preset (with the same name).

Would that even be possible with auto-entities? In theory something like this:

{% for preset in state_attr('sensor.wled_preset_liste', 'presets') %}
  - type: custom:button-card
    name: {{ preset }}
    icon: mdi:lightbulb
    tap_action:
      action: call-service
      service: script.wled_preset
      service_data:
        preset: "{{ preset }}"
  {% endfor %}

OK. I have done some testing and I don’t believe you can template media_content_id or any data in an action on a card. What you can do is call a script passing entity_id and then template a variable before calling media_player.play_media

1 Like

@Rav
I just put this together for use with the SpotifyPlus integration. You might be able to do something similar with your requirements. Note that ALL of this is done in HA (no Python scripts nor MQTT required). It also plays on the specified Sonos device when a tile graphic is clicked.

Recently Played Dashboard

Displays the Spotify Recently Played list for a given SpotifyPlus media player.

This will allow you to select a recently played item for play on the media player by tapping on a track image.

How it Looks

How it Works

A template trigger is defined (via configuration.yaml) that will fire when the integration updates its media_content_id attribute (e.g. a Spotify track uri value). The integration updates this attribute whenever the current track ends, and a new track begins.

The template trigger action calls the integrations’ get_player_recent_tracks service to retrieve the current list of Spotify recently played entries. The list is returned as service response data, which gets stored to a variable named service_response.

The template trigger sensor step updates the sensor.spotifyplus_recent_info template sensor state to the current datetime value. It also sets the tracks attribute with a summarized list of recently played track data: name, uri, image_url, and artist.

The template sensor can then be referenced in Lovelace UI cards that support templates.

Requirements

The following are required in order to use this dashboard:

  • configuration.yaml trigger definitions (see below).
  • input_boolean.always_enabled_helper must be defined as an ā€˜always on’ toggle switch. This is defined in the HA Configuration Helpers page as a toggle switch named always_enabled_helper. Once it is defined set it to On and leave it on.

Limitations

The returned list of items will be truncated if the size of the list exceeds 16k in length. This should not be a problem, unless you start adding more track fields to the data that is stored for each track. This is due to the fact that the HA trigger sensor can only store a maximum of 16k of data in the HA state database entry.

A maximum of 50 recently played items can be returned due to Spotify Web API limitations.

configuration.yaml Changes

The following must be added to your configuration.yaml (or equivalent template definitions file). It is a trigger that detects when the track media_content_id changes on the media player, and updates a template sensor with the current track info.

You will need to make the following changes to the yaml:

  • change media_player.YOUR_SPOTIFYPLUS_ENTITY_ID to your SpotifyPlus media player entity_id (e.g. media_player.spotifyplus_username)
# SpotifyPlus Recently Played Update Template Sensor.
# Triggered when the 'media_content_id' state changes (or when HA starts).
# IMPORTANT - Always set the sensor name and unique_id to match
  - trigger:
      - platform: state
        entity_id:
          - media_player.YOUR_SPOTIFYPLUS_ENTITY_ID 
        attribute: media_content_id
      - platform: homeassistant
        event: start
    action:
      - service: system_log.write
        data:
          level: info
          logger: my_templates_automation
          message: "Automation triggered: SpotifyPlus Recently Played Update Trigger"
      - service: spotifyplus.get_player_recent_tracks
        data:
          entity_id: media_player.YOUR_SPOTIFYPLUS_ENTITY_ID
          after: 0
          before: 0
        response_variable: service_response
    sensor:
      - name: spotifyplus_recent_info
        unique_id: spotifyplus_recent_info
        state: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
        attributes:
          tracks: >
            {% set ns = namespace(tracks=[]) %}
            {%- for item in service_response['result']['items'] -%}
              {%- set itemTrk = item['track'] -%}
              {%- set trackName = itemTrk['name'] | default('') -%}
              {%- set trackImageUrl = itemTrk['image_url'] | default('') -%}
              {%- set trackUri = itemTrk['uri'] | default('') -%}
              {%- set trackArtist = itemTrk['artists'][0]['name'] | default('') -%}
              {%- set track = {'name': trackName, 'uri': trackUri, 'image_url': trackImageUrl, 'artist': trackArtist} -%}
              {%- set ns.tracks = ns.tracks + [track]  -%}
            {%- endfor -%}
            {{ ns.tracks|to_json(sort_keys=True,ensure_ascii=True,pretty_print=True) }}

Lovelace UI Card Definition

Add the following YAML to a dashboard of your choice. I chose a View Type of Panel (1 card) for my dashboard, so it covers the entire width of the viewport.

This will dynamically build and format the recently played list into a grid with cover artwork and titles.

You will need to make the following changes to the yaml:

  • change media_player.YOUR_SPOTIFYPLUS_ENTITY_ID to your SpotifyPlus media player entity_id (e.g. media_player.spotifyplus_username)
  • change YOUR_DEVICE_ID to the Spotify Connect device id you want to play the track on (e.g. Office Speaker)
type: vertical-stack
cards:
  - type: markdown
    content: |-
      # SpotifyPlus Recently Played
      Tap an item to play the content.
      Last refreshed on: {{ states('sensor.spotifyplus_recent_info') }}
  - type: custom:auto-entities
    card:
      type: grid
      columns: 8
    card_param: cards
    filter:
      template: >-
        {% set serviceResponse = None -%} 

        {%- set itmMediaPlayerEntityId = 'media_player.YOUR_SPOTIFYPLUS_ENTITY_ID' -%}

        {%- set itmDeviceId = 'YOUR_DEVICE_ID' -%}

        {%- if has_value('sensor.spotifyplus_recent_info') -%}

        {%-   set serviceResponse =
        state_attr('sensor.spotifyplus_recent_info','tracks') -%}

        {%- endif -%}

        {%- if serviceResponse != None -%}
          {%- for track in serviceResponse -%}
          
            {%- set trackImageUrl = track['image_url'] | default('/local/spotifyplus/default.png') -%}
            {%- set trackName = track['name'] | default('unknown') -%}
            {%- set trackUri = track['uri'] | default('') -%}
            {{
              {
        'type': 'picture-entity', 'entity':
        'input_boolean.always_enabled_helper', 'image': trackImageUrl,
        'show_state': false, 'show_name': true, 'name': trackName, 
        'tap_action': {
          'action': 'perform-action',
          'perform_action': 'spotifyplus.player_media_play_tracks',
          'data': {
            'entity_id': itmMediaPlayerEntityId,
            'uris': trackUri,
            'device_id': itmDeviceId
            }
          }
              }
            }},
          {%- endfor -%}
        {%- endif -%}
6 Likes

@dcapslock

Hi Darryn

Thanks for the hint!

As a quick workaround, I now use an input_text helper that receives the respective URI and forwards it to an automation that addresses the appropriate Sonos speaker and plays the respective episode there. The advantage is that you can also start different radio plays in several rooms (not that I need it).

        tap_action:
          action: call-service
          service: input_text.set_value
          data:
            entity_id: input_text.spotify_uri
            value: this.entity_id

1 Like

@thlucas

Hey Todd

Wow, thank you very much for your help and effort!

Following your Github documentation the ā€œArtist Favorites Sectionā€ and your comments regarding triggers and templates should help a lot.

I will definitely take a look at your integration!

1 Like

FYI: Button changes in HA 2025.8 (currently in beta) break auto-entities GUI editor buttons (add filters, delete filter, card gui/visual, change card).

I have raised an issue, created a PR and also provide a build with fix which includes other recent PRs I have submitted.

See HA 2025.8 button migration causes Auto Entities editor buttons to fail Ā· Issue #563 Ā· thomasloven/lovelace-auto-entities Ā· GitHub

1 Like

I wanted to share the progression that I made with one of my auto-entities cards. Special thanks goes out to @Mariusthvdb for pointing me in the right direction to get the card_mod to work in the final result and @Ildar_Gabdullin’s Entities card post in the card_mod thread.

This is what I started with using - entity_id: sensor.*_motion_detector_battery_level include:

Code
type: custom:auto-entities
card:
  type: entities
  title: Motion Detector Batteries
  card_mod:
    style: |
      ha-card {
        background: black;
        --primary-text-color: white;
      }
filter:
  include: 
    - entity_id: sensor.*_motion_detector_battery_level
  exclude:
    - options: {}
      state: unavailable
    - options: {}
      hidden_by: user
sort:
  method: state
  numeric: true
  reverse: true

I added card_mod to colorize the states and icons using the red-to-green scale template that I posted in Green-to-red icon color gradient template (battery percentage).

Code
type: custom:auto-entities
card:
  type: entities
  title: Motion Detector Batteries
  card_mod:
    style: |
      ha-card {
        background: black;
        --primary-text-color: white;
      }
filter:
  include:
    - entity_id: sensor.*_motion_detector_battery_level
      options:
        card_mod:
          style:
            hui-generic-entity-row $: |
              {% set percentage = states(config.entity) | int %}
              {% set r, g, b = 0, 0, 0 %}
              {% if (percentage <= 51) %}
                {% set r = 255 %}
                {% set g = (5.0 * percentage) | round | int %}
              {% else %}
                {% set g = 255 %}
                {% set r = (505 - 4.89 * percentage) | round | int %}
              {% endif %}
              {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}
              .state { color: {{ gradient }} }
              state-badge { color: {{gradient}}; }  
  exclude:
    - options: {}
      state: unavailable
    - options: {}
      hidden_by: user
sort:
  method: state
  numeric: true
  reverse: true

I did not like how each entity had Motion Detector Battery Level in the name. To fix this, I knew I needed to be able to use a template to get the entities, replace the text, and still apply the card_mod. This is the end result.

Code
type: custom:auto-entities
card:
  type: entities
  title: Motion Detector Batteries
  card_mod:
    style: |
      ha-card {
        background: black;
        --primary-text-color: white;
      }
unique: entity
show_empty: true
filter:
  template: |
    {%- set device_list = states.sensor 
      | selectattr('entity_id', 'search', 'motion_detector_battery_level')
      | rejectattr('state' , 'in' , ['unknown','unavailable'])
      | map(attribute='entity_id')
      | list -%} 
    {%- for device in device_list -%}
      {{ { 
        'entity': device,
        'name': state_attr(device, "friendly_name") | regex_replace(find='Motion Detector Battery Level', replace='', ignorecase=true) ,
        'card_mod': 
          {'style':
            {'hui-generic-entity-row $': '
              {% set percentage = states(config.entity) | int %}
              {% set r, g, b = 0, 0, 0 %}
              {% if (percentage <= 51) %}
                {% set r = 255 %}
                {% set g = (5.0 * percentage) | round | int %}
              {% else %}
                {% set g = 255 %}
                {% set r = (505 - 4.89 * percentage) | round | int %}
              {% endif %}
              {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}

              .state { color: {{ gradient }}; }
              state-badge { color: {{ gradient }}; }'
            }
          }
      } }},
    {%- endfor -%}
sort:
  method: state
  reverse: true
  numeric: true

The final template can be easily adapted to use a list of entities similar to the standard include: method where a complex template is not needed but can still utilize the rest of the code.

Code
{%- set device_list = [
  'sensor.s25_ultra_battery_level', 'sensor.watch5_battery_level',
  'sensor.tab_s7_fe_battery_level', 'sensor.ipad_battery_level'
] -%} 

UPDATE: This example shows how to find multiple strings to be removed from the displayed name. regex_replace(find='Battery Level|Door|Battery', replace='', ignorecase=true)

Code
type: custom:auto-entities
card:
  type: entities
  title: Sensor Batteries
  card_mod:
    style: |
      ha-card {
        background: black;
        --primary-text-color: white;
      }
unique: entity
show_empty: true
filter:
  template: |
    {%- set device_list = [
      'sensor.refrigerator_battery','sensor.freezer_battery',
      'sensor.living_room_door_battery_level','sensor.bathroom_door_battery_level',
      'sensor.hallway_closet_battery_level'
    ] -%} 
    {%- for device in device_list -%}
      {{ { 
        'entity': device,
        'name': state_attr(device, "friendly_name") | regex_replace(find='Battery Level|Door|Battery', replace='', ignorecase=true),
        'card_mod': 
        
          {'style':
            {'hui-generic-entity-row $': '
              {% set percentage = states(config.entity) | int %}
              {% set r, g, b = 0, 0, 0 %}
              {% if (percentage <= 51) %}
                {% set r = 255 %}
                {% set g = (5.0 * percentage) | round | int %}
              {% else %}
                {% set g = 255 %}
                {% set r = (505 - 4.89 * percentage) | round | int %}
              {% endif %}
              {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}

              .state { color: {{ gradient }}; }
              state-badge { color: {{ gradient }}; }'

            }
          }
      } }},
    {%- endfor -%}
sort:
  method: state
  reverse: true
  numeric: true

At the risk of going off-topic, here’s how I’ve brought this all together. I use the /breakthestatic/swipe-card (which is a little more up-to-date than /bramkragten/swipe-card).
20250809-2231

Code
type: custom:swipe-card
start_card: 2
parameters:
  effect: cube
  loop: true
  freeMode: true
  speed: 4000
  autoplay:
    delay: 2500
    disableOnInteraction: false
    reverseDirection: false
    stopOnLastSLide: false
cards:
  - type: custom:auto-entities
    card:
      type: entities
      title: My Devices
      card_mod:
        style: |
          ha-card {
            background: black;
            --primary-text-color: white;
          }
    unique: entity
    show_empty: true
    filter:
      template: |
        {%- set device_list = [
          'sensor.s25_ultra_battery_level', 'sensor.watch5_battery_level',
          'sensor.tab_s7_fe_battery_level', 'sensor.dereks_ipad_battery_level'
        ] -%} 
        {%- for device in device_list -%}
          {{ { 
            'entity': device,
            'name': state_attr(device, "friendly_name") | regex_replace(find='Battery Level', replace='', ignorecase=true) ,
            'card_mod': 
            
              {'style':
                {'hui-generic-entity-row $': '
                  {% set percentage = states(config.entity) | int %}
                  {% set r, g, b = 0, 0, 0 %}
                  {% if (percentage <= 51) %}
                    {% set r = 255 %}
                    {% set g = (5.0 * percentage) | round | int %}
                  {% else %}
                    {% set g = 255 %}
                    {% set r = (505 - 4.89 * percentage) | round | int %}
                  {% endif %}
                  {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}

                  .state { color: {{ gradient }}; }
                  state-badge { color: {{ gradient }}; }'

                }
              }
          } }},
        {%- endfor -%}
    sort:
      method: state
      reverse: true
      numeric: true
  - type: custom:auto-entities
    card:
      type: entities
      title: Motion Detector Batteries
      card_mod:
        style: |
          ha-card {
            background: black;
            --primary-text-color: white;
          }
    unique: entity
    show_empty: true
    filter:
      template: |
        {%- set device_list = states.sensor 
          | selectattr('entity_id', 'search', 'motion_detector_battery_level')
          | rejectattr('state' , 'in' , ['unknown','unavailable'])
          | map(attribute='entity_id')
          | list -%} 
        {%- for device in device_list -%}
          {{ { 
            'entity': device,
            'name': state_attr(device, "friendly_name") | regex_replace(find='Motion Detector Battery Level', replace='', ignorecase=true),
            'card_mod': 
            
              {'style':
                {'hui-generic-entity-row $': '
                  {% set percentage = states(config.entity) | int %}
                  {% set r, g, b = 0, 0, 0 %}
                  {% if (percentage <= 51) %}
                    {% set r = 255 %}
                    {% set g = (5.0 * percentage) | round | int %}
                  {% else %}
                    {% set g = 255 %}
                    {% set r = (505 - 4.89 * percentage) | round | int %}
                  {% endif %}
                  {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}

                  .state { color: {{ gradient }}; }
                  state-badge { color: {{ gradient }}; }'

                }
              }
          } }},
        {%- endfor -%}
    sort:
      method: state
      reverse: true
      numeric: true
  - type: custom:auto-entities
    card:
      type: entities
      title: Sensor Batteries
      card_mod:
        style: |
          ha-card {
            background: black;
            --primary-text-color: white;
          }
    unique: entity
    show_empty: true
    filter:
      template: |
        {%- set device_list = [
          'sensor.refrigerator_battery','sensor.freezer_battery',
          'sensor.living_room_door_battery_level','sensor.bathroom_door_battery_level',
          'sensor.hallway_closet_battery_level'
        ] -%} 
        {%- for device in device_list -%}
          {{ { 
            'entity': device,
            'name': state_attr(device, "friendly_name") | regex_replace(find='Battery Level|Door|Battery', replace='', ignorecase=true),
            'card_mod': 
            
              {'style':
                {'hui-generic-entity-row $': '
                  {% set percentage = states(config.entity) | int %}
                  {% set r, g, b = 0, 0, 0 %}
                  {% if (percentage <= 51) %}
                    {% set r = 255 %}
                    {% set g = (5.0 * percentage) | round | int %}
                  {% else %}
                    {% set g = 255 %}
                    {% set r = (505 - 4.89 * percentage) | round | int %}
                  {% endif %}
                  {% set gradient = "#%0x" | format( r * 0x10000 + g * 0x100 + b * 0x1 ) %}

                  .state { color: {{ gradient }}; }
                  state-badge { color: {{ gradient }}; }'

                }
              }
          } }},
        {%- endfor -%}
    sort:
      method: state
      reverse: true
      numeric: true
5 Likes

yes, nice! we have too few examples of filter templates with more complex card-mod stylings, so this is great resource material. Let me add one that we handled in the process:

{% for b in label_entities('batterij') %} {{
  {
    'entity': b,
    'card_mod':
      {'style':
          "hui-generic-entity-row {
              background:
                {% set perc = states(config.entity)|float(0) %}
                {% set rest = 100 - perc %}
                {% if perc <= 10 %} {% set bar = '255,0,0' %}
                {% elif perc <= 20 %} {% set bar = '255, 51, 0' %}
                {% elif perc <= 30 %} {% set bar = '255, 85, 0' %}
                {% elif perc <= 40 %} {% set bar = '255, 153, 0' %}
                {% elif perc <= 50 %} {% set bar = '255, 204, 0' %}
                {% elif perc <= 60 %} {% set bar = '255, 255, 0' %}
                {% elif perc <= 70 %} {% set bar = '204, 255, 0' %}
                {% elif perc <= 80 %} {% set bar = '153, 255, 0' %}
                {% elif perc <= 90 %} {% set bar = '102, 255, 0' %}
                {% else %} {% set bar = '51, 255, 0' %}
                {% endif %}
                linear-gradient(to right, rgb({{bar}},0.9) 0%, rgb({{bar}},0.6) {{perc}}%,
                                          rgba({{bar}},0.3){{perc}}%, rgba({{bar}},0.1) 100%);
            }
            :host {
              --card-mod-icon-color:
                {% set perc = states(config.entity)|float(0) %}
                {% if perc <= 10 %} rgb(225, 20, 60)
                {% elif perc <= 20 %} rgb(153, 38, 0)
                {% elif perc <= 30 %} rgb(153, 38, 0)
                {% elif perc <= 40 %} rgb(153, 115, 0)
                {% elif perc <= 50 %} rgb(153, 153, 0)
                {% elif perc <= 60 %} rgb(153, 153, 0)
                {% elif perc <= 70 %} rgb(115, 153, 0)
                {% elif perc <= 80 %} rgb(77, 153, 0)
                {% elif perc <= 90 %} rgb(38, 153, 0)
                {% else %} rgb(0, 153, 0)
                {% endif %};
              }"
      }
  }
}},{% endfor %}

it is an exercise in quoting, but in this case turned out to be way simpler than I had figured. I just dropped in the complex bit after 'style': inside double quotes to make that a single string and the mod was there.

it is essentially the filter template variant of this include version

Yaml for the 'include' version
type: custom:auto-entities
card:
  type: entities
  title: Battery Status
  card_mod:
    class: class-header-margin
    style:
      hui-sensor-entity-row:
        $: |
          hui-generic-entity-row {
            height: 25px;
            padding: 0px 16px;
            border-radius: var(--ha-card-border-radius);
            border: 1px groove var(--divider-color);
          }
      .: |
        ha-card {
          color: var(--secondary-color);
          font-weight: 400;
        }
        .card-content {
          max-height: 450px;
          overflow-y: scroll;
        }
  state_color: false
  show_header_toggle: false
filter:
  include:
    - options:
        card_mod:
          style: |
            hui-generic-entity-row {
              background:
                {% set perc = states(config.entity)|float(0) %}
                {% set rest = 100 - perc %}
                {% if perc <= 10 %} {% set bar = '255,0,0' %}
                {% elif perc <= 20 %} {% set bar = '255, 51, 0' %}
                {% elif perc <= 30 %} {% set bar = '255, 85, 0' %}
                {% elif perc <= 40 %} {% set bar = '255, 153, 0' %}
                {% elif perc <= 50 %} {% set bar = '255, 204, 0' %}
                {% elif perc <= 60 %} {% set bar = '255, 255, 0' %}
                {% elif perc <= 70 %} {% set bar = '204, 255, 0' %}
                {% elif perc <= 80 %} {% set bar = '153, 255, 0' %}
                {% elif perc <= 90 %} {% set bar = '102, 255, 0' %}
                {% else %} {% set bar = '51, 255, 0' %}
                {% endif %}
                linear-gradient(to right, rgb({{bar}},0.9) 0%, rgb({{bar}},0.6) {{perc}}%,
                                          rgba({{bar}},0.3){{perc}}%, rgba({{bar}},0.1) 100%);
            }
            :host {
              --card-mod-icon-color:
                {% set perc = states(config.entity)|float(0) %}
                {% if perc <= 10 %} rgb(225, 20, 60)
                {% elif perc <= 20 %} rgb(153, 38, 0)
                {% elif perc <= 30 %} rgb(153, 38, 0)
                {% elif perc <= 40 %} rgb(153, 115, 0)
                {% elif perc <= 50 %} rgb(153, 153, 0)
                {% elif perc <= 60 %} rgb(153, 153, 0)
                {% elif perc <= 70 %} rgb(115, 153, 0)
                {% elif perc <= 80 %} rgb(77, 153, 0)
                {% elif perc <= 90 %} rgb(38, 153, 0)
                {% else %} rgb(0, 153, 0)
                {% endif %};
              }
      entity_id: sensor.*_battery_level
sort:
  method: state
  numeric: true
  reverse: false
show_empty: false
2 Likes

I am trying to make a low battery warning card that will leverage the entities created by Battery Notes. I have been able to successfully create cards that

  1. Populate device battery levels that are below a defined threshold, i.e. lower than 20%, and…
  2. Populate with devices with low batteries using the battery_low entity (binary_sensor.*_battery_sensor_low)

What I am trying to create is a card that will use both. The card would display that battery level when the battery falls below the Battery Notes low battery threshold. So when a sensor ā€œbinary_sensor.*_battery_sensor_lowā€ is ā€œonā€, then the card will display the device and the battery level. I have been trying to creat the card without having to make an entry in the code for each sensor, but rather one that would work off of any device in the battery notes integration.

So far, everything I have tried has not worked.

Anyone have any tips?

Have you looked at the Low battery level detection & notification for all battery sensors blueprint?
Low battery level detection & notification for all battery sensors - Blueprints Exchange - Home Assistant Community

@jeffcrum I have, and if I understand that blueprint correctly, it works similarly as an auto-entities card that will populate when a battery falls below a predetermined level. That predetermined level then is the same for all batteries. What I am trying to accomplish is varying levels for different batteries, and this is where integrating the ā€˜binary_sensor.*_battery_sensor_low’ comes in. Inside of the Battery Notes integration, you can set different low levels for each battery. When that individual battery falls below it’s predetermined level set in the sensor provided by the Battery Notes integration, it would be considered low. This way I could have one battery below at 30% and another at 20%, all individually configurable from battery notes and not having to change the code in the Auto-Entity for each battery.