- Complete installation and uninstallation scripts - Optimized TLP configuration for maximum battery life - PowerTOP analysis and auto-tune functionality - Real-time battery monitoring with detailed stats - ThinkPad-specific optimizations and battery thresholds - Comprehensive documentation and usage guides - Tested on ThinkPad T14 Gen 1 with 13% power reduction
227 lines
7.7 KiB
Bash
Executable File
227 lines
7.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Battery Status Monitor
|
|
# Displays detailed battery information and power consumption
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Function to print header
|
|
print_header() {
|
|
echo -e "${BLUE}=================================================${NC}"
|
|
echo -e "${BLUE} Battery Status Monitor${NC}"
|
|
echo -e "${BLUE}=================================================${NC}"
|
|
echo
|
|
}
|
|
|
|
# Function to get battery information
|
|
get_battery_info() {
|
|
local bat_path="/sys/class/power_supply"
|
|
local ac_path="/sys/class/power_supply/A[CD]*"
|
|
|
|
echo -e "${CYAN}Battery Information:${NC}"
|
|
echo "----------------------------------------"
|
|
|
|
# Find all batteries
|
|
for battery in "$bat_path"/BAT*; do
|
|
if [[ -d "$battery" ]]; then
|
|
local bat_name=$(basename "$battery")
|
|
local capacity=$(cat "$battery/capacity" 2>/dev/null || echo "N/A")
|
|
local status=$(cat "$battery/status" 2>/dev/null || echo "N/A")
|
|
local voltage=$(cat "$battery/voltage_now" 2>/dev/null || echo "0")
|
|
local current=$(cat "$battery/current_now" 2>/dev/null || echo "0")
|
|
local energy_full=$(cat "$battery/energy_full" 2>/dev/null || echo "0")
|
|
local energy_now=$(cat "$battery/energy_now" 2>/dev/null || echo "0")
|
|
local power_now=$(cat "$battery/power_now" 2>/dev/null || echo "0")
|
|
|
|
# Convert values to human readable format
|
|
voltage_v=$(echo "scale=2; $voltage / 1000000" | bc -l 2>/dev/null || echo "0")
|
|
current_a=$(echo "scale=2; $current / 1000000" | bc -l 2>/dev/null || echo "0")
|
|
energy_full_wh=$(echo "scale=2; $energy_full / 1000000" | bc -l 2>/dev/null || echo "0")
|
|
energy_now_wh=$(echo "scale=2; $energy_now / 1000000" | bc -l 2>/dev/null || echo "0")
|
|
power_w=$(echo "scale=2; $power_now / 1000000" | bc -l 2>/dev/null || echo "0")
|
|
|
|
# Color code based on battery level
|
|
if (( $(echo "$capacity >= 80" | bc -l) )); then
|
|
color=$GREEN
|
|
elif (( $(echo "$capacity >= 50" | bc -l) )); then
|
|
color=$YELLOW
|
|
else
|
|
color=$RED
|
|
fi
|
|
|
|
echo -e "${BLUE}$bat_name:${NC}"
|
|
echo -e " Capacity: ${color}${capacity}%${NC}"
|
|
echo -e " Status: $status"
|
|
echo -e " Voltage: ${voltage_v}V"
|
|
echo -e " Current: ${current_a}A"
|
|
echo -e " Power: ${power_w}W"
|
|
echo -e " Energy: ${energy_now_wh}Wh / ${energy_full_wh}Wh"
|
|
|
|
# Calculate remaining time
|
|
if [[ "$status" == "Discharging" ]] && (( $(echo "$power_w > 0" | bc -l) )); then
|
|
remaining_hours=$(echo "scale=2; $energy_now_wh / $power_w" | bc -l)
|
|
remaining_minutes=$(echo "scale=0; $remaining_hours * 60" | bc -l)
|
|
hours=$(echo "scale=0; $remaining_minutes / 60" | bc -l)
|
|
minutes=$(echo "scale=0; $remaining_minutes % 60" | bc -l)
|
|
echo -e " Time left: ${hours}h ${minutes}m"
|
|
elif [[ "$status" == "Charging" ]] && (( $(echo "$power_w > 0" | bc -l) )); then
|
|
charge_needed=$(echo "scale=2; $energy_full_wh - $energy_now_wh" | bc -l)
|
|
charge_time=$(echo "scale=2; $charge_needed / $power_w" | bc -l)
|
|
charge_minutes=$(echo "scale=0; $charge_time * 60" | bc -l)
|
|
charge_hours=$(echo "scale=0; $charge_minutes / 60" | bc -l)
|
|
charge_mins=$(echo "scale=0; $charge_minutes % 60" | bc -l)
|
|
echo -e " Time to full: ${charge_hours}h ${charge_mins}m"
|
|
fi
|
|
echo
|
|
fi
|
|
done
|
|
|
|
# Check AC adapter status
|
|
for ac in $ac_path; do
|
|
if [[ -d "$ac" ]] 2>/dev/null; then
|
|
local ac_name=$(basename "$ac")
|
|
local ac_online=$(cat "$ac/online" 2>/dev/null || echo "0")
|
|
if [[ "$ac_online" == "1" ]]; then
|
|
echo -e "AC Adapter: ${GREEN}Connected${NC}"
|
|
else
|
|
echo -e "AC Adapter: ${RED}Disconnected${NC}"
|
|
fi
|
|
break
|
|
fi
|
|
done
|
|
echo
|
|
}
|
|
|
|
# Function to show TLP status
|
|
show_tlp_status() {
|
|
if command -v tlp-stat &> /dev/null; then
|
|
echo -e "${CYAN}TLP Status:${NC}"
|
|
echo "----------------------------------------"
|
|
tlp-stat -s 2>/dev/null | head -10
|
|
echo
|
|
fi
|
|
}
|
|
|
|
# Function to show power consumption
|
|
show_power_consumption() {
|
|
echo -e "${CYAN}Power Consumption:${NC}"
|
|
echo "----------------------------------------"
|
|
|
|
# Try to get power consumption from various sources
|
|
local power_consumption=""
|
|
|
|
# Method 1: From battery power_now
|
|
for battery in /sys/class/power_supply/BAT*; do
|
|
if [[ -d "$battery" ]]; then
|
|
local power_now=$(cat "$battery/power_now" 2>/dev/null || echo "0")
|
|
if [[ "$power_now" != "0" ]]; then
|
|
power_w=$(echo "scale=2; $power_now / 1000000" | bc -l)
|
|
power_consumption="$power_w"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ -n "$power_consumption" ]]; then
|
|
echo -e "Current draw: ${power_consumption}W"
|
|
else
|
|
echo "Power consumption data not available"
|
|
fi
|
|
|
|
# CPU frequency information
|
|
if [[ -f /proc/cpuinfo ]]; then
|
|
local cpu_freq=$(cat /proc/cpuinfo | grep "cpu MHz" | head -1 | awk '{print $4}')
|
|
if [[ -n "$cpu_freq" ]]; then
|
|
echo -e "CPU frequency: ${cpu_freq} MHz"
|
|
fi
|
|
fi
|
|
|
|
# Load average
|
|
local load_avg=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
|
|
echo -e "Load average: $load_avg"
|
|
|
|
# Temperature (if available)
|
|
if command -v sensors &> /dev/null; then
|
|
local temp=$(sensors | grep "Core 0" | awk '{print $3}' | head -1)
|
|
if [[ -n "$temp" ]]; then
|
|
echo -e "CPU temperature: $temp"
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
}
|
|
|
|
# Function to show system uptime and power efficiency
|
|
show_efficiency() {
|
|
echo -e "${CYAN}System Efficiency:${NC}"
|
|
echo "----------------------------------------"
|
|
|
|
# Uptime
|
|
local uptime_info=$(uptime -p)
|
|
echo -e "Uptime: $uptime_info"
|
|
|
|
# Memory usage
|
|
local mem_info=$(free -h | grep "Mem:" | awk '{print "Used: " $3 " / " $2}')
|
|
echo -e "Memory: $mem_info"
|
|
|
|
# Disk activity
|
|
if command -v iostat &> /dev/null; then
|
|
local disk_usage=$(iostat -d 1 2 | tail -n +4 | head -1 | awk '{print $4 + $5}')
|
|
echo -e "Disk I/O: ${disk_usage} KB/s"
|
|
fi
|
|
|
|
echo
|
|
}
|
|
|
|
# Function to provide power saving tips
|
|
show_tips() {
|
|
echo -e "${CYAN}Power Saving Tips:${NC}"
|
|
echo "----------------------------------------"
|
|
echo "• Lower screen brightness"
|
|
echo "• Close unused applications"
|
|
echo "• Disable unused wireless devices"
|
|
echo "• Use power saving mode"
|
|
echo "• Enable TLP and PowerTOP optimizations"
|
|
echo "• Consider using an SSD instead of HDD"
|
|
echo
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
# Check if bc is available for calculations
|
|
if ! command -v bc &> /dev/null; then
|
|
echo "Installing bc for calculations..."
|
|
sudo apt update && sudo apt install -y bc
|
|
fi
|
|
|
|
# Clear screen and show header
|
|
clear
|
|
print_header
|
|
|
|
# Show all information
|
|
get_battery_info
|
|
show_tlp_status
|
|
show_power_consumption
|
|
show_efficiency
|
|
show_tips
|
|
|
|
echo -e "${BLUE}Last updated: $(date)${NC}"
|
|
}
|
|
|
|
# Watch mode - refresh every 5 seconds
|
|
if [[ "${1:-}" == "--watch" ]]; then
|
|
while true; do
|
|
main
|
|
sleep 5
|
|
done
|
|
else
|
|
main
|
|
fi |