Tutorial

New updates and improvements to Roundfleet.

Important notice

The code examples and scripts provided in these tutorials are for educational purposes only. Roundfleet is not responsible for any issues, damages, or security vulnerabilities that may arise from the use, modification, or implementation of these examples. Always review and test code in a secure environment before using it in production systems.

Battery Charging Limit Management on macOS

Manage battery charging limits across your Roundfleet 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

# Roundfleet Battery Management Tool
# Comprehensive battery charging limit management for enterprise environments

# Configuration
LOG_FILE="/var/log/roundfleet_battery.log"
BACKUP_DIR="/var/backups/roundfleet/battery"
REPORT_DIR="/var/reports/roundfleet/battery"
CONFIG_FILE="/etc/roundfleet/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 "Roundfleet 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 "=== Roundfleet 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 "Roundfleet 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 "=== Roundfleet 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.roundfleet.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.roundfleet.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 TypeRecommended LimitReasoning
Desktop Macs75-80%Always plugged in, prioritize longevity
Laptop Macs (Stationary)80%Mostly plugged in usage
Laptop Macs (Mobile)90%Need higher capacity for portability
Degraded Battery70-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

Related Tutorials

Battery Management on macOS

Learn how to monitor battery status, health, and performance on macOS devices using advanced battery management tools with enterprise-grade monitoring, optimization, compliance, and fleet-wide battery analytics capabilities.

Jul 7, 2025

Sleep and Power Management for macOS

Manage macOS sleep and power settings across Roundfleet devices with automated power policies, energy optimization, compliance monitoring, and comprehensive fleet-wide power management for enterprise efficiency and security.

Jul 7, 2025

Shutdown and Reboot Management for macOS

Manage macOS shutdown and reboot operations across Roundfleet devices with automated maintenance scheduling, graceful shutdown procedures, security validation, and comprehensive fleet-wide power management for enterprise operations.

Jul 7, 2025

Scheduled Restart Management on macOS

Comprehensive guide to scheduling, managing, and monitoring system restarts across macOS fleets with advanced scheduling policies, user notifications, maintenance windows, and compliance reporting.

Jul 7, 2025

Run Setup Assistant on macOS Devices at Next Reboot

Learn how to trigger macOS Setup Assistant on the next reboot for device reconfiguration, user onboarding, and enterprise deployment scenarios.

Jul 7, 2025

Manage Running Processes on macOS

Learn how to monitor CPU usage, memory status, view running processes, and terminate processes on macOS devices using command-line scripts for system management.

Jul 7, 2025

User Creation Management on macOS

Comprehensive guide for enterprise user provisioning and lifecycle management on Roundfleet devices with automated workflows, security controls, and standardized user creation processes.

Jul 7, 2025

User Account Management on macOS

Learn how to create, manage, and configure user accounts on macOS devices using command-line tools. Comprehensive guide for admin and standard user creation, password policies, and enterprise user management.

Jul 7, 2025