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:
- If I am connected to my home wifi
- If the phone is currently being charged
- 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
All mounted in a low tech cardboard box:
Cheers,
John