#!/usr/bin/perl -w #============================================================================== # description: #------------------------------------------------------------------------------ # Perl script to administrate an UPS using an Hardware::UPS::Perl # driver either via a running UPS agent or directly on a serial device. #============================================================================== #============================================================================== # embedded pod documentation: #------------------------------------------------------------------------------ =head1 NAME upsadm - administrates an UPS using an Hardware::UPS::Perl driver indirectly via TCP or directly on a serial device =head1 SYNOPSIS B S<[ B<-h>, B<--help> ]> S<[ B<-M>, B<--man> ]> S<[ B<-V>, B<--version> ]> S<[ B<-D>, B<--driver> I ]> S<[ B<-d>, B<--debug-level> [I] ]> S<[ B<-r>, B<--remote> [I]> S<[ B<-T>, B<--toggle-beeper> ]> S<[ B<-t>, B<--test> [I] ]> S<[ B<-B>, B<--test-battery-low> ]> S<[ B<-c>, B<--cancel-test> ]> S<[ B<-S>, B<--shutdown> I ]> S<[ B<-R>, B<--restore> I ]> S<[ B<-C>, B<--cancel-shutdown> ]> [I] =head1 DESCRIPTION B is a command line utility to administrate an UPS using a driver specified on the command line. There are to ways of operating: On the one hand, the UPS can reside on a local serial device specified by the optional F parameter. If the parameter is omitted, F, i.e. the COM1 port, is used per default unless overriden by the environment variable F. On the other hand, the UPS can be administrated via TCP/IP, if there is an UPS agent running at a remote host speciefied by the F<--remote> option. =head1 OPTIONS =over 4 =item B<-h>, B<--help> Displays a short usage help message and exits without errors. =item B<-M>, B<--man> Displays the embedded pod documentation of B (this screen) using B, B and B as pager; it exits without errors. =item B<-V>, B<--version> Displays version information and exits without errors. =item B<-D>, B<--driver> I Sets the UPS driver I to use. I is a case-insensitive string. If not specified, the default driver "Megatec" is used. =item B<-d>, B<--debug-level> [I] Sets the integer debug level I. If the debug level is not specified, a default of 1 is assumed. A higher debug level will increase the verbosity. The maximum is 5. =item B<-r>, B<--remote> [I] Switches to the remote operation modus, i.e. the UPS is watched via TCP/IP using a remotely running UPS agent. The remote site is specified by the F and optionally the TCP port F separated by ':'. If not specified, the local host's default FQDN will be used together with default TCP port F<9050>. =item B<-T>, B<--toggle-beeper> Toggles the beeper. =item B<-t>, B<--test> [I] Tests the UPS for a period of I in minutes. If the argument is omitted, a standard test lasting 10 seconds is performed. =item B<-B>, B<--test-battery-low> Tests the UPS until the battery is low. =item B<-c>, B<--cancel-test> Cancels any test activity. =item B<-S>, B<--shutdown> [I] Causes the UPS to shutdown in a period of I minutes. =item B<-R>, B<--restores> [I] Restores the UPS after a period of I minutes after a shutdown has been performed. This option requires the option F<--shutdown>. =item B<-C>, B<--cancel-shutdown> Cancels any shutdown activity. =back =head1 EXAMPLES =over 4 =item B Tests the UPS. =item B -t 10 I Tests the UPS on COM2 for 10 minutes. =item B B<-r> I<192.168.1.2:7030> Tests the UPS located at host F<192.168.1.2> via an UPS agent listening at TCP port F<7030> at this host. =back =head1 SEE ALSO groff(1), less(1), pod2man(1), upsagent(1), upsstat(1), upswatch(1), Getopt::Long(3pm), Hardware::UPS::Perl::Connection(3pm), Hardware::UPS::Perl::Connection::Net(3pm), Hardware::UPS::Perl::Connection::Serial(3pm), Hardware::UPS::Perl::Constants(3pm), Hardware::UPS::Perl::Driver(3pm), Hardware::UPS::Perl::Driver::Megatec(3pm), Hardware::UPS::Perl::General(3pm), Hardware::UPS::Perl::Logging(3pm), Hardware::UPS::Perl::PID(3pm), Hardware::UPS::Perl::Utils(3pm) =head1 AUTHOR Christian Reile, Christian.Reile@t-online.de =cut #============================================================================== # Entries for revision control: #------------------------------------------------------------------------------ # Revision : $Revision: 1.3 $ # Author : $Author: creile $ # Last Modified On: $Date: 2007/04/17 19:52:26 $ # Status : $State: Exp $ #------------------------------------------------------------------------------ # Modifications : #------------------------------------------------------------------------------ # # $Log: upsadm.pl,v $ # Revision 1.3 2007/04/17 19:52:26 creile # unnecessary comments removed. # # Revision 1.2 2007/04/14 09:37:26 creile # documentation update. # # Revision 1.1 2007/04/07 14:52:43 creile # initial revision. # # #============================================================================== #============================================================================== # packages required: #------------------------------------------------------------------------------ # # Getopt::Long - processing options # strict - restricting unsafe constructs # # Hardware::UPS::Perl::Constants - importing Hardware::UPS::Perl constants # Hardware::UPS::Perl::General - importing Hardware::UPS::Perl variables # and functions for scripts # Hardware::UPS::Perl::Logging - importing Hardware::UPS::Perl methods # dealing with log files # #============================================================================== use Getopt::Long; use strict; use Hardware::UPS::Perl::Constants qw( UPSFQDN UPSPORT UPSSCRIPT UPSTCPPORT ); use Hardware::UPS::Perl::General; use Hardware::UPS::Perl::Logging; #============================================================================== # defining global variables: #------------------------------------------------------------------------------ # # $DebugLevel - the debug level # $Driver - the actual driver to use # $Host - the host the UPS resides # $Logger - the UPS logging object # $Port - the actual serial device the UPS is located on # $ToggleBeeperFlag - flag indicating to toggle the beeper # %Test - hash indicating what to test # %ProcessTest - action table to process testing # $CancelTestFlag - flag indicating to cancel a test # $ShutdownPeriod - period until the UPS is shut down # $RestartPeriod - period until the UPS is restored again # $CancelShutdownFlag - flag indicating to cancel any shutdown activity # #============================================================================== use vars qw( $DebugLevel $Driver $Host $Logger $Port $ToggleBeeperFlag %Test %ProcessTest $CancelTestFlag %Shutdown %ProcessShutdown $CancelShutdownFlag ); #============================================================================== # defining subroutines: #============================================================================== sub Init { # subroutine for initializing the working environment # initializing the working environment InitWE(); # revision number use constant REVISION_VERSION => sprintf( "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/ ); # revison date use constant REVISION_DATE => sprintf( "%d/%02d/%02d", q$Date: 2007/04/17 19:52:26 $ =~ /(\d+)\/(\d+)\/(\d+)/ ); # the default driver use constant DRIVER => "Megatec"; # action table to process tests %ProcessTest = ( standard => sub { # the standard test my $ups = shift; if (!$ups->testUPS()) { Warning( "testing UPS failed -- " .$ups->getErrorMessage() ); } }, period => sub { # test for a certain period my $ups = shift; my $period = shift; if (!$ups->testUPSPeriod($period)) { Warning( "testing UPS failed -- " .$ups->getErrorMessage() ); } }, batteryLow => sub { # the test until battery low occurs my $ups = shift; if (!$ups->testUPS()) { Warning( "testing UPS failed -- " .$ups->getErrorMessage() ); } }, ); # action table to process shutdowns %ProcessShutdown = ( standard => sub { # a real shutdown without restore my $ups = shift; my $period = shift; if (!$ups->shutdownUPS($period)) { Warning( "shutting UPS down failed -- " .$ups->getErrorMessage() ); } }, restore => sub { # a shutdown followed be a restore my $ups = shift; my $period = shift; if (!$ups->shutdownRestore(@{$period})) { Warning( "shutting UPS down with restore failed -- " .$ups->getErrorMessage() ); } }, ); } # end of subroutine "Init" sub GetParameters { # subroutine for getting and checking options # hidden local variables my $debugLevel; # switch to specify the debug level my $driver; # switch to specify the driver to load my $host; # switch to specify the host the UPS resides my $toggleBeeper; # switch to sepcify the beeper's toogle my $testPeriod; # switch to sepcify the test period my $testBatteryLow; # switch to sepcify the test the UPS until battery low my $cancelTest; # switch to sepcify a cancelling of a test my $shutdownPeriod; # switch to sepcify the shutdown period of an UPS my $restorePeriod; # switch to sepcify the restore period of an UPS my $cancelShutdown; # switch to sepcify a cancelling of a shutdown my $help; # switch for displaying usage help my $manpage; # switch for displaying man page my $version; # switch for displaying version information my $return; # returning error # configuring subroutine `GetOptions': case sensitivity &Getopt::Long::config("no_ignore_case"); # getting options $return = GetOptions( "debug-level|d:i" => \$debugLevel , "driver|D=s" => \$driver , "remote|r:s" => \$host , "toggle-beeper|T" => \$toggleBeeper , "test|t:s" => \$testPeriod , "test-low|B" => \$testBatteryLow, "cancel-test|c" => \$cancelTest , "shutdown|S=s" => \$shutdownPeriod, "restore|R=s" => \$restorePeriod , "cancel-shutdown|C" => \$cancelShutdown, "help|h" => \$help , "man|M" => \$manpage , "version|V" => \$version , ); # checking all options Usage(1) if ( ! $return ); # displaying usage help and exit without errors Usage(0) if ( $help ); # displaying man page and exit without errors ManPage() if ( $manpage ); # displaying version information and exit without errors if ( $version ) { Version(REVISION_VERSION, REVISION_DATE, "administrates an UPS"); } # checking individual options # # setting the debug level if ( defined($debugLevel) ) { $DebugLevel = $debugLevel ? $debugLevel : 1; } else { $DebugLevel = 0; } # the driver to use $Driver = $driver ? $driver : DRIVER; # tasks # # toggling of the beeper $ToggleBeeperFlag = $toggleBeeper ? $toggleBeeper : undef; # testing the UPS if ($testBatteryLow and $testPeriod) { Error("excluding options --test-battery-low and --test"); } else { if (defined $testBatteryLow) { $Test{batteryLow} = 1; } else { if (defined $testPeriod) { if ($testPeriod) { $Test{period} = $testPeriod; } else { $Test{standard} = 1; } } } } # cancel test $CancelTestFlag = $cancelTest ? $cancelTest : 0; # shutdown of the UPS if ($restorePeriod and !$shutdownPeriod) { Error("option --restore requires --shutdown"); } else { if ($restorePeriod) { $Shutdown{restore} = [ $shutdownPeriod, $restorePeriod, ]; } elsif ($shutdownPeriod) { $Shutdown{standard} = $shutdownPeriod; } } # cancel shutdown $CancelShutdownFlag = $cancelShutdown ? $cancelShutdown : 0; # setting the operation modus if (defined $host) { # remote watch $Host = $host ? $host : UPSFQDN; if ($Host =~ /:/) { $Host = $`; $Port = $'; } else { $Port = UPSTCPPORT; } } else { # local watch $Host = q{}; # setting the serial port $Port = $ARGV[0] ? $ARGV[0] : UPSPORT; } # opening the log file $Logger = Hardware::UPS::Perl::Logging->new({ File => \*STDOUT, }); if (!defined $Logger) { Error("creating logger failed -- $UPSERROR"); } } # end of subroutine "GetParameters" sub Usage { # subroutine for displaying a short usage help and exiting, if # $exitStatus >= 0; # # parameters: $exitStatus (input) - status on exit # input as hidden local variable my $exitStatus = shift; # displaying short usage help on STDOUT print <= 0 exit $exitStatus; } # end of subroutine "Usage" #============================================================================== # start of main body: #============================================================================== # hidden local variables my $connectOptions; # the connection options my $ups; # the UPS object # initializing of working environment Init(); # getting options GetParameters(); # connecting to UPS if ($Host) { # remotely via TCP $connectOptions = { Host => $Host , TCPPort => $Port , DebugLevel => $DebugLevel, Driver => $Driver , Logger => $Logger , }; } else { # locally via a serial port $connectOptions = { SerialPort => $Port , DebugLevel => $DebugLevel, Driver => $Driver , Logger => $Logger , }; } $ups = ConnectUPS($connectOptions); # toggle the beeper if (defined $ToggleBeeperFlag) { $ups->toggleBeeper(); } # testing the UPS TEST_UPS: while (my ($testType, $arg) = each %Test) { $ProcessTest{ $testType }->($ups, $arg); } # cancel UPS test if ($CancelTestFlag) { $ups->cancelTest() or Warning("cancel of testing UPS failed -- ".$ups->getErrorMessage()); } # shutting the UPS down SHUTDOWN_UPS: while (my ($shutdownType, $arg) = each %Shutdown) { $ProcessShutdown{ $shutdownType }->($ups, $arg); } # cancel UPS shutdown if ($CancelShutdownFlag) { $ups->cancelShutdown() or Warning("cancel of UPS shutdown failed -- ".$ups->getErrorMessage()); } # exiting exit 0;