Smart phone charging using Home Assistant
After finally getting Tasmota flashed onto a smart plug I was able to get started on one of the smart home projects I'd been pondering for a while... a smart phone charger that could stop the phone charging when it reached a certain battery charge level.
My motivation was this... I had been the owner of a Google Pixel phone which I purchased in 2017. After 2 years of use I was becoming increasingly disappointed with the battery life of the device, which prompted me to install the AccuBattery app to attempt to quantify how poor the remaining battery capacity was. I was alarmed to find that the battery capacity was less than 50% of the original capacity (and has now dropped to less than 40% at the time of writing)
So after I got a new Android phone in around May 2019, I started reading about how I could improve this. The AccuBattery documentation has some very useful articles describing how lithium ion (Li-ion) batteries degrade under different charging scenarios. I also read this paper. The upshot is that time at high voltage seems to be detrimental to battery longevity, and that it is therefore potentially advantageous to stop charging your phone before it reaches higher charge levels and higher voltages.
AccuBattery has a useful feature that notifies you when your phone reaches a certain charge. This is fine if you are close to the phone, and are awake, but is not very useful for overnight or unattended charging.
So, I figured that with the combination of Home Assistant and a smart plug running Tasmota, I should be able to set up a system which could stop charging after the phone battery reached a certain state.
I had already configured a Sonoff smart plug running Tasmota to talk to Home Assistant via MQTT, meaning I could turn the power on and off when charging my phone.
However, one of the missing pieces of the puzzle was giving Home Assistant knowledge of the battery state of my phone. A bit of googling turned up a thread on the Home Assistant forum suggesting this could be done using the Google Maps based device tracker in Home Assistant.
I set up using a Google account specifically for this purpose, and had members of my household share their location with this account using Google Maps. It was then necessary to obtain a cookie for this account using the method described in the the documentation, and store it in the Home Assistant configuration directory. Then I added the following to my configuration.yaml file.
Upon restarting Home Assistant, a new file was created named known_devices.yaml. This file contained an entry, representing a device_tracker entity, for each user that had shared their location with the account I had created. An example is shown below
I then created two sensors for each user; one to record the battery level, and the second to record the charging state. The entries in my configuration.yaml file took the following form.
After checking the configuration and restarting Home Assistant, I was able to see the locations of the users in the map view of Home assistant, and also their battery status by looking at the various sensors... perfect!
The next step was to build an automation in Home Assistant that would automatically turn off the smart plug when the battery reached a certain level of charge. I also wanted to include some functionality that would enable Home Assistant to be aware of which phone was charging, so that it could deal with multiple users.
After a number of iterations, I arrived at the following automation.
The trigger value (77%) is slightly below the target value for the battery charge level (80%), to avoid overshooting as Google Maps can sometimes take a few minutes to update, particularly when the phone is otherwise idle.
The automation has conditions to check that:
When the trigger fires, and the conditions are met, the automation action turns off the smart plug, and gets a Google Home device to announce the phone is charged.
I've set up some Lovelace entities to track the battery state of the phones over time.
Update (Feb 2020): After using this method to control my battery charging for around 8 months, AccuBattery is reporting my battery health state (estimated capacity divided by design capacity) is around 98%.
I'm not sure if this is accurate as I find that when I do complete a longer charge cycle, the implied estimated capacity is a bit lower, as you can see in the image below. But regardless, even if I take the worst case data point in that plot, the battery health is still likely to be somewhere around 94%, which at this stage still seems to imply a degradation rate that is materially better than I had experienced with my previous phone.
My motivation was this... I had been the owner of a Google Pixel phone which I purchased in 2017. After 2 years of use I was becoming increasingly disappointed with the battery life of the device, which prompted me to install the AccuBattery app to attempt to quantify how poor the remaining battery capacity was. I was alarmed to find that the battery capacity was less than 50% of the original capacity (and has now dropped to less than 40% at the time of writing)
So after I got a new Android phone in around May 2019, I started reading about how I could improve this. The AccuBattery documentation has some very useful articles describing how lithium ion (Li-ion) batteries degrade under different charging scenarios. I also read this paper. The upshot is that time at high voltage seems to be detrimental to battery longevity, and that it is therefore potentially advantageous to stop charging your phone before it reaches higher charge levels and higher voltages.
AccuBattery has a useful feature that notifies you when your phone reaches a certain charge. This is fine if you are close to the phone, and are awake, but is not very useful for overnight or unattended charging.
So, I figured that with the combination of Home Assistant and a smart plug running Tasmota, I should be able to set up a system which could stop charging after the phone battery reached a certain state.
I had already configured a Sonoff smart plug running Tasmota to talk to Home Assistant via MQTT, meaning I could turn the power on and off when charging my phone.
However, one of the missing pieces of the puzzle was giving Home Assistant knowledge of the battery state of my phone. A bit of googling turned up a thread on the Home Assistant forum suggesting this could be done using the Google Maps based device tracker in Home Assistant.
I set up using a Google account specifically for this purpose, and had members of my household share their location with this account using Google Maps. It was then necessary to obtain a cookie for this account using the method described in the the documentation, and store it in the Home Assistant configuration directory. Then I added the following to my configuration.yaml file.
device_tracker:
- platform: google_maps
username: username@gmail.com
Upon restarting Home Assistant, a new file was created named known_devices.yaml. This file contained an entry, representing a device_tracker entity, for each user that had shared their location with the account I had created. An example is shown below
google_maps_XXXXXXXXXXXXXXXXXXXXX:
hide_if_away: false
icon:
mac:
name: 'User1 Phone'
picture: https://lh3.googleusercontent.com/a-/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
track: true
I then created two sensors for each user; one to record the battery level, and the second to record the charging state. The entries in my configuration.yaml file took the following form.
sensor:
- platform: template
sensors:
phone_battery_level_user1:
friendly_name: 'Phone Battery Level User1'
value_template: '{{states.device_tracker.google_maps_XXXXXXXXXXXXXXXXXXXXX.attributes.battery_level}}'
unit_of_measurement: '%'
- platform: template
sensors:
phone_battery_charging_user1:
friendly_name: 'Phone Battery Charging User1'
value_template: '{{states.device_tracker.google_maps_XXXXXXXXXXXXXXXXXXXXX.attributes.battery_charging}}'
After checking the configuration and restarting Home Assistant, I was able to see the locations of the users in the map view of Home assistant, and also their battery status by looking at the various sensors... perfect!
The next step was to build an automation in Home Assistant that would automatically turn off the smart plug when the battery reached a certain level of charge. I also wanted to include some functionality that would enable Home Assistant to be aware of which phone was charging, so that it could deal with multiple users.
After a number of iterations, I arrived at the following automation.
automation:
- id: smart_charging_user1
alias: Smart Phone Charging User1
trigger:
- platform: numeric_state
entity_id: sensor.phone_battery_level_user1
above: 77
condition:
- condition: template
value_template: '{{(as_timestamp(states.switch.switch_phone.last_changed) - as_timestamp(states.sensor.phone_battery_charging_user1.last_changed) ) | abs < 900}}'
- condition: state
entity_id: sensor.phone_battery_charging_user1
state: 'True'
- condition: state
entity_id: device_tracker.google_maps_XXXXXXXXXXXXXXXXXXXXX
state: 'home'
action:
- service: switch.turn_off
data:
entity_id: switch.switch_phone
- service: tts.google_say
data:
entity_id: media_player.hub_kitchen
message: "Phone charged"
The trigger value (77%) is slightly below the target value for the battery charge level (80%), to avoid overshooting as Google Maps can sometimes take a few minutes to update, particularly when the phone is otherwise idle.
The automation has conditions to check that:
- the time the smart plug turned on, and the time the phone started charging are within 15 minutes of each other; this buffer is needed due to the time Google Maps sometimes requires to update
- the phone is actually charging
- the phone is at home.
When the trigger fires, and the conditions are met, the automation action turns off the smart plug, and gets a Google Home device to announce the phone is charged.
I've set up some Lovelace entities to track the battery state of the phones over time.
Update (Feb 2020): After using this method to control my battery charging for around 8 months, AccuBattery is reporting my battery health state (estimated capacity divided by design capacity) is around 98%.
I'm not sure if this is accurate as I find that when I do complete a longer charge cycle, the implied estimated capacity is a bit lower, as you can see in the image below. But regardless, even if I take the worst case data point in that plot, the battery health is still likely to be somewhere around 94%, which at this stage still seems to imply a degradation rate that is materially better than I had experienced with my previous phone.
Ultimately time will tell whether this has been useful or not, but so far the results seem promising.
Great stuff! I never knew that Google Maps reports your battery soc. Thorough article, well researched and presented.
ReplyDeleteThanks Martin. Glad you learnt something from it!
DeleteCool feature one thing could be very interesting to add: Proximity - What if an iBeacon, Eddystone or NFC could be used to tell Home Assistant that my phone is now placed on my bedroom table and it is ready to charge when the battery is below 80% and it is not charging. With the new HA companion app we have all information regarding charging state and battery level we only need to know that the phone is "plugged" and ready to charge (from our Tasmota plug) next to the bed.
ReplyDeleteIt's not easy to know when the phone is plugged in but not charging. You could potentially use NFC to do that (i.e., always put the phone on the NFC tag when you plug it in).
Delete