Battery state for Android

For iOS devices, it is possible to get both the battery level (percentage) and the battery state (Full, Unplugged, Charging, etc.) from the automatically created sensors sensor.device_name_battery_level and sensor.device_name_battery_state.
For Android I am using OwnTracks for device tracking, and this does send the battery level so I have been able to replicate the battery level sensor by creating a template sensor. However, this doesn’t send the battery state. Is there anything for Android which will send the battery state in addition to the level?
I was considering creating an automation which would be triggered when the battery is low on a device and it would be useful to be able to see if the device is on charge but, without this, it would only work for iOS devices.

I’m looking for this as well. It looks like OwnTracks doesn’t support it. It might be useful to open that as an issue on their GitHub as a feature request. https://github.com/owntracks/android/issues

I ended up using template sensors and a couple of trend binary sensors configured like this:

sensor:
  - platform: template
    sensors:
      phone_battery_level:
        friendly_name: Phone Battery Level
        unit_of_measurement: '%'
        value_template: '{{ state_attr("device_tracker.phone","battery") }}'
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% if battery_level == 'unknown' %}
            mdi:battery-unknown
          {% else %}
            {% if battery_round >= 100 %}
              mdi:battery
            {% elif battery_round > 0 %}
              mdi:battery-{{ battery_round }}
            {% else %}
              mdi:battery-alert
            {% endif %}
          {% endif %}
      phone_battery_state:
        friendly_name: Phone Battery State
        value_template: >-
          {% set battery_level = state_attr("device_tracker.phone","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone_battery_increase","on") %}
          {% if charging %}
            Charging
          {% else %}
            {% if battery_round >= 100 %}
              Full
            {% elif battery_round > 0 %}
              Unplugged
            {% else %}
              Low
            {% endif %}
          {% endif %}
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone_battery_increase","on") %}
          {% if charging %}
            mdi:power-plug
          {% else %}
            mdi:power-plug-off
          {% endif %}

binary_sensor:
  - platform: trend
    sensors:
      phone_battery_increase:
        entity_id: sensor.phone_battery_level
      phone_battery_decrease:
        entity_id: sensor.phone_battery_level
        invert: true

Edit: I’ve updated this with the full configuration of my sensors.

5 Likes

Hey Steven, that works perfect but can I ask - how would I change this for a sensor not a device_tracker?

Only reason I ask as I use a different app that reports battery state but lovelace doesn’t support getting attributes from states yet so I need something like this.

My Sensor reports this info:

Entity:
sensor.r3m0dul8_battery_sensor

State:
43 (<— Battery Level at the time)

Attributes:
health: good
status: discharging
voltage: 3801 mV
technology: Li-ion
icon: mdi:battery-50
power: Unplugged
temperature: 27.4
unit_of_measurement: %
friendly_name: r3m0dul8 Battery Sensor

What I would like is to pull that info like you have but from this sensor instead using the app ‘Ariela’ but I’m unsure how exactly to do this.

Any help would be appreciated - been a few months since this post was made so hoping you can help in this area.

It should be a bit simpler for yours, as the attributes of the sensor already have everything you need. Something like this should work:

sensor:
  - platform: template
    sensors:
      r3m0dul8_battery_state:
        friendly_name: r3m0dul8 Battery State
        value_template: >-
          {{ states.sensor.r3m0dul8_battery_sensor.attributes["power"] }}
        icon_template: >-
          {{ states.sensor.r3m0dul8_battery_sensor.attributes["icon"] }}

Then the existing sensor.r3m0dul8_battery_sensor should give you the battery percentage and sensor.r3m0dul8_battery_state will give you the state.
I’m not familiar with that particular sensor, so you may need to replace states.sensor.r3m0dul8_battery_sensor.attributes["power"] with states.sensor.r3m0dul8_battery_sensor.attributes["status"]

2 Likes

No, you were right - “power” was fine, status just show what state the battery is in discharge etc. I assume that a straight copy/paste overwrite of the former code would be your intention of that above? I did it anyway, and commented out my old code incase I fallback to that previous jinja code you did. Excellent working example and perfect for my case-use and my Lovelace is getting more and more prettier by the hour!

Works perfect by the way - my only request would be the icon for the representation of the current charging state so;

When charging it would show mdi:power-plug and when ‘unplugged’ shows mdi:power-plug-off

I’m still trying to come to grips with the template side of things - but it I’m finding it a powerful too when you want your own look I suppose.

