How to add a global attribute to all entities of a certain domain

Im trying to add an attribute to all entities of a certain domain
so i thought to do it via customize_global.yaml

"camera.*":
  ftp_available: >
   {% for s in states.switch if 'ftp' in s.entity_id and this.device_id == s.deviced_id %}{% endfor %}

the result is that the attribute is added to all camera entities but the value is a string of the code
Screenshot 2024-03-25 152344

how can i solve it?

Custom attributes do not support templating, only static values.

FWIW, even if they did, your template doesn’t contain any expressions… so it’s hard to tell what you are actually trying to do.

If you want customize_glob to work, you need to use a “naming” convention so the desired entity IDs can be found using only the basic pattern-matching function demonstrated in the docs.

well i tried with static values but doesn’t work:

switch.*ftp*:
  camera_service: >-
    {{ integration_entities('reolink') | list }}

that’s still a template.

if you’re using {{ or {%, you’re in template mode…

1 Like

so how can i achieve my goal?

You can only do that by building a custom integration and defining devices that way.

But, if you are using Reolinks, that functionality is already available for most, if not all, of the cameras through the official integration.

What is your goal?

Your first template has no output, and the second template would output a list of all entities held by the Reolink integration. Do you really want every switch with “ftp” in it’s entity ID to have an attribute that contains such a list?

Not exactly, i want to add an attribute to every camera (ftp_available: true/false) that checks if that camera’s product has also a switch with “ftp” in it’s entity ID.

AFAIK, there’s no way to directly do that.

Options:

  1. Use the Template editor tool to “print” the configuration, then copy/paste it into place.

    • Pro: No need for additional entities, attribute is added to the camera.
    • Con: You would still need to manually update the configuration any time you add or change camera entities.
  2. Use an attribute in a template sensor or custom jinja variable to store a list of camera entities that match your criteria.

    • Pro: Updates automatically (or, in the case of the custom jinja variable, can be automated to update).
    • Con: No way to tell by simply looking at the camera entity.
    • Con: May require more complex templating in the long run.

I had already thought about the second case you listed but I wanted to avoid creating a new sensor. It would have been more convenient to add an attribute to each individual camera entity. If you argue that this is impossible, I have already developed a sensor that achieved this purpose. Please check it out and tell me what you think.

- platform: template
  sensors:
    all_cams_sensor:
      friendly_name: All cams sensor
      value_template: >
       {%- for s in states.camera %}
       {%- if loop.first %}{{loop.length}}{% endif %}
       {%- endfor %}
      attribute_templates:
        list: >
         {%- for s in states.camera %}
         {{s.entity_id}}{% if not loop.last %}, {% endif %}
         {%- endfor %}
        cams_offline: >
         {%- for s in states.camera 
         if s.state == 'unavailable' %}
         {{s.entity_id}}{% if not loop.last %}, {% endif %}
         {%- endfor %}
        cams_with_FTP: >
         {%- for cams in states.camera | map(attribute='entity_id')-%}
         {% set camid = device_id(cams) %}
         {% for ftp in states.switch | selectattr('entity_id', 'contains', 'ftp')%}
         {% if  device_id(ftp.entity_id) == camid%}
         {{ ftp.entity_id}} {% endif %}{%endfor%}
         {%- endfor -%}

I don’t know what you’re talking about. Setting up a sensor with the data in its attributes is one of the two options I listed… why would I say it was impossible?

I think you need to review the available filters and methods. What is the point of all those loops? Using filters is both more efficient and easier to read. For example, the following returns the same value as your method above.

value_template: "{{ states.camera | count }}"

Also, be aware that all of those attributes are returning stings, not functional lists. By actually making the list attribute a functional list then using the self-referencing variable this in the subsequent templates they wouldn’t have to recalculate everything all over again.

I think that your suggestion about creating a sensor from which to obtain information on a specific domain makes more sense for many aspects, first of all that it updates automatically if there is a change in states in real time.

Furthermore, following your suggestions on creating a list format and reusing that to obtain values with the this state, allowed me to develop what you see below:

- platform: template
  sensors:
    all_cams_sensor:
      friendly_name: All cams sensor
      value_template: >
         {% set ns = namespace(entity_id=[]) %}
         {% for s in states.camera %}
         {% set ns.entity_id = ns.entity_id + [ '%s' % (s.entity_id ) ] %}
         {% endfor %}
         {{ ns.entity_id |sort(attribute='entity_id') | list | join(', ') }}
      attribute_templates:
        device_ids: >
         {% set ns = namespace(device_id=[]) %}
         {% for s in this.state.split(', ') |list%}
         {% set ns.device_id = ns.device_id + [ '%s' % device_id(s) ]  %}
         {% endfor %}
         {{ ns.device_id}}
        online_cams: >
         {{ this.state.split(', ') | select('is_state', 'idle') |list}}
        offline_cams: >
          {{ this.state.split(', ') | select('is_state', ['unknown','unavailable']) |list}}
        cams_with_FTP: >
         {% set ns = namespace(entity_id=[]) %}
         {% for ftp in states.switch | selectattr('entity_id', 'contains', 'ftp') %}
         {% if  device_id(ftp.entity_id) in this.attributes.device_ids %}
         {% set ns.entity_id= ns.entity_id + [ '%s' % (ftp.entity_id) ]  %}{%endif%}
         {% endfor %}
         {{ ns.entity_id | list }}
        cams_without_FTP: >
         {% set ns = namespace(entity_id=[]) %}
         {% for ftpid in this.attributes.cams_with_FTP %}
         {% for ids in this.state.split(', ') |list %}
         {% if not device_id(ftpid) in device_id(ids) %}
         {% set ns.entity_id= ns.entity_id + [ '%s' % (ids) ]  %}{%endif%}
         {% endfor %} {% endfor %}
         {{ ns.entity_id | list }}

I kindly ask you to check everything and if you have any suggestions on how to further streamline the code it will be welcomed.

I apologize if it may seem like I’m a novice but in fact it’s exactly like that as my decades of experience are based exclusively on server-side architecture. I recently wanted to delve into this chapter just because I think HA is an excellent alternative in the amateur management of home automation.

In this regard, I ask you to point me to an online documentation where I can learn more about the jinja code since the one suggested by HA is not exhaustive. For example, I tried to find out what the differences are between the in and contains arguments of the selectattr filter but I can’t find enough information.

I thank you in advance

As stated in my previous response, you do not need to use all those loops. The template you are using for value_template can be reduced to:

{{ states.camera | map(attribute='entity_id') | join(', ') }}

Be aware that the state of an entity (which is being set by value_template) is limited to 255 characters. If you have a lot of cameras or they have long IDs, this whole construction of listing them as a string in the state will not work reliably. That is why I specifically stated you should “Use an attribute in a template sensor…”. Attributes are not held to the same character limit.

There is no such resource that covers everything that Jinja templates can do in Home Assistant. The source you linked covers Jinja’s core functions. The Home Assistant Templating docs are the the most comprehensive and up-to-date source for HA-specific functions.

Keep in mind that, since Jinja is built on Python, there are also some Python methods that can be called. I am not aware of any resource that comprehensively documents which methods are available and which are not.

1 Like

I agree about the waste of resources in using the “for loop” especially if it is done by a sensor which, from what I understand, by default sensors automatically update every 30 seconds so the loop would repeat. However I can’t find another method to get info from the “device_ids” attribute and those for FTP. Can you suggest me a valid alternative?