Add (bring back) friendly_name to template sensors

with the new template: integration we can no longer configure friendly_names for sensors and binary sensors. The new name: variable is used to create identical object_id and friendly_name.

see: Template - Home Assistant

However, many object id’s will be not suitable for usage in the frontend, (way too long, or too technical) forcing a whole new set of customizations on friendly name (consider adding pre_/_suffix’ s to object id’s to easily and automatically sort them, indicate integrations that made them, or any other reason one might have to have another friendly_name than object id)

example in current/legacy format which I use in a card that only shows my outside temp sensors, based on core Hue integration made entity_id’s, and already using sensor_temperature in the object_id:

      backdoor_buiten_sensor_calibrated_temperature:
        friendly_name: Backdoor buiten
        value_template: >
          {{(states('sensor.backdoor_buiten_sensor_temperature')|float +
             states('input_number.temp_calibration')|float)|round(2)}}

please consider adding the configuration variable friendly_name: to the integration template:

I too usually use different names in the backend compared to the frontend. I try to stick to the English language when programming and therefore give the sensors a English object_id, whilst giving it a German friendly_name, to have the Objects pop up in a native language on Lovelace.

4 Likes

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' }}"

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.
4 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.

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.

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