Add (bring back) friendly_name to template sensors

Unless I am mistaken, I believe you are using the object_id to store meta-data that you use later, perhaps to use for selection or organization.

Would it help if you could define custom attributes directly within the Template Sensor’s configuration (instead of in customize.yaml)?

For example, in ‘modern’ format:

  - name: Backdoor buiten
    state: >
       {{(states('sensor.backdoor_buiten_sensor_temperature')|float +
          states('input_number.temp_calibration')|float)|round(2)}}
    custom_attributes:
      - name: entity_type
        value: sensor
      - name: calibrated
        value: true
      - name: category
        value: temperature
      - name: location
        value: outdoors

Afterwards, you can use a template to easily select entities based on their custom_attributes.

However, if you are adding meta-data to the object_id to cause the entities to appear in a desired order within Developer Tools > States, then custom attributes won’t be useful for that.

This is already solved with the new integration. Use unique_id, do not use name. Then in the attributes section, add a friendly_name template.

- sensor:
  - unique_id: light_count
    state: "{{ states.light | list | count }}"
    attributes:
      friendly_name: "{{ states.light | list | count }} lights are on"
  binary_sensor:
  - unique_id: lights_on
    state: "{{ states.light | list | count > 0 }}"
    attributes:
      friendly_name: "Lights are {{ 'on' if states.light | list | count > 0 else 'off' }}"
9 Likes

Thanks! I can’t believe I overlooked the existing ability to define custom attributes in the sensor’s configuration. I even have existing examples of it in my own system! :man_facepalming:

Unfortunately, what failed to work in my tests was overriding friendly_name. For example, this Template Sensor on my test system:

  - name: All Lights On
    state: "{{ states.light | selectattr('state', 'eq', 'on' | list | count }}"
    attributes:
      entities: "{{ states.light | selectattr('state', 'eq', 'on') | map(attribute='name') | list | join(', ') }}"
      friendly_name: "{{'Thingamajig'}}"
      type: "{{'Widget'}}"
      location: "{{'Rock and a hard place'}}"

Rendered this:

Screenshot from 2021-05-08 12-42-36

Its friendly_name should be “Thingamajig” but it’s still based on name. I don’t know if that’s by design or a bug.

it needs something to update it, it’s working for my ‘county’ coronavirus entity, which is based on rest

I turned on a light, which served to update the sensor’s state and its (custom) entities attribute but not friendly_name. It’s still called “All Lights on”.

Screenshot from 2021-05-08 12-52-18

this is mine:

  - unique_id: corona_virus_county
    state: >
      {%- set features = state_attr('sensor.corona_virus_county_rest', 'features') %}
      {%- set items = features | map(attribute='attributes') | list %}
      {%- if items | length > 0 %}
        {%- set item = items | first %}
        {%- set last_updated = item.Last_Update | int / 1000 %}
        {{ last_updated | timestamp_custom('%Y-%m-%dT%H:%M:%S.%f+00:00', False) }}
      {%- else %}
        {{ states('sensor.corona_virus_county_rest') }}
      {%- endif %}
    availability: >
      {%- set features = state_attr('sensor.corona_virus_county_rest', 'features') %}
      {%- set features = features | map(attribute='attributes') | list %}
      {{ features | length > 0 }}
    attributes:
      template: corona_virus
      friendly_name: >
        {%- set features = state_attr('sensor.corona_virus_county_rest', 'features') %}
        {%- set items = features | map(attribute='attributes') | list %}
        {%- if items | length > 0 %}
          {%- set item = items | first %}
          Corona Virus {{ item.Admin2 }}
        {%- else %}
          Corona Virus {{ state_attr('sensor.corona_virus_county_rest', 'county') }}
        {%- endif %}

I never assigned it a name though.

Ahah! That’s it!

I removed name, added unique_id: all_lights_on and here’s the result:

It created a sensor whose object_id combines the word “template” with the value of its unique_id. Now its friendly_name is “Thingamajig”.

Interesting, I thought name is required but the documentation clearly shows it’s optional.

2 Likes

Nice, so then it works.

  1. Use unique_id.
  2. Don’t use name.
  3. Add a friendly_name attributes template.
  4. Profit.
9 Likes

Just for laughs, I also tried eliminating both name and unique_id. It passed Check Configuration and produced this:

Screenshot from 2021-05-08 13-06-59

Not a recommended way of creating (nameless) sensors but it (surprisingly) works.

TBH, I bet this works on other template integrations too. The existence of the friendly name attribute is what causes the problems. Without name, friendly_name doesn’t exist and it defaults to <states_obj>.name when shown in the UI.

As long as the value assigned to unique_id is meaningful, the user retains control over the sensor’s object_id (but with “template_” prepended to it) as well as its friendly_name. Good enough for me.

I just add a template attribute to all my templates instead of adding it to the object_id.

- sensor:
  - unique_id: something_xyz
    ...
    attributes:
      template: <description of wtf it does>

Adding the unique_id gives you the control the name in the UI too. If name doesn’t exist, it’ll use the unique_id as the object_id. If name and unique_id exist, it’ll take the name and chop it into a object_id. If name exists and unique_id doesn’t, you won’t be able to edit it in the UI and it’ll chop the name into the object_id. And you’ve already seen what it does without a name and a unique_id.

1 Like

you’ve been at it while Ive been away :wink: thanks!

and no, I haven’t tried that yet, though I did try to understand the code, and especially this on friendly_names.

Thats why I was confused friendly_name not to be mentioned in the documentation. Given the fact it is such a system wide default configuration variable, it does feel awkward we should now configure it under the manually added attributes (templates), and not have it as a default option perse. (hence my FR…)

Please let me ask if I overlooked another possible feature, namely the much anticipated template variables? It would be so great if we could set a variable, to be used in all following templates of the same sensor. Or maybe even better, use the state of the main state in all other templates, as a config entity.

It would shorten Add (bring back) friendly_name to template sensors - #8 by petro Petro’s template dramatically.

that would allow me to do what I have been trying for a very long time now, in the friendly_name_template: (declare once in an anchor, and insert that anchor in the other 22):

      corridor_terrace_sensor_light_level_raw:
        value_template: >
          {{state_attr('sensor.corridor_terrace_sensor_light_level','lightlevel')}}
#        friendly_name_template: >
#          Corridor terrace:
#          {% set light_level = state_attr('sensor.corridor_terrace_sensor_light_level','lightlevel')|int %}
#          {% if light_level < 1 %} dark
#          {% elif light_level < 3000 %} bright moonlight
#          {% elif light_level < 10000 %} night light
#          {% elif light_level < 17000 %} dimmed light
#          {% elif light_level < 22000 %} 'cosy' living room
#          {% elif light_level < 25500 %} 'normal' non-task light
#          {% elif light_level < 28500 %} working / reading
#          {% elif light_level < 33000 %} inside daylight
#          {% elif light_level < 40000 %} maximum to avoid glare
#          {% elif light_level < 51000 %} clear daylight
#          {% else %} direct sunlight
#          {% endif %}

Because the above needs to be repeated for all (23) sensors individually with the legacy format, I do it in a customization:

        friendly_name: >
          function capitalizeFirstLetter(string) {
              return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
              }
          var id = entity.entity_id.split('.')[1].split('_sensor_light_level_raw')[0].replace(/_/g,' ');
          var id = capitalizeFirstLetter(id);
          if (state < 1) return id + ': dark';
          if (state < 3000 ) return id + ': bright moonlight';
          if (state < 10000) return id + ': night light';
          if (state < 17000) return id + ': dimmed light';
          if (state < 22000) return id + ': \'cosy\' living room';
          if (state < 25500 ) return id + ': \'normal\' non-task light';
          if (state < 28500) return id + ': working / reading';
          if (state < 33000) return id + ': inside daylight';
          if (state < 40000) return id + ': maximum to avoid glare';
          if (state < 51000) return id + ': clear daylight';
          return id + ': direct sunlight';

which would be the anchor if the template variables would be available.

now back to your findings above which I havent studied completely yet.

Hi @petro ,

I thought doing so would prevent the auto prepending of the ‘template_’ string to the unique id when it generates the entity id, but it still appears.
How do you manage not to have this in your entity id? Do you edit it afterwards in the UI?

Just add a name and it’ll use the name to create the object id.

1 Like

Thanks for your prompt reply, but it does not really answer my questions, I am afraid. You did not use name, I think. And I wanted to have the friendly_name working as well, which does not seem possible when using name.
What is the exact purpose of your template attribute?

Then just change the entity id through the ui

So I can organize my system and know where it comes from

OK, thanks, that’s what I thought.
It would have been more convenient to be able to control all of these in the yaml configuration. Maybe in the future…

Alright, I misunderstood it. Thanks!