How to Monitor Laptop Battery Health Over Time in Python
Log battery percentage, power status, and remaining time every N seconds to a JSON file using psutil for ongoing health monitoring.
pip install psutil
Python code
44 linesimport time
import json
from pathlib import Path
from datetime import datetime
try:
import psutil
except ImportError:
print("psutil required: pip install psutil")
exit(1)
LOG_FILE = Path("battery_health_log.json")
def monitor_battery(log_interval=60, duration=300):
"""Log battery percentage and remaining time every `log_interval` seconds."""
if not LOG_FILE.exists():
with open(LOG_FILE, "w") as f:
json.dump([], f)
start = time.time()
while time.time() - start < duration:
battery = psutil.sensors_battery()
if battery is None:
print("No battery detected.")
break
entry = {
"timestamp": datetime.now().isoformat(),
"percent": battery.percent,
"power_plugged": battery.power_plugged,
"secs_left": battery.secsleft if battery.secsleft != -1 else None
}
with open(LOG_FILE, "r+") as f:
data = json.load(f)
data.append(entry)
f.seek(0)
json.dump(data, f, indent=2)
print(f"Logged: {entry['percent']}% | Plugged: {entry['power_plugged']}")
time.sleep(log_interval)
if __name__ == "__main__":
monitor_battery(log_interval=10, duration=30) # Short demo: 3 entries over 30 seconds
Output
Logged: 85 | Plugged: True
Logged: 85 | Plugged: True
Logged: 84 | Plugged: True
How it works
This script uses psutil.sensors_battery() to get live battery stats—percentage, whether the charger is plugged in, and estimated seconds left. It writes each reading as a JSON entry with a timestamp to battery_health_log.json. A second-by-second timed loop controls recording frequency. The file is opened in r+ mode to append without overwriting earlier entries. Storing the log lets you graph battery degradation over weeks or months.
Common mistakes
- Forgetting to install psutil before running, causing an ImportError.
- Using `w` mode instead of `r+` which overwrites the entire log file each time.
- Not checking `battery is None` on a desktop without a battery, causing an AttributeError.
- Assuming `secsleft` is always an integer; it returns `-1` when unknown and should be converted to `None`.
Variations
- Use `csv.writer` instead of JSON for simpler spreadsheet import.
- Add a `--daemon` flag to run indefinitely, logging every hour and rotating the file daily.
Real-world use cases
- A background service on a laptop tracks charge cycles to alert the user when battery health drops below 80%.
- An IT admin deploys the script across company laptops to collect fleet-wide battery degradation data.
- A power-user runs the logger while on battery to measure discharge rate under different workloads.
Sponsored
More from Automation & scripting
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
- Automatically Log CPU, RAM, and Disk Usage Every Minute in Python easy
- Batch Rename Hundreds of Files in Python easy
Keep learning
Related tutorials and quizzes for this topic.