Battery watcher and observer for Mac and Linux laptop.
#!/usr/bin/env perl | |
# xtetsuji by 2014/04/19 | |
our $VERSION = "0.01"; | |
use strict; | |
use warnings; | |
use utf8; | |
use AnyEvent; | |
use Config; | |
#use Cocoa::Growl ':all'; | |
use File::Basename qw(basename); | |
use Getopt::Long (); | |
use WebService::ImKayac::Simple; | |
use constant HAVE_COCOA_GROWL => eval { | |
require Cocoa::Growl; | |
import Cocoa::Growl ':all'; | |
1; | |
}; | |
if ( !HAVE_COCOA_GROWL ) { | |
# Cocoa::Growl の無い環境ではとりあえず何もしないコマンドとして定義しておく | |
*growl_register = sub {}; | |
*growl_notify = sub {}; | |
} | |
use constant APPLICATION_NAME => basename($0); | |
use constant GRAPH_DOWN => -1; | |
use constant GRAPH_UP => 1; | |
use constant GRAPH_RELAX => 0; | |
use constant OSNAME => $Config{osname}; | |
my $p = Getopt::Long::Parser->new( | |
config => [qw(posix_default no_ignore_case auto_help)] | |
); | |
$p->getoptions( | |
'watch-percents=s' => \my $watch_percents, | |
'imkayac-config=s' => \my $imkayac_config, | |
'interval=i' => \my $interval, | |
); | |
our $DEFAULT_INTERVAL = 600; | |
growl_register( | |
app => APPLICATION_NAME, | |
#icon => '', | |
notifications => [qw/info/], | |
); | |
my $IMKAYAC_CONFIG_FILE = $imkayac_config || "$ENV{HOME}/.imkayac.yml"; | |
if ( !-f $IMKAYAC_CONFIG_FILE ) { | |
die qq(ImKayac config file "$IMKAYAC_CONFIG_FILE" is not found\n); | |
} | |
binmode STDOUT, ':utf8'; | |
my @watch_percents = (20, 50, 80); | |
if ( $watch_percents ) { | |
@watch_percents = split /,/, $watch_percents; | |
if ( grep { !/^\d+$/ } @watch_percents ) { | |
die "watch-percent option specify comma separated digits.\n"; | |
} | |
} | |
#chomp(my $hostname = `hostname`); | |
my $hostname = $Config{myhostname}; | |
my $previous_percent = get_remaining(); # initialize | |
my $cv = AnyEvent->condvar; | |
my $im = WebService::ImKayac::Simple->new($IMKAYAC_CONFIG_FILE); | |
my $notify_callback = sub { | |
my $response = shift; | |
print $response . "\n"; # DEBUG? | |
growl_notify( | |
name => 'info', | |
title => APPLICATION_NAME, | |
description => $response, | |
); | |
$im->send(APPLICATION_NAME . ": " . $response . " ($hostname)"); # ok either flagged utf-8 or not. | |
}; | |
my $timer = AnyEvent->timer( | |
after => 10, | |
interval => $interval || $DEFAULT_INTERVAL, | |
cb => sub { | |
my $current_percent = get_remaining(); | |
my $response = ''; | |
# process... | |
for my $key (@watch_percents) { | |
if ( my $res = graph_direction( $previous_percent => $current_percent, $key ) ) { | |
if ( $res == GRAPH_UP ) { | |
$response = "${key}% を上回りました。現在${current_percent}%です。"; | |
} | |
elsif ( $res == GRAPH_DOWN ) { | |
$response = "${key}% を下回りました。現在${current_percent}%です。"; | |
} | |
} | |
} | |
if ( $previous_percent != 100 && $current_percent == 100 ) { | |
$response = "満充電されました。"; | |
} | |
if ( $response ) { | |
$notify_callback->($response); | |
} | |
# reinitialize | |
$previous_percent = $current_percent; | |
}, | |
); | |
$cv->recv(); | |
sub get_remaining { | |
if ( OSNAME eq 'darwin' ) { | |
return get_remaining_mac() | |
} elsif ( OSNAME eq 'linux' ) { | |
return get_remaining_linux(); | |
} else { | |
die "Unsupported your architecture yet\nPlease contact to \@xtetsuji by Twitter if you want to use this program!\n"; | |
} | |
} | |
sub get_remaining_mac { | |
my $pmset = `pmset -g ps`; | |
my ($percent) = $pmset =~ /(\d+)%; /; | |
return $percent; | |
} | |
# 追加してみたけどまだ試していない | |
sub get_remaining_linux { | |
my $acpi = `acpi -b`; | |
my ($percent) = $acpi =~ /(\d+)%, /; | |
return $percent; | |
} | |
# see: http://polamjag.hatenablog.jp/entry/2013/10/23/125843 | |
sub graph_direction { | |
my ($prev, $cur, $thr) = @_; | |
if ( grep { !/^\d+$/ } ($prev, $cur, $thr) ) { | |
require Carp; | |
Carp::croak "graph_direction error. ($prev, $cur, $thr)"; | |
} | |
if ( $cur < $thr && $thr < $prev ) { | |
return GRAPH_DOWN; | |
} | |
elsif ( $prev < $thr && $thr < $cur ) { | |
return GRAPH_UP; | |
} | |
else { | |
return GRAPH_RELAX; | |
} | |
} | |
=pod | |
=head1 NAME | |
battery-watchd - battery watcher and observer for Mac and Linux laptop | |
=head1 SYNOPSIS | |
battery-watchd & | |
=head1 OPTIONS | |
=head2 --watch-percents | |
battery-watchd --watch-percents=5,10,15,20 | |
Specify watch percents separated by comma. | |
=head2 --imkayac-config | |
battery-watchd --imkayac-config=/path/to/config.yml | |
Specify your ImKayac config file path. | |
Default path is "$ENV{HOME}/.imkayac.yml". | |
This file format is YAML format. See below CONFIG FILE SYNTAX section. | |
=head2 --interval | |
battery-watchd --interval=600 | |
Specify watching interval seconds. | |
Default may be 600 seconds. You confirm it by following command. | |
grep DEFAULT_INTERAVAL `which battery-watched` | |
=head1 CONFIG FILE SYNTAX | |
You can give a battery state by ImKayac. | |
So you have to tell this program ImKayac setting. | |
This program gives ImKayac setting file of YAML file. | |
It syntax is same as L<WebService::ImKayac::Simle>'s format. | |
Setting file's path is below "--imkayac-config" section. | |
=head1 DEPENDENCIES | |
L<AnyEvent>, | |
L<Cocoa::Growl>, | |
L<WebService::ImKayac::Simple>, | |
and some Perl5 core modules. | |
=head1 COPYRIGHT AND LICENSE | |
Copyright (C) 2014 by OGATA Tetsuji | |
This library is free software; you can redistribute it and/or modify | |
it under the same terms as Perl itself. | |
=cut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment