#!/usr/bin/perl
# show battery level for bluetooth devices
# Jerry Stratton astoundingscripts.com
use Term::ANSIColor;
$normal = color 'green';
$warning = color 'yellow';
$critical = color 'red';
$clear = color 'reset';
$warningLevel = 30;
$criticalLevel = $warningLevel/2;

#check for command-line switches
while ($option = shift) {
	if ($option =~ /^--colors$/) {
		$colors = 1;
	} elsif ($option =~ /^--warnings$/) {
		$warningsOnly = 1;
	} elsif ($option =~ /^--wired$/) {
		$showWired = 1;
	} elsif ($option =~ /^--help$/) {
		help();
	} elsif ($option =~ /^--verbose$/) {
		$verbose = 1;
	} else {
		help("Unknown option $option");
	}
}

#collect battery levels
@ioText = `/usr/sbin/ioreg -l`;
for (@ioText) {
	$bluetoothName = $1 if m/"Bluetooth Product Name" = "([^"]*)"/;
	$wiredName = $1 if m/"Product" = "([^"]*)"/;
	if (m/"BatteryPercent" = ([0-9]+)/) {
		my $level = $1;
		my $device = 'Unknown Device';
		my $source = 'No name found';
		if ($bluetoothName ne '') {
			$device = $bluetoothName;
			$source = 'bluetooth';
		} elsif ($wiredName) {
			$device = $wiredName;
			$source = 'wired';
		}
		$devices{$device} = $level;
		$sources{$device} = $source;
		$maxDeviceWidth = length($device) if length($device) > $maxDeviceWidth;
		$maxLevelWidth = length($level) if length($level) > $maxLevelWidth;
		undef $bluetoothName;
		undef $wiredName;
	}
}

#display battery levels
for $device (sort keys %devices) {
	$level = $devices{$device};
	$source = $sources{$device};
	next if $warningsOnly && $level > $warningLevel && (!$showWired || $source ne 'wired');

	$spaces = 1;
	$spaces += $maxDeviceWidth-length($device);
	$spaces += $maxLevelWidth-length($level);
	$alignment = ' ' x $spaces;

	if ($colors) {
		if ($level <= $criticalLevel) {
			print $critical;
		} elsif ($level <= $warningLevel) {
			print $warning;
		} else {
			print $normal;
		}
	}
	print "$device:$alignment$level";
	print " ($source)" if $verbose;
	print $clear if $colors;
	print "\n";
}

sub help {
	my $message = shift;
	print "$0 [--warnings]\n";
	print "\tshow battery levels of any product with a battery level.\n";
	print "\t--colors:\tdisplay different battery warning levels in different colors.\n";
	print "\t--verbose:\tdisplay where the device name came from.\n";
	print "\t--warnings:\tonly show levels at warning level ($warningLevel%) or below.\n";
	print "\t--wired:\tshow all wired devices, even if above the warning level.\n";
	print "\n";
	print "$message.\n" if $message;
	exit;
}
