Battery Charging Limit Management on macOS
Manage battery charging limits across your MacFleet devices to optimize battery health and implement enterprise power management policies. This tutorial covers installation of battery management tools, charging limit configuration, persistence settings, and comprehensive fleet-wide battery health monitoring.
Understanding Battery Charging Limits
Battery charging limits help preserve battery health by preventing overcharging, especially beneficial for devices that remain plugged in continuously:
Why Set Charging Limits?
- Battery Longevity - Prevents degradation from constant 100% charge
- Heat Reduction - Lower charge levels generate less heat during operation
- Enterprise Cost Savings - Extended battery life reduces replacement costs
- Power Management - Optimized charging for stationary workstations
- Environmental Benefits - Longer battery life reduces electronic waste
Battery Management Tools
bclm
- Battery Charge Limit Max (primary tool)- SMC - System Management Controller (hardware interface)
- Homebrew - Package manager for macOS tools
- Power Management - Built-in macOS power controls
Prerequisites and Installation
Install Homebrew Package Manager
#!/bin/bash
# Install Homebrew package manager
echo "đē Installing Homebrew package manager..."
# Check if Homebrew is already installed
if command -v brew >/dev/null 2>&1; then
echo "âšī¸ Homebrew is already installed"
echo "Homebrew version: $(brew --version | head -1)"
else
echo "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [[ $? -eq 0 ]]; then
echo "â
Homebrew installed successfully"
else
echo "â Homebrew installation failed"
exit 1
fi
fi
# Verify installation and add to PATH if needed
if [[ -f /opt/homebrew/bin/brew ]]; then
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -f /usr/local/bin/brew ]]; then
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/usr/local/bin/brew shellenv)"
fi
echo "Homebrew location: $(which brew)"
Install BCLM (Battery Charge Limit Max)
#!/bin/bash
# Install bclm (Battery Charge Limit Max)
echo "đ Installing bclm (Battery Charge Limit Max)..."
# Ensure Homebrew is available
if ! command -v brew >/dev/null 2>&1; then
echo "â Homebrew not found. Please install Homebrew first."
exit 1
fi
# Install bclm
echo "Adding zackelia/formulae tap..."
if brew tap zackelia/formulae; then
echo "â
Tap added successfully"
else
echo "â Failed to add tap"
exit 1
fi
echo "Installing bclm..."
if brew install bclm; then
echo "â
bclm installed successfully"
else
echo "â bclm installation failed"
exit 1
fi
# Verify installation
if command -v bclm >/dev/null 2>&1; then
echo "bclm location: $(which bclm)"
echo "Testing bclm access..."
# Test read access (doesn't require sudo)
if bclm read >/dev/null 2>&1; then
echo "â
bclm is working correctly"
echo "Current charging limit: $(bclm read)%"
else
echo "â ī¸ bclm installed but may require additional permissions"
fi
else
echo "â bclm not found in PATH"
exit 1
fi
Basic Charging Limit Management
Set Charging Limit
#!/bin/bash
# Set battery charging limit
LIMIT="$1"
if [[ -z "$LIMIT" ]]; then
echo "â Usage: $0 <percentage>"
echo "Example: $0 80"
echo "Valid range: 50-100"
exit 1
fi
# Validate limit range
if [[ "$LIMIT" -lt 50 || "$LIMIT" -gt 100 ]]; then
echo "â Invalid limit: $LIMIT"
echo "Charging limit must be between 50% and 100%"
exit 1
fi
echo "đ Setting battery charging limit to $LIMIT%..."
# Get current limit for comparison
CURRENT_LIMIT=$(bclm read 2>/dev/null)
if [[ -n "$CURRENT_LIMIT" ]]; then
echo "Current limit: $CURRENT_LIMIT%"
fi
# Set new charging limit
if sudo bclm write "$LIMIT"; then
echo "â
Charging limit set to $LIMIT%"
# Verify the setting
NEW_LIMIT=$(bclm read 2>/dev/null)
if [[ "$NEW_LIMIT" == "$LIMIT" ]]; then
echo "â
Setting verified: $NEW_LIMIT%"
else
echo "â ī¸ Warning: Verification shows $NEW_LIMIT% instead of $LIMIT%"
fi
else
echo "â Failed to set charging limit"
exit 1
fi
echo "âšī¸ Note: Restart may be required for changes to take effect"
Read Current Charging Limit
#!/bin/bash
# Read current battery charging limit
echo "đ Reading current battery charging limit..."
if command -v bclm >/dev/null 2>&1; then
CURRENT_LIMIT=$(bclm read 2>/dev/null)
if [[ -n "$CURRENT_LIMIT" ]]; then
echo "Current charging limit: $CURRENT_LIMIT%"
# Provide context about the limit
if [[ "$CURRENT_LIMIT" -eq 100 ]]; then
echo "âšī¸ Battery charges to maximum capacity (no limit set)"
elif [[ "$CURRENT_LIMIT" -ge 80 ]]; then
echo "âšī¸ Conservative charging limit for battery longevity"
elif [[ "$CURRENT_LIMIT" -ge 60 ]]; then
echo "âšī¸ Moderate charging limit for extended battery life"
else
echo "âšī¸ Aggressive charging limit for maximum battery preservation"
fi
else
echo "â Unable to read charging limit"
echo "This may indicate bclm is not properly installed or lacks permissions"
exit 1
fi
else
echo "â bclm not found. Please install bclm first."
exit 1
fi
Make Charging Limit Persistent
#!/bin/bash
# Make charging limit persistent across reboots
echo "đž Making charging limit persistent..."
if ! command -v bclm >/dev/null 2>&1; then
echo "â bclm not found. Please install bclm first."
exit 1
fi
# Get current limit
CURRENT_LIMIT=$(bclm read 2>/dev/null)
if [[ -z "$CURRENT_LIMIT" ]]; then
echo "â Unable to read current charging limit"
exit 1
fi
echo "Current charging limit: $CURRENT_LIMIT%"
# Make persistent
if sudo bclm persist; then
echo "â
Charging limit ($CURRENT_LIMIT%) is now persistent"
echo "The limit will be maintained across system reboots"
else
echo "â Failed to make charging limit persistent"
exit 1
fi
echo "âšī¸ To remove persistence, run: sudo bclm unpersist"
Remove Charging Limit Persistence
#!/bin/bash
# Remove charging limit persistence
echo "đ Removing charging limit persistence..."
if ! command -v bclm >/dev/null 2>&1; then
echo "â bclm not found. Please install bclm first."
exit 1
fi
# Get current limit before removing persistence
CURRENT_LIMIT=$(bclm read 2>/dev/null)
if [[ -n "$CURRENT_LIMIT" ]]; then
echo "Current charging limit: $CURRENT_LIMIT%"
fi
# Remove persistence
if sudo bclm unpersist; then
echo "â
Charging limit persistence removed"
echo "The limit may reset to 100% after next reboot"
else
echo "â Failed to remove charging limit persistence"
exit 1
fi
echo "âšī¸ To restore persistence, run: sudo bclm persist"
Advanced Battery Management
Enterprise Battery Health Check
#!/bin/bash
# Comprehensive battery health assessment
echo "đ Performing comprehensive battery health check..."
# Check if battery is present
if ! system_profiler SPPowerDataType | grep -q "Battery Information"; then
echo "â No battery found on this system"
exit 1
fi
echo "=== Battery Health Assessment ==="
# Get battery information
BATTERY_INFO=$(system_profiler SPPowerDataType)
# Extract key metrics
CYCLE_COUNT=$(echo "$BATTERY_INFO" | grep "Cycle Count" | awk '{print $3}')
CONDITION=$(echo "$BATTERY_INFO" | grep "Condition" | awk '{print $2}')
MAX_CAPACITY=$(echo "$BATTERY_INFO" | grep "Maximum Capacity" | awk '{print $3}' | sed 's/%//')
echo "Battery Condition: $CONDITION"
echo "Cycle Count: $CYCLE_COUNT"
echo "Maximum Capacity: $MAX_CAPACITY%"
# Check charging limit if bclm is available
if command -v bclm >/dev/null 2>&1; then
CHARGING_LIMIT=$(bclm read 2>/dev/null)
if [[ -n "$CHARGING_LIMIT" ]]; then
echo "Charging Limit: $CHARGING_LIMIT%"
else
echo "Charging Limit: Not set (100%)"
fi
fi
# Power adapter information
POWER_ADAPTER=$(echo "$BATTERY_INFO" | grep -A5 "AC Charger Information" | grep "Wattage" | awk '{print $2}')
if [[ -n "$POWER_ADAPTER" ]]; then
echo "Power Adapter: ${POWER_ADAPTER}W"
fi
# Health assessment
echo -e "\n=== Health Assessment ==="
if [[ "$CONDITION" == "Normal" ]]; then
echo "â
Battery condition is normal"
elif [[ "$CONDITION" == "Replace Soon" ]]; then
echo "â ī¸ Battery should be replaced soon"
elif [[ "$CONDITION" == "Replace Now" ]]; then
echo "â Battery needs immediate replacement"
else
echo "âšī¸ Battery condition: $CONDITION"
fi
if [[ -n "$CYCLE_COUNT" ]]; then
if [[ "$CYCLE_COUNT" -lt 500 ]]; then
echo "â
Cycle count is healthy ($CYCLE_COUNT cycles)"
elif [[ "$CYCLE_COUNT" -lt 1000 ]]; then
echo "â ī¸ Moderate cycle count ($CYCLE_COUNT cycles)"
else
echo "â High cycle count ($CYCLE_COUNT cycles)"
fi
fi
if [[ -n "$MAX_CAPACITY" ]]; then
if [[ "$MAX_CAPACITY" -ge 90 ]]; then
echo "â
Maximum capacity is excellent ($MAX_CAPACITY%)"
elif [[ "$MAX_CAPACITY" -ge 80 ]]; then
echo "â
Maximum capacity is good ($MAX_CAPACITY%)"
elif [[ "$MAX_CAPACITY" -ge 70 ]]; then
echo "â ī¸ Maximum capacity is declining ($MAX_CAPACITY%)"
else
echo "â Maximum capacity is poor ($MAX_CAPACITY%)"
fi
fi
# Recommendations
echo -e "\n=== Recommendations ==="
if [[ -z "$CHARGING_LIMIT" || "$CHARGING_LIMIT" -eq 100 ]]; then
echo "đĄ Consider setting a charging limit (80-90%) for better battery health"
fi
if [[ "$CYCLE_COUNT" -gt 1000 && "$MAX_CAPACITY" -lt 80 ]]; then
echo "đĄ Battery replacement may be needed soon"
fi
Optimized Charging Limit Recommendations
#!/bin/bash
# Provide charging limit recommendations based on usage patterns
echo "đ¯ Analyzing optimal charging limit recommendations..."
# Get device model and usage information
DEVICE_MODEL=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}')
UPTIME=$(uptime | awk '{print $3}' | sed 's/,//')
echo "Device: $DEVICE_MODEL"
echo "Current uptime: $UPTIME"
# Check if device is primarily plugged in
AC_POWER_COUNT=$(pmset -g log | grep -c "Using AC" 2>/dev/null || echo "0")
BATTERY_POWER_COUNT=$(pmset -g log | grep -c "Using Batt" 2>/dev/null || echo "0")
echo -e "\n=== Usage Pattern Analysis ==="
if [[ "$AC_POWER_COUNT" -gt "$BATTERY_POWER_COUNT" ]]; then
USAGE_TYPE="Desktop/Stationary"
RECOMMENDED_LIMIT=80
echo "Usage pattern: Primarily AC powered"
echo "Recommendation: Set charging limit to $RECOMMENDED_LIMIT%"
else
USAGE_TYPE="Mobile/Portable"
RECOMMENDED_LIMIT=90
echo "Usage pattern: Frequently on battery"
echo "Recommendation: Set charging limit to $RECOMMENDED_LIMIT%"
fi
# Get current battery health
BATTERY_CONDITION=$(system_profiler SPPowerDataType | grep "Condition" | awk '{print $2}')
MAX_CAPACITY=$(system_profiler SPPowerDataType | grep "Maximum Capacity" | awk '{print $3}' | sed 's/%//')
if [[ -n "$MAX_CAPACITY" && "$MAX_CAPACITY" -lt 85 ]]; then
RECOMMENDED_LIMIT=75
echo "â ī¸ Battery health is declining, recommended limit: $RECOMMENDED_LIMIT%"
fi
# Check current setting
if command -v bclm >/dev/null 2>&1; then
CURRENT_LIMIT=$(bclm read 2>/dev/null)
if [[ -n "$CURRENT_LIMIT" ]]; then
echo "Current limit: $CURRENT_LIMIT%"
if [[ "$CURRENT_LIMIT" -eq "$RECOMMENDED_LIMIT" ]]; then
echo "â
Current setting is optimal"
else
echo "đĄ Consider adjusting to $RECOMMENDED_LIMIT% for optimal battery health"
fi
else
echo "Current limit: Not set (100%)"
echo "đĄ Recommended action: Set charging limit to $RECOMMENDED_LIMIT%"
fi
fi
echo -e "\n=== Implementation Command ==="
echo "To set recommended limit: sudo bclm write $RECOMMENDED_LIMIT"
echo "To make persistent: sudo bclm persist"
Enterprise Battery Management Script
#!/bin/bash
# MacFleet Battery Management Tool
# Comprehensive battery charging limit management for enterprise environments
# Configuration
LOG_FILE="/var/log/macfleet_battery.log"
BACKUP_DIR="/var/backups/macfleet/battery"
REPORT_DIR="/var/reports/macfleet/battery"
CONFIG_FILE="/etc/macfleet/battery_policy.conf"
# Battery policy settings
DEFAULT_CHARGING_LIMIT=80
MOBILE_DEVICE_LIMIT=90
STATIONARY_DEVICE_LIMIT=75
ENFORCE_BATTERY_POLICY=false
HEALTH_CHECK_ENABLED=true
ALERT_CAPACITY_THRESHOLD=80
ALERT_CYCLE_THRESHOLD=1000
# Logging function
log_action() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Setup directories
setup_directories() {
for dir in "$BACKUP_DIR" "$REPORT_DIR" "$(dirname "$CONFIG_FILE")"; do
if [[ ! -d "$dir" ]]; then
sudo mkdir -p "$dir"
log_action "Created directory: $dir"
fi
done
}
# Check if device has a battery
check_battery_presence() {
if system_profiler SPPowerDataType | grep -q "Battery Information"; then
return 0
else
echo "â No battery found on this system"
log_action "No battery detected on device"
return 1
fi
}
# Install battery management tools
install_battery_tools() {
echo "đ§ Installing battery management tools..."
log_action "Battery tools installation started"
# Check and install Homebrew
if ! command -v brew >/dev/null 2>&1; then
echo "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add to PATH
if [[ -f /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -f /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
fi
# Install bclm
if ! command -v bclm >/dev/null 2>&1; then
echo "Installing bclm..."
brew tap zackelia/formulae && brew install bclm
if command -v bclm >/dev/null 2>&1; then
echo "â
bclm installed successfully"
log_action "bclm installed successfully"
else
echo "â bclm installation failed"
log_action "bclm installation failed"
return 1
fi
else
echo "â
bclm already installed"
fi
return 0
}
# Generate comprehensive battery report
generate_battery_report() {
local report_file="$REPORT_DIR/battery_report_$(date +%Y%m%d_%H%M%S).txt"
echo "đ Generating comprehensive battery report..."
{
echo "MacFleet Battery Management Report"
echo "Generated: $(date)"
echo "Device: $(hostname)"
echo "================================="
echo ""
# System information
echo "=== System Information ==="
system_profiler SPHardwareDataType | grep -E "Model Name|Model Identifier|Processor|Memory"
echo ""
# Battery hardware information
echo "=== Battery Hardware Information ==="
local battery_info=$(system_profiler SPPowerDataType)
echo "$battery_info" | grep -E "Condition|Cycle Count|Maximum Capacity|Manufacturer|Device Name|Pack Lot Code|PCB Lot Code|Firmware Version|Hardware Revision"
echo ""
# Current charging limit
echo "=== Charging Limit Configuration ==="
if command -v bclm >/dev/null 2>&1; then
local current_limit=$(bclm read 2>/dev/null)
if [[ -n "$current_limit" ]]; then
echo "Current charging limit: $current_limit%"
# Check if persistent
local smc_value=$(sudo bclm read 2>/dev/null)
if [[ "$smc_value" == "$current_limit" ]]; then
echo "Persistence status: Enabled"
else
echo "Persistence status: Disabled"
fi
else
echo "Current charging limit: Not set (100%)"
echo "Persistence status: N/A"
fi
else
echo "bclm status: Not installed"
fi
echo ""
# Power usage analysis
echo "=== Power Usage Analysis ==="
echo "Power adapter connected: $(system_profiler SPPowerDataType | grep -q "AC Charger Information" && echo "Yes" || echo "No")"
# Get power adapter info if available
local adapter_info=$(system_profiler SPPowerDataType | grep -A3 "AC Charger Information" | grep "Wattage")
if [[ -n "$adapter_info" ]]; then
echo "Power adapter: $(echo "$adapter_info" | awk '{print $2}')W"
fi
# Battery temperature and voltage
echo "Battery temperature: $(ioreg -l | grep Temperature | awk '{print $3/100}' | head -1)°C"
echo "Battery voltage: $(ioreg -l | grep Voltage | awk '{print $3/1000}' | head -1)V"
echo ""
# Health assessment
echo "=== Battery Health Assessment ==="
local condition=$(echo "$battery_info" | grep "Condition" | awk '{print $2}')
local cycle_count=$(echo "$battery_info" | grep "Cycle Count" | awk '{print $3}')
local max_capacity=$(echo "$battery_info" | grep "Maximum Capacity" | awk '{print $3}' | sed 's/%//')
echo "Overall condition: $condition"
echo "Cycle count: $cycle_count"
echo "Maximum capacity: $max_capacity%"
# Health scoring
local health_score=100
if [[ "$condition" != "Normal" ]]; then
health_score=$((health_score - 20))
fi
if [[ -n "$cycle_count" ]]; then
if [[ "$cycle_count" -gt 1000 ]]; then
health_score=$((health_score - 20))
elif [[ "$cycle_count" -gt 500 ]]; then
health_score=$((health_score - 10))
fi
fi
if [[ -n "$max_capacity" ]]; then
if [[ "$max_capacity" -lt 70 ]]; then
health_score=$((health_score - 30))
elif [[ "$max_capacity" -lt 80 ]]; then
health_score=$((health_score - 20))
elif [[ "$max_capacity" -lt 90 ]]; then
health_score=$((health_score - 10))
fi
fi
echo "Health score: $health_score/100"
# Recommendations
echo ""
echo "=== Recommendations ==="
if [[ "$health_score" -ge 80 ]]; then
echo "â
Battery health is good"
echo "đĄ Consider setting charging limit to 80% for optimal longevity"
elif [[ "$health_score" -ge 60 ]]; then
echo "â ī¸ Battery health is declining"
echo "đĄ Set charging limit to 75% and monitor closely"
else
echo "â Battery health is poor"
echo "đĄ Consider battery replacement and immediate charging limit to 70%"
fi
# Policy compliance check
if [[ "$ENFORCE_BATTERY_POLICY" == "true" ]]; then
echo ""
echo "=== Policy Compliance ==="
echo "Battery policy enforcement: ENABLED"
echo "Default charging limit: $DEFAULT_CHARGING_LIMIT%"
if [[ -n "$current_limit" ]]; then
if [[ "$current_limit" -eq "$DEFAULT_CHARGING_LIMIT" ]]; then
echo "Compliance status: â
COMPLIANT"
else
echo "Compliance status: â NON-COMPLIANT"
echo "Current: $current_limit%, Required: $DEFAULT_CHARGING_LIMIT%"
fi
else
echo "Compliance status: â NON-COMPLIANT (no limit set)"
fi
fi
} > "$report_file"
echo "đ Report saved to: $report_file"
log_action "Battery report generated: $report_file"
}
# Set optimal charging limit based on usage pattern
set_optimal_charging_limit() {
local force_limit="$1"
echo "đ¯ Determining optimal charging limit..."
if ! check_battery_presence; then
return 1
fi
# Install tools if needed
if ! command -v bclm >/dev/null 2>&1; then
if ! install_battery_tools; then
echo "â Failed to install required tools"
return 1
fi
fi
local recommended_limit="$DEFAULT_CHARGING_LIMIT"
# Override with forced limit if provided
if [[ -n "$force_limit" ]]; then
recommended_limit="$force_limit"
echo "Using forced limit: $recommended_limit%"
else
# Analyze usage pattern
echo "Analyzing device usage pattern..."
# Check if device is primarily stationary (simplified detection)
local model=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}')
if echo "$model" | grep -qi "mac studio\|mac pro\|imac"; then
recommended_limit="$STATIONARY_DEVICE_LIMIT"
echo "Detected stationary device, recommended limit: $recommended_limit%"
else
recommended_limit="$MOBILE_DEVICE_LIMIT"
echo "Detected mobile device, recommended limit: $recommended_limit%"
fi
# Adjust based on battery health
local max_capacity=$(system_profiler SPPowerDataType | grep "Maximum Capacity" | awk '{print $3}' | sed 's/%//')
if [[ -n "$max_capacity" && "$max_capacity" -lt 85 ]]; then
recommended_limit=75
echo "Adjusted for battery health: $recommended_limit%"
fi
fi
# Set the charging limit
echo "Setting charging limit to $recommended_limit%..."
if sudo bclm write "$recommended_limit"; then
echo "â
Charging limit set to $recommended_limit%"
# Make persistent
if sudo bclm persist; then
echo "â
Charging limit made persistent"
log_action "Charging limit set to $recommended_limit% and made persistent"
else
echo "â ī¸ Failed to make charging limit persistent"
log_action "Charging limit set to $recommended_limit% but persistence failed"
fi
# Verify setting
local verify_limit=$(bclm read 2>/dev/null)
if [[ "$verify_limit" == "$recommended_limit" ]]; then
echo "â
Setting verified: $verify_limit%"
else
echo "â ī¸ Verification failed: expected $recommended_limit%, got $verify_limit%"
fi
else
echo "â Failed to set charging limit"
log_action "Failed to set charging limit to $recommended_limit%"
return 1
fi
}
# Monitor battery health and alert on issues
monitor_battery_health() {
echo "đ Monitoring battery health..."
if ! check_battery_presence; then
return 1
fi
local battery_info=$(system_profiler SPPowerDataType)
local condition=$(echo "$battery_info" | grep "Condition" | awk '{print $2}')
local cycle_count=$(echo "$battery_info" | grep "Cycle Count" | awk '{print $3}')
local max_capacity=$(echo "$battery_info" | grep "Maximum Capacity" | awk '{print $3}' | sed 's/%//')
local alerts_triggered=0
# Check condition
if [[ "$condition" != "Normal" ]]; then
echo "đ¨ ALERT: Battery condition is $condition"
log_action "ALERT: Battery condition is $condition"
((alerts_triggered++))
fi
# Check cycle count
if [[ -n "$cycle_count" && "$cycle_count" -gt "$ALERT_CYCLE_THRESHOLD" ]]; then
echo "đ¨ ALERT: High cycle count - $cycle_count cycles"
log_action "ALERT: High cycle count - $cycle_count cycles"
((alerts_triggered++))
fi
# Check capacity
if [[ -n "$max_capacity" && "$max_capacity" -lt "$ALERT_CAPACITY_THRESHOLD" ]]; then
echo "đ¨ ALERT: Low maximum capacity - $max_capacity%"
log_action "ALERT: Low maximum capacity - $max_capacity%"
((alerts_triggered++))
fi
if [[ "$alerts_triggered" -eq 0 ]]; then
echo "â
No battery health alerts"
log_action "Battery health monitoring: No alerts"
else
echo "â ī¸ $alerts_triggered battery health alert(s) triggered"
log_action "Battery health monitoring: $alerts_triggered alerts triggered"
fi
return $alerts_triggered
}
# Main execution function
main() {
local action="${1:-help}"
local target="${2:-}"
log_action "=== MacFleet Battery Management Started ==="
setup_directories
case "$action" in
"install"|"setup")
install_battery_tools
;;
"report"|"status")
generate_battery_report
;;
"set")
if [[ -n "$target" ]]; then
set_optimal_charging_limit "$target"
else
set_optimal_charging_limit
fi
;;
"read"|"current")
if command -v bclm >/dev/null 2>&1; then
local current=$(bclm read 2>/dev/null)
if [[ -n "$current" ]]; then
echo "Current charging limit: $current%"
else
echo "No charging limit set (100%)"
fi
else
echo "â bclm not installed"
fi
;;
"persist")
if command -v bclm >/dev/null 2>&1; then
if sudo bclm persist; then
echo "â
Charging limit made persistent"
else
echo "â Failed to make charging limit persistent"
fi
else
echo "â bclm not installed"
fi
;;
"unpersist")
if command -v bclm >/dev/null 2>&1; then
if sudo bclm unpersist; then
echo "â
Charging limit persistence removed"
else
echo "â Failed to remove charging limit persistence"
fi
else
echo "â bclm not installed"
fi
;;
"monitor")
monitor_battery_health
;;
"health")
if check_battery_presence; then
local battery_info=$(system_profiler SPPowerDataType)
echo "=== Battery Health Summary ==="
echo "$battery_info" | grep -E "Condition|Cycle Count|Maximum Capacity"
if command -v bclm >/dev/null 2>&1; then
local limit=$(bclm read 2>/dev/null)
echo "Charging Limit: ${limit:-100}%"
fi
fi
;;
"help"|*)
echo "MacFleet Battery Management Tool"
echo "Usage: $0 [action] [options]"
echo ""
echo "Actions:"
echo " install - Install battery management tools (Homebrew, bclm)"
echo " report - Generate comprehensive battery report"
echo " set [limit] - Set optimal charging limit (or specify percentage)"
echo " read - Read current charging limit"
echo " persist - Make charging limit persistent"
echo " unpersist - Remove charging limit persistence"
echo " monitor - Monitor battery health and trigger alerts"
echo " health - Show battery health summary"
echo " help - Show this help message"
echo ""
echo "Examples:"
echo " $0 install # Install required tools"
echo " $0 set 80 # Set 80% charging limit"
echo " $0 set # Set optimal limit based on device type"
echo " $0 report # Generate detailed report"
echo ""
echo "Charging Limit Guidelines:"
echo " 50-100% - Valid range"
echo " 80% - Recommended for most devices"
echo " 75% - For stationary/desktop Macs"
echo " 90% - For mobile/laptop Macs"
;;
esac
log_action "=== MacFleet Battery Management Completed ==="
}
# Execute main function
main "$@"
Battery Health Monitoring
Automated Health Checks
# Schedule daily battery health monitoring
create_health_monitoring_schedule() {
local plist_file="$HOME/Library/LaunchAgents/com.macfleet.battery-monitor.plist"
cat > "$plist_file" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.macfleet.battery-monitor</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>$(realpath "$0")</string>
<string>monitor</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
EOF
launchctl load "$plist_file" 2>/dev/null
echo "â
Daily battery monitoring scheduled"
}
Charging Limit Recommendations
Device Type | Recommended Limit | Reasoning |
---|---|---|
Desktop Macs | 75-80% | Always plugged in, prioritize longevity |
Laptop Macs (Stationary) | 80% | Mostly plugged in usage |
Laptop Macs (Mobile) | 90% | Need higher capacity for portability |
Degraded Battery | 70-75% | Extend remaining battery life |
Important Notes
- Supported Devices - Only works on Mac devices with batteries
- Administrative Privileges - Requires sudo access for SMC modifications
- System Compatibility - Compatible with modern macOS versions
- Restart Requirements - Some changes may require system restart
- Fleet Deployment - Test on individual devices before bulk deployment
- Battery Health - Monitor battery condition regularly for optimal results