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.
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.
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 variablethis 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.
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.
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?
In any case, I implemented this solution to better manage the information on the cameras. I hope it can be of use to someone. I thank all the participants in this discussion.
in the configuration.yaml file I called up a folder that contains my templates for the sensors like this
sensor: !include_dir_merge_list sensors
subsequently I created a cams.yaml file where I implemented the sensor described in this discussion:
- platform: template
sensors:
all_cams_sensor:
friendly_name: All cams sensor
value_template: >
{{ states.camera | map(attribute='entity_id') | list | count }}
attribute_templates:
cams_list: >
{{ states.camera | map(attribute='entity_id') |sort(attribute='entity_id') | list | join(', ') |default('') }}
device_ids: >
{% set ns = namespace(device_id=[]) %}
{% for s in this.attributes.cams_list.split(', ') |is_defined |list %}
{% set ns.device_id = ns.device_id + [ '%s' % device_id(s) ] %}
{% endfor %}
{{ ns.device_id }}
online_cams: >
{{ this.attributes.cams_list.split(', ') |is_defined| select('is_state', 'idle') |list }}
offline_cams: >
{{ this.attributes.cams_list.split(', ')|is_defined | select('is_state', '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.attributes.cams_list.split(', ') |is_defined |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 }}