Help with regex, templates and values

Hi everyone.

I am trying to use templates to create a “friendly name” for the list of bluetooth devices an Android device is connected to. Using sensor.my_device_bluetooth_connection 's attribute connected_paired_devices I get a value returned like this:

['98:F0:7B:69:CB:BE (My Car)', '80:2C:F5:42:0D:69 (Galaxy Watch Active2(8309))']

I would ideally like to end up with

My Car
Galaxy Watch Active2(8309)

I have tried a couple of things with regex, but not sure that will work and it it is the best way to go about it. Sometimes the phone will not be connected to anything at all, sometime it will be one device and sometimes 2 devices. So I don’t know how to handle this particular situation.

Thank you in advance for any help!

Edit: I have read this post: Automation Attribute Template but I think our use cases differ a bit. I just want to get the current list of connected devices, not check whether something is indeed connected.

Copy-paste the following template into the Template Editor and confirm it reports what you want.

{% set x = ['98:F0:7B:69:CB:BE (My Car)', '80:2C:F5:42:0D:69 (Galaxy Watch Active2(8309))'] %}

{% set ns = namespace(names=[]) %}
{% for n in x %}
  {% set ns.names = ns.names + [n[19:-1]] %}
{% endfor %}
{{ ns.names | join('\n') }}

Screenshot

For your application, the template will look like this:

{% set ns = namespace(names=[]) %}
{% for n in state_attr('sensor.my_device_bluetooth_connection', 'connected_paired_devices') %}
  {% set ns.names = ns.names + [n[19:-1]] %}
{% endfor %}
{{ ns.names | join('\n') }}
1 Like

I just love this juggling, so simple to look at…so hard to learn :ok_hand:
So n[19:-1] is trying to get anything between the quotes : from position-19 to position-last minus 1 ?
Side question: will this work on any text ?

Yes it works for strings as well as for lists, and tuples.

Tutorial

1 Like

Freaking hell, this well done,thank you so much @123 . It produces exactly what I want it to produce.

May I please ask a follow-up question?

I am currently using the following piece of code to achieve a Total Power Production value.

- platform: template
    sensors:
      total_power_production:
        friendly_name: "Total Power Production"
        unit_of_measurement: "kWh"
        value_template: "{{ (states('sensor.inverter1_power_generation')|float) + (states('sensor.inverter2_power_generation')|float) }}"

So my question is, how do I use your code for the value_template? Do I literally just use all of your code?

- platform: template
    sensors:
      my_connected_bluetooth_devices:
        friendly_name: "My Connected Bluetooth Devices"
        value_template: "{{ {% set ns = namespace(names=[]) %}
                        {% for n in state_attr('sensor.my_device_bluetooth_connection', 'connected_paired_devices') %}
                        {% set ns.names = ns.names + [n[19:-1]] %}
                        {% endfor %}
                        {{ ns.names | join('\n') }} }}"

Possibly one line for the sake of yaml?
Thank you again!

- platform: template
    sensors:
      my_connected_bluetooth_devices:
        friendly_name: "My Connected Bluetooth Devices"
        value_template: >
          {% set ns = namespace(names=[]) %}
          {% for n in state_attr('sensor.my_device_bluetooth_connection', 'connected_paired_devices') %}
          {% set ns.names = ns.names + [n[19:-1]] %}
          {% endfor %}
          {{ ns.names | join(', ') }}

I changed join('\n') to join(', ') because, to my knowledge, Home Assistant doesn’t support the use of newlines in an entity’s state value. Feel free to try it with \n just in case I’m wrong about it.


NOTE

When creating a new Template Sensor, you should consider using the ‘modern’ format for configuring it. You’ve chosen to configure this Template Sensor using what is now known as ‘legacy’ format. It hasn’t been deprecated but it will not receive any new features in the future (whereas modern format will and already supports features unavailable in legacy format).

image

Thank you so much!!!

This worked.

I read your note, and I have been over that documentation like 100 times, but obviously I am too stupid to convert these templates. If you are willing to help me with this one, I will try and keep up and convert all my other ones as well. I am willing to learn, I just don’t understand the difference really. Sorry for being so stupid.

The first important thing to know is that Template Sensors in modern format are not placed in the sensors.yaml file. Traditionally, all sensor entities are located under the sensor: key but not Template Sensors in modern format. They go under a new key named template: and so if you don’t put them there, you’ll get errors.

Using a text editor, open the configuration.yaml file and search for this line:

template: !include templates.yaml

If it exists, it means all Template Sensors (and other Template entities) are located in a separate file named templates.yaml.

Use your text editor to open the templates.yaml file and enter the following configuration:

  - sensor:
      - name: "My Connected Bluetooth Devices"
        state: >
          {% set ns = namespace(names=[]) %}
          {% for n in state_attr('sensor.my_device_bluetooth_connection', 'connected_paired_devices') %}
          {% set ns.names = ns.names + [n[19:-1]] %}
          {% endfor %}
          {{ ns.names | join(', ') }}

If your configuration.yaml doesn’t have

template: !include templates.yaml

or even just a solitary

template:

then let me know and I’ll help you sort it out.

I have used your example, and converted my other templates now too. I did not have that entry in configuration.yaml, but I added it. I copied the example from the scenes: !scenes.yaml line.
It seems my templates are working. I am posting my one example here for anyone who may come across this thread:

Old code: (in configuration.yaml)


  - platform: template
    sensors:
      total_power_consumption:
        friendly_name: "Total Power Consumption"
        unit_of_measurement: "kWh"
        value_template: "{{ (states('sensor.my_inverter1_consumption_in_watts')|float) + (states('sensor.inverter2_consumption_in_watts') | float) }}"


  - platform: template
    sensors:
      total_power_production:
        friendly_name: "Total Power Production"
        unit_of_measurement: "kWh"
        value_template: "{{ (states('sensor.inverter1_power_generation')|float) + (states('sensor.inverter2_power_generation')|float) }}"

New code: (in templates.yaml)

- sensor:
    - name: "Total Power Consumption"
      unit_of_measurement: kWh
      state: "{{ (states('sensor.my_inverter1_consumption_in_watts')|float) + (states('sensor.inverter2_consumption_in_watts') | float) }}"

    - name: "Total Power Production"
      unit_of_measurement: kWh
      state: "{{ (states('sensor.inverter1_power_generation')|float) + (states('sensor.inverter2_power_generation')|float) }}"

Note: What had saved me from having to redo all my ‘Helpers’ is by making sure my old sensor name and the new sensor name were identical. For example:

in the old code total_power_production sensor was sensor.total_power_production. By using “Total Power Production” as the name in the new template, the sensor stayed sensor.total_power_production. So for n00bs like me, just take note of that.

Legacy format makes it easy to assign an object_id to a Template Sensor that’s different from its friendly_name. For example, the following legacy configuration produces sensor.total_power (where the object_id is “total_power”) with a ‘Total Power Consumption’ as its friendly_name.

- platform: template
    sensors:
      total_power:
        friendly_name: Total Power Consumption
        unit_of_measurement: kWh
        value_template: "{{ states('sensor.s1')|float(0) + states('sensor.s2') | float(0) }}"

Modern format doesn’t allow you to do that; it’s a two-step process. You would configure it like shown below which produces sensor.total_power_consumption (an entity with total_power_consumption as its object_id therefore it’s now a different entity from sensor.total_power) and then, in the UI, you change the sensor’s entity_id to sensor.total_power.

  - sensor:
      - name: Total Power Consumption
        unit_of_measurement: kWh
        state: "{{ states('sensor.s1')|float(0) + states('sensor.s2') | float(0) }}"

All this to say that if you have legacy Template Sensors whose object_id and friendly_name are significantly different, it can present a challenge to cleanly convert them to modern format. By “cleanly” I mean without losing the history of the legacy Template Sensor which will happen if the modern format Template Sensor you create doesn’t have exactly the same entity_id as the legacy version.

In my case, most of my legacy Template Sensors had an object_id significantly different from their friendly_name. Therefore I potentially faced losing sensor history during the conversion process. Fortunately, someone figured out the exact sequence of steps needed to ensure clean conversion (and it worked for me).

This is a beautiful and thorough explanation. Thank you for the time. Newcomers to HA will hopefully find this post and this explanation, and most certainly be thankful for it. I know I am.

1 Like