Controlling phone charging

Problem:
I have a new phone and I want the battery to last for as long as possible. My understanding is that charging it to 100% overnight, every night may reduce my battery capacity over time.
I played with adaptive charging, but there is no way to shut off the charging before it reaches 100%.

The plan:
Build a solution to shut off the phone charger when the battery charge reaches 85%

The approach:
Use a script running on the phone to send a message to a raspberry pi when the battery is full and use a relay connected to the pi to control the USB power to my wireless phone charger.

Details:
The solution works in two parts.

a) Write a script for the phone (using the Automate app) that detects:

  1. If I am connected to my home wifi
  2. If the phone is currently being charged
  3. If the battery level is over 85%

If all three of these conditions are met then send an http request to my raspberry pi to ask it to turn off the charger.

b) Have a tiny web server running on a raspberry pi. I had a spare pi 1B which is more than capable of running the script and is able to supply enough power to the charger as well (noting that it is a slow charger).

If the web server receives a request then breaks the relay so the phone stops charging and then sleeps for a while before looping.

This is my script for the Android Automate app:

And this is the python script that runs on the pi:

#!/usr/bin/python
# Script to stop phone charging when an http request is received
# To stop the phone charging a relay is connected to a raspberry pi GPIO pin
# John Kenyon 2024

# Libraries
import RPi.GPIO as GPIO
from time import sleep
import socket

# Define constants
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 8001
RELAY_PIN = 24
SLEEP_TIME = 5*60*60 # 5 hours

# Define a simple web server that quits after it receives a connection
def waitForConnection():
  # https://www.codementor.io/@joaojonesventura/building-a-basic-http-server-from-scratch-in-python-1cedkg0842
  # Modified to exit when a connection is made
  # Create socket
  server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  server_socket.bind((SERVER_HOST, SERVER_PORT))
  server_socket.listen(1)
  # Wait until we receive any connection (as we don’t parse anything this is pretty safe)
  client_connection, client_address = server_socket.accept()
  response = 'HTTP/1.0 200 OK\n\n'
  client_connection.sendall(response.encode())
  client_connection.close()
  # Close socket
  server_socket.close()

# Define a function to control the GPIO and switch off the charger
def switchOffChargerForTime(delay):
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(RELAY_PIN, 0)
  sleep(delay)
  GPIO.setup(RELAY_PIN,1)
  GPIO.cleanup()

while True:
  waitForConnection()
  switchOffChargerForTime(SLEEP_TIME)

I had a few issues with the relay and managed to get it to work using the code above. If you have a better behaved relay then the GPIO calls really should be to GPIO.output, but for some odd reason this works :slight_smile:

All mounted in a low tech cardboard box:

Cheers,
John

5 Likes

Cool @John74609
Lovely, clean, and pythonic script.

2 Likes

I must try this. Thank you.

2 Likes

I love this idea @John74609 :smiley: I agree, it feels like the OS doesn’t expose enough battery management options to really super-mile the lifetime of your battery.
The best my phone does is to “charging slowly” until my morning alarm. Which is great! But i remember with another model I could select the min/max charge setpoints to extend battery life. I respect that you’ve implemented this outside the phone for when that feature doesn’t exist. How good!

Also what a great intro to the Automate app. I’m going to have to check that out :smiley:

Consider submitting your project on our Projects Page when it’s complete!

3 Likes

My Lenovo Android tablet has a feature it offered me because it saw i had it plugged in all the time.

It doesn’t start charging until it gets down to 40%, and then only goes up to 60%.
I imaging this is the same thing as maintaining a storage charge (3.7v or thereabouts per cell)

Thanks for all your kind comments. I am still struggling with keeping it stable so I will update the first post as soon as I work out my bugs. The issue is that sometimes the HTTP call from the Automate app refuses to connect. I am not sure if it is a client or server issue. I also changed to use a separate power supply for the charger just to isolate any power related issues on the pi.
-John

1 Like

Amazing work John!

I solved my stability issue. The cheap wifi adaptor I was using was going to sleep :slight_smile:
That meant that while I was testing it and checking it regularly it appeared to work fine, as I was ssh’ing in to the pi every hour, but once I left it alone, the wifi dropped.
Fixed by adding:
/sbin/iwconfig wlan0 power off
to /etc/rc.local

1 Like

I use home assistant on my home network, because I use apple Ive got my iphone, ipad, iwatch etc linked in through my apple account on home assistant.
I can see at a glance how much power is in each device. I can also turn off various power points that have my device connected through when it reaches a preset level ie. 80% most days and 100% for the days I know I’m not going to be in a location where I can convienantly top up my device.

4 Likes