Thanks a ton for all your help - gotta love this community! Hopefully I’ll get my Jinja skills up and get more understanding of this language implementation in my yaml.

Thank you for this! This gave me the direction I needed to go to figure out how to do this.

I’m using Google Location Services. It does give a charging status as a true/false. I took your base code, and added a nested loop to check for the the “true” statement for charging, then put the percentage icon for the battery with the charger next to it.

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 %}

Thanks again!!

This is working great for me. But, and there is always a but I need to add another phone.
It recognizes one phone but not the other.
Basically I duplicated the config, but I must be missing something.
Any ideas on how to distinguish the config for two devices.
Thanks

Are you using template sensors and trend binary sensors like I used in my config? If so, you would need to make sure that you have all of these duplicated per phone. For example, if the two phones have entity ids of device_tracker.phone1 and device_tracker.phone2, you would need to have a configuration like this (I’ve cut out some of the repeated parts for brevity):

sensor:
  - platform: template
    sensors:
      phone1_battery_level:
        friendly_name: Phone 1 Battery Level
        unit_of_measurement: '%'
        value_template: '{{ state_attr("device_tracker.phone1","battery") }}'
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone1","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% if battery_level == 'unknown' %}
            mdi:battery-unknown
          {% else %}
            {% if battery_round >= 100 %}
              mdi:battery
            {% elif battery_round > 0 %}
              mdi:battery-{{ battery_round }}
            {% else %}
              mdi:battery-alert
            {% endif %}
          {% endif %}
      phone1_battery_state:
        friendly_name: Phone 1 Battery State
        value_template: >-
          {% set battery_level = state_attr("device_tracker.phone1","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone1_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone1_battery_increase","on") %}
          {% if charging %}
            Charging
          {% else %}
            {% if battery_round >= 100 %}
              Full
            {% elif battery_round > 0 %}
              Unplugged
            {% else %}
              Low
            {% endif %}
          {% endif %}
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone1","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone1_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone1_battery_increase","on") %}
          {% if charging %}
            mdi:power-plug
          {% else %}
            mdi:power-plug-off
          {% endif %}
     phone2_battery_level:
        friendly_name: Phone 2 Battery Level
        unit_of_measurement: '%'
        value_template: '{{ state_attr("device_tracker.phone2","battery") }}'
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone2","battery")|int('unknown') %}
          ... rest is the same as phone1 ...
     phone2_battery_state:
        friendly_name: Phone 2 Battery State
        value_template: >-
          {% set battery_level = state_attr("device_tracker.phone2","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone2_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone2_battery_increase","on") %}
          ... rest is the same as phone1 ...
        icon_template: >-
          {% set battery_level = state_attr("device_tracker.phone2","battery")|int('unknown') %}
          {% set battery_round = (battery_level|int / 10)|int * 10 %}
          {% set charging = is_state("binary_sensor.phone2_battery_increase","on") %}
          {% set discharging = is_state("binary_sensor.phone2_battery_increase","on") %}
          ... rest is the same as phone1 ...
    
binary_sensor:
      - platform: trend
        sensors:
          phone1_battery_increase:
            entity_id: sensor.phone1_battery_level
          phone1_battery_decrease:
            entity_id: sensor.phone1_battery_level
            invert: true
          phone2_battery_increase:
            entity_id: sensor.phone2_battery_level
          phone2_battery_decrease:
            entity_id: sensor.phone2_battery_level
            invert: true
1 Like

Thank you so much. Pardon my late reply. Had to make an an emergency business out of the country.

I was pretty close to what you posted. I pasted in your information, and for the life of me could not get it to work for the second phone. I then saw the comment of … rest is the same as phone1…
Took this old guy an hour to figure it out, but once I did it works great.

Again thank you and the community of people who post for making this fairly easy.
Carltonb

Hi @Steven_Rollason,

{% set charging = is_state("binary_sensor.phone1_battery_increase","on") %}
{% set discharging = is_state("binary_sensor.phone1_battery_increase","on") %}

I assume there must be a typo here? If discharging, should it not point at decrease binary_sensor?

I have tasker with an mqtt plugin send the battery percentage every time it changes to an mqtt topic where Home Assistant picks it up.

Yes, that’s a typo. I just noticed it myself (I have the same typo in my setup). It doesn’t really make any difference, as the value of the discharging variable isn’t actually being used anywhere else (it only checks whether it is charging or not).

1 Like