Device tracker attributes, and cleaner code

Hi All,
I’m using Google Location Sharing, and I’m working on building a trigger that will message my users to tell them to plug their phones in when they get to a certain battery level. I’ve successfully captured the data with a sensor. However, I wanted to see if there may be a way to do this a little more “cleanly”, if you will. Here’s my current code:

- platform: template
    sensors:
      user_1_battery:
        friendly_name: "User_1's Battery level"
        value_template: "{{ states.device_tracker.google_maps_######.attributes.battery_level }}"

now, the problem I run into is, I have 6 users. in order to do this, the most straightforward way is to build a sensor for each, for each of the attributes that I need to check. This can get crazy, quick.

Is there anyway that I can provide a list of the device trackers ID’s, and then apply that to the code with a variable in the code, sort of like doing a function? Sort of like this:

list_of_names:
google_maps_#####1
google_maps_#####2
google_maps_#####3  

- platform: template
    sensors:
      user_battery:
        friendly_name:  %user% " Battery level"
        value_template: "{{ states.device_tracker.%user%.attributes.battery_level }}"

I know this is clear as mud, but does anyone see where I"m going with this idea? Is this even possible on this platform?

Thanks!

I think I get it. You want to create multiple sensor entities (one per user) that are all based on the same ‘skeleton’ of a template_sensor. Effectively, you want to do ‘code re-use’. All six sensors are identical except for the user’s name so why not define the skeleton of a sensor once and then just pass it the name of the user?

As far as I know, you can’t do that.

There’s a way in YAML to create a shareable block that can be included elsewhere (many times). See YAML Anchors, References, Extend. However, as far as I can see, it’s not applicable in this case. There’s just not enough in that template_sensor to merit its use.

There’s a frighteningly long thread (that I’ve promised myself to read … but never have) that might be applicable to you:

Precisely what I mean; from a general coding/math idea it would be creation of a function (I’m a little embarrassed at how long it took me to remember the right word for it :slight_smile: )

The long thread you mentioned looks like it may be a pretty strong candidate for a fix, but ideally when it’s done I’d like this to fire off a message to the individual users, rather than just me. Still it gives me an example of what can be done with this code, to tear apart and tinker with. Thanks!!

Anybody else have any input?

FWIW, you can pass variables to python scripts but I’m not sure that’s of any help for your use-case.

Minimally, you need an automation that’s triggered when any one of the six phone batteries drops below a threshold. Then it reports which phone battery is below the threshold.

I’ll take a look; my wife is learning some Python right now, she may be able to offer insight when looking at it as well. Thanks again!!

You could try something like this:

- alias: Low batter warning
  trigger:
    - platform: numeric_state
      entity_id:
        - device_tracker.google_maps_#####1
        - device_tracker.google_maps_#####2
        - device_tracker.google_maps_#####3
        - device_tracker.google_maps_#####4
        - device_tracker.google_maps_#####5
        - device_tracker.google_maps_#####6
      value_template: "{{ state.attributes.battery_level }}"
      below: 20
  action:
    - service: notify.blah
      data_template:
        message: >
          {{ trigger.to_state.name }}'s battery is low!
1 Like

Exactly what I had in mind: “automation that’s triggered when any one of the six phone batteries drops below a threshold.” :+1:

1 Like

oh that’s pretty… i have a/an inelegant solution in place, but I may be able to take this structure and modify it. Here’s what I did (x6)

 - platform: template
sensors:
  dylan_battery:
    unit_of_measurement: '%'
    friendly_name: "Kid2's Battery level"
    value_template: "{{ states.device_tracker.google_maps_########.attributes.battery_level }}"
    icon_template: >-
      {% set battery_level = state_attr("device_tracker.google_maps_#######","battery_level")|int('unknown') %}
      {% set battery_round = (battery_level|int / 10)|int * 10 %}
      {% set charge_status = state_attr("device_tracker.google_maps_######","battery_charging") %}
      {% if battery_level == 'unknown' %}
        mdi:battery-unknown
      {% else %}
        {% if charge_status == True %}
          {% if battery_round > 0 %}
            mdi:battery-charging-{{ battery_round }}
          {% else %}
            mdi:battery-charging-outline
          {% endif %}
        {% else %}
          {% if battery_round >= 100 %}
            mdi:battery
          {% elif battery_round > 0 %}
             mdi:battery-{{ battery_round}}
          {% else %}
            mdi:battery-alert
          {% endif %}
        {% endif %}
      {% endif %}

The end result is the battery percentage to the right, with an icon that changes based on whether or not it’s plugged in and what percentage of charge it has.

Hi, I used this

- alias: low battery alerts
  trigger:
    - platform: numeric_state
      entity_id:
        - binary_sensor.openclose_9
        - binary_sensor.openclose_9_2
        - binary_sensor.door
        - binary_sensor.motion_sensor
        - binary_sensor.presence_7
        - binary_sensor.door_bunker
      value_template: '{{ state.attributes.battery_level }}'
      below: '99'

but got

Error rendering data template: UndefinedError: ‘state’ is undefined

any suggestion?
Thanks

What is the rest of your automation? I.e., the condition and action parts. I suspect the error is coming from there (notice it says “data template”), since that trigger should be good.

Hello, here we are:

- alias: low battery alerts
  trigger:
    - platform: numeric_state
      entity_id:
        - binary_sensor.openclose_9
        - binary_sensor.openclose_9_2
        - binary_sensor.door
        - binary_sensor.motion_sensor
        - binary_sensor.presence_7
        - binary_sensor.door_bunker
      value_template: '{{ state.attributes.battery_level }}'
      below: '99'
    #- platform: state
  #    entity_id: switch.lightone
  #    from: 'off'
  #    to: 'on'
  action:
    - service: tts.google_say
      entity_id:
        - media_player.bunker
        - media_player.googlehome9940
      data_template:
        message: "{{ trigger.to_state.attributes.friendly_name }} battery is too low"
    - service: notify.email_one
      data_template:
        title: ' {{ trigger.to_state.attributes.friendly_name }} battery is low!'
        message: 'Hi,  {{ trigger.to_state.attributes.friendly_name }} is at  {{ state.attributes.battery_level }} .'

I added the second trigger to test that action but I just receive the google message. The notify service is working (tested in another automation)
Thanks a lot

try:

message: >
  Hi,  {{ trigger.to_state.attributes.friendly_name }} is at  {{ trigger.to_state.attributes.battery_level }} .

I think the problem is in the last line:

        message: 'Hi,  {{ trigger.to_state.attributes.friendly_name }} is at  {{ state.attributes.battery_level }} .'

It should be:

        message: 'Hi,  {{ trigger.to_state.attributes.friendly_name }} is at  {{ trigger.to_state.attributes.battery_level }} .'

Thanks a lot, this is working. The email is sent but there is no value:

I receive:

Hi, Openclose_9 is at .

If I try to put

{{ trigger.to_state.attributes.battery_level }}

in the google_say data message it doesn’t work at all (no email and no vocal message at all).

Any suggestion?

That’s because when you put the message into google_say disconnected from the automation it’s originally connected to there is no “trigger.to_state”…

what that bit of code does is it creates a placeholder in the template that looks for the entity that caused the automation to trigger along with the new state of the entity which then allows the template to access the associated attributes of the triggering entity.

try putting the following into the tts and see what the result is (using the entity_id of the example friendly name you used last above):

{{ states.binary_sensor.openclose_9.attributes.battery_level }}