Template to display loaded components on HA instance?

For anyone using a recent version of Home Assistant, this works:

  - platform: rest
    name: My Config
    resource: http://localhost:8123/api/config
    authentication: basic
    value_template: "{{ value_json.version }}"
    json_attributes:
      - components
      - unit_system
      - config_dir
    headers:
      Content-Type: application/json
      Authorization: !secret api_bearer_token
      User-Agent: Home Assistant REST sensor

api_bearer_token is a string (in secrets.yaml) containing:

api_bearer_token: Bearer <your long-lived access token goes here>
4 Likes

I knew I saw loaded components somewhere and I have been looking everywhere to try and find it. I wanted to do exactly what you are trying to achieve. Cheers

Glad I came and checked this thread before I started working on a Python script!

@Mariusthvdb does this satisfy what you’re looking for? If you want to display it as a sorted, formatted list in Lovelace, you can use the new card-templater card and apply it to a Markdown card with the following template:

{% for component in states.sensor.my_config.attributes.components|sort -%}
  {{ component  + "\n"}}
{%- endfor %}
2 Likes

yes it does, and its working. on my ha 84.3 system I need the authorization using the bearer token, for my 92.1 system I can use below configuration …without authentication, from another instance that is, havent checked in on the system itself yet)


using this:

  - platform: rest
    name: Hassio Main config
    resource: https://mydomain.duckdns.org:8123/api/config
    value_template: "{{ value_json.version }}"
    json_attributes:
      - components
      - unit_system
      - config_dir

! Thanks @123!
please help me get this into a python script

{% for component in state_attr('sensor.hassio_main_config','components')|sort -%}
  {{ component  + "\n"}}
{%- endfor %}

so I can use

state = hass.states.get('sensor.hassio_main_config').state

components = state.attributes.get('components')


hass.states.set('sensor.components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': components
    })

using that custom_ui_state_card, I can show the card in regular HA too!

Can we get the domains like this too? The state of the template sensor in my first post is way too long also, so if we could get that in to an attribute via the rest api that would be very nice indeed.

https://mydomain.duckdns.org:8124/api/services and then some nifty value_template to sort the domain names only?

I’m a little out of my depth on this one, as I pretty much went straight to Lovelace UI when I started with Home Assistant, and I’m not really familiar with custom_ui_state_card.

never mind the state card, thats only to represent the outcome in a regular HA card and can’t show more than max 255 characters.

Im now trying to get the components in this python script… maybe you would be know how to help, I seem to have forgotten the correct syntax… been a while since I wrote my last python ;-(

same goes for the domains sensor. I can now only show the number of domains, nt the domains themselves.

update

found it… duh

components = hass.states.get('sensor.hassio_main_config').attributes['components']

hass.states.set('sensor.components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': components
    })

would you please be able to give me the code for that?
havent used that card before, this might be a fine reason to start…

Yes, I was going to put it together tonight. I’ll post it when it’s done.

well, finally made some progress, showing in regular HA:

51

now I want to ‘unlist’ this showing each component on its own line, and dont show the brackets and quotes. Also want to list them alphabetically, but thats of second concern.

Should be very easily be able to do that with the for loop, but didn’t get the correct syntax yet, please have a look?
after that I can simply substitute the format(components) with format(line)…

components = hass.states.get('sensor.hassio_main_config').attributes['components']

for c in components:
    state = hass.states.get(c)
    line = '{}\n'.format(state)

text = '*========== {} Loaded Components ========\n' \
                 '+{}' \
                 .format(len(components),
                         components)


hass.states.set('sensor.hassio_main_components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': text
    })

This is doing nothing in your code. Why have it?

This will get you everything on it’s own line.

components = hass.states.get('sensor.hassio_main_config').attributes['components']
components.sort()

text = ['*========== {} Loaded Components ========'.format(len(components))]
text = text + components
text = '\n'.join(text)

hass.states.set('sensor.hassio_main_components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': text
    })

Indeed, it just showed it to give an idea of what I was looking for. and yes, your code works, thank you!

could I order that alphabetically also?
Since this is a very long card now (… i know, i asked for it) maybe format it as a comma separated listing (still without the quotes and brackets?

52

like this:

text = ', '.join(text)

24

updated the code to handle sorting

there’s a bit of a caveat: Id need the header to have another color code (* in this case ) than the rest of the list. Right now the * works on the full text , since you add the header to that text and the following lines consecutively. Somehow Id love to be able to separate those.

that’s the way the custom-ui card works. Example of another card:

        busted=""
        busted_badge=""

        if (len(results)) > min_items_to_show or show_if_empty:
            visible = True
            for e in results:
                line = '{} in: {}'.format(e, ','.join(grouped_entities[e]))
                busted = '{}!- {}\n'.format(busted,line)
                busted_badge = '{}{}\n'.format(busted_badge,line)
                friendly_name_badge = len(results)
        else:
            visible = False
            busted = '!- All busted, {} Ghosts found!\n'.format(len(results))
            busted_badge = 'No Ghosts found\n'
            friendly_name_badge = 'All busted'

    ghost_card = '*=========== Ghosts ===========\n' \
                 '{}\n' \
                 '*========= Entity count =========\n' \
                 '!- {} entities to list\n' \
                 '#- {} real entities\n' \
                 '+- {} grouped entities\n' \
                 '+- {} groups processed\n' \
                 '*========== Settings ===========\n' \
                 '/- targetting group: {}\n' \
                 '$- ignoring {} items:\n' \
                 '%|-> {}\n' \
                 '$- ignoring {} domains:\n' \
                 '%|-> {}' \
                 .format(busted,
                         len(results),
                         len(real_entities),
                         len(grouped_entities),
                         len(processed_groups),
                         target_group,
                         len(ignore_items),
                         ignore_items_unlist,
                         len(ignore_domains),
                         ignore_domains_unlist)

    hass.states.set('sensor.ghosts_sensor', len(results), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': ghost_card,
         })

showing as:

what indicates the color code?

found it as I corrected my post above…

see: ‘*’ for bold:

14

‘+’ for green:

18

##########################################################################################
# Codes for text_colors declared in 
# Custom card: /custom_ui/state-card-value_only.html
# changed to use below customizing options:
##########################################################################################

#      case "*": return "bold";
#      case "/": return "italic";
#      case "!": return "red";
#      case "+": return "green";
#      case "=": return "yellow";
#      case "%": return "grey";
#      case "$": return "brown";
#      case "#": return "blue";
#      default:  return "normal";

ah, try this

components = hass.states.get('sensor.hassio_main_config').attributes['components']
cnt = len(components)
components.sort()
components = ', '.join(components)

text = '*========== {} Loaded Components ========\n+'.format(cnt)
text = text + components

hass.states.set('sensor.hassio_main_components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': text
    })

tried it but that results in the same, because there is still text = text + components.
This works:

components = hass.states.get('sensor.hassio_main_config').attributes['components']
components.sort()
components = ', '.join(components)

text = '*========== {} Loaded Components ========\n' \
        '{}' \
          .format(len(components),
                  components)


hass.states.set('sensor.hassio_main_components', len(components), {
        'custom_ui_state_card': 'state-card-value_only',
        'text': text
    })

29

though now my count is off…

so changed a bit:

components = hass.states.get('sensor.hassio_main_config').attributes['components']
count = len(components)
components.sort()
list = ', '.join(components)

text = '*========== {} Loaded Components ========\n' \
        '{}' \
          .format(count,
                  list)


hass.states.set('sensor.hassio_main_components', count, {
        'custom_ui_state_card': 'state-card-value_only',
        'text': text
    })

bingo:

49

thanks!

text = '*========== {} Loaded Components ========\n' \
        '{}' \
          .format(count,
                  list)

vs

text = '*========== {} Loaded Components ========\n+'.format(count)
text = text + components

is the exact same code, no different in how the strings are added together. custom ui must do something funky.

Try this out:

type: 'custom:card-templater'
card:
  content_template: |-
    {{ "<details>\n"}}
    {% for component in states.sensor.my_config.attributes.components|sort -%}
      {{ component  + "\n"}}
    {%- endfor %}
    {{ "</details>" }}
  title_template: '{{states.sensor.my_config.attributes.components|length}} Components Loaded'
  type: markdown
entities:
  - sensor.my_config

It will look like this initially:
image

and then expands to show all:
image

I couldn’t successfully use the <summary> tag to change the phrasing from “Details”, maybe someone more well-versed in Markdown can take this a step further. But it’s a starting point.

1 Like

It does give the opportunity to use the extra color/style tag though.
Which in this case was what I was looking for.
Completely missed the tag at the end of the first line…can confirm this to work indeed.
I’ll note the variation though for future use!