Imported Upstream version 2.4.3

This commit is contained in:
arnaud.quette@free.fr 2010-03-26 00:20:59 +01:00
commit 26fb71b504
446 changed files with 148951 additions and 0 deletions

View file

@ -0,0 +1,11 @@
# Network UPS Tools: data/html
EXTRA_DIST = README \
app/gui.glade \
app/NUT-Monitor \
app/nut-monitor.desktop \
app/nut-monitor.png \
app/README \
module/PyNUT.py \
module/test_nutclient.py

420
scripts/python/Makefile.in Normal file
View file

@ -0,0 +1,420 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Network UPS Tools: data/html
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = scripts/python
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nut_arg_with.m4 \
$(top_srcdir)/m4/nut_check_ipv6.m4 \
$(top_srcdir)/m4/nut_check_libgd.m4 \
$(top_srcdir)/m4/nut_check_libhal.m4 \
$(top_srcdir)/m4/nut_check_libneon.m4 \
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
$(top_srcdir)/m4/nut_check_libpowerman.m4 \
$(top_srcdir)/m4/nut_check_libssl.m4 \
$(top_srcdir)/m4/nut_check_libusb.m4 \
$(top_srcdir)/m4/nut_check_libwrap.m4 \
$(top_srcdir)/m4/nut_check_os.m4 \
$(top_srcdir)/m4/nut_report_feature.m4 \
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BINDIR = @BINDIR@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONFPATH = @CONFPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@
HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@
HAL_FDI_PATH = @HAL_FDI_PATH@
HAL_USER = @HAL_USER@
HAVE_GLIB_2_14 = @HAVE_GLIB_2_14@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBGD_CFLAGS = @LIBGD_CFLAGS@
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
LIBHAL_CFLAGS = @LIBHAL_CFLAGS@
LIBHAL_LDFLAGS = @LIBHAL_LDFLAGS@
LIBNEON_CFLAGS = @LIBNEON_CFLAGS@
LIBNEON_LDFLAGS = @LIBNEON_LDFLAGS@
LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@
LIBNETSNMP_LDFLAGS = @LIBNETSNMP_LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@
LIBPOWERMAN_LDFLAGS = @LIBPOWERMAN_LDFLAGS@
LIBS = @LIBS@
LIBSSL_CFLAGS = @LIBSSL_CFLAGS@
LIBSSL_LDFLAGS = @LIBSSL_LDFLAGS@
LIBTOOL = @LIBTOOL@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_LDFLAGS = @LIBUSB_LDFLAGS@
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
LIBWRAP_LDFLAGS = @LIBWRAP_LDFLAGS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NETLIBS = @NETLIBS@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OS_NAME = @OS_NAME@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RUN_AS_GROUP = @RUN_AS_GROUP@
RUN_AS_USER = @RUN_AS_USER@
SED = @SED@
SERLIBS = @SERLIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STATEPATH = @STATEPATH@
STRIP = @STRIP@
SUN_LIBUSB = @SUN_LIBUSB@
VERSION = @VERSION@
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
cgiexecdir = @cgiexecdir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
driverexecdir = @driverexecdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
hotplugdir = @hotplugdir@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfigdir = @pkgconfigdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
udevdir = @udevdir@
EXTRA_DIST = README \
app/gui.glade \
app/NUT-Monitor \
app/nut-monitor.desktop \
app/nut-monitor.png \
app/README \
module/PyNUT.py \
module/test_nutclient.py
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/python/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu scripts/python/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

32
scripts/python/README Normal file
View file

@ -0,0 +1,32 @@
Python NUT Client files
-----------------------
This directory contains various NUT Client related Python scripts, written by
David Goncalves, and released under GPL v3.
* "module": this directory contains PyNUT.py, which is a Python abstraction
class to access NUT server(s). You can use it in Python programs to access NUT's
upsd data server in a simple way, without having to know the NUT protocol.
To import it on Python programs you have to use the following (case sensitive) :
'import PyNUT'
This module provides a 'PyNUTClient' class that can be used to connect and get
data from an upsd data server.
To install the PyNUT module on Debian/Ubuntu, copy it to:
/usr/share/python-support/python-pynut/
This directory also contains test_nutclient.py, which is a PyNUT test program.
For this to be fully functional, you will need to adapt the login, password and
upsname to fit your configuration.
* "app": this directory contains the NUT-Monitor application, that uses the
PyNUT class, along with its resources.
To install it, you will either need to keep the files together, or to install:
- NUT-Monitor to /usr/bin, /usr/X11R6/bin/ or something like that,
- gui.glade to /usr/share/nut-monitor/,
- nut-monitor.png to something like /usr/share/pixmaps/
- and nut-monitor.desktop to /usr/share/applications

423
scripts/python/app/NUT-Monitor Executable file
View file

@ -0,0 +1,423 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 David Goncalves <david@lestat.st>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# 2008-02-01 David Goncalves
# A gui to monitor UPSes via NUT using PyNUT class.
# 2009-02-12 David Goncalves
# Modified the status report method to allow 'composite' UPS status
# ( OL + TRIM, OL + OFF, etc... )
import gtk, gtk.glade, gobject, pango
import sys, os, time
import threading
import PyNUT
# Activate use of threadings
gobject.threads_init()
class gui :
__widgets = {}
__callbacks = {}
__ups_handler = None
__ups_thread = None
__ups_name = ""
__ups_commands = list()
__ups_connected = False
__version = "1.1"
__release = "2009-02-12"
def __init__( self ) :
if os.path.exists( "gui.glade" ) :
glade_file = "gui.glade"
else :
glade_file = "/usr/share/nut-monitor/gui.glade"
self.__widgets["interface"] = gtk.glade.XML( glade_file )
self.__widgets["main_window"] = self.__widgets["interface"].get_widget("window1")
self.__widgets["button_ups_refresh"] = self.__widgets["interface"].get_widget("button1")
self.__widgets["button_ups_connect"] = self.__widgets["interface"].get_widget("button2")
self.__widgets["button_ups_disconnect"] = self.__widgets["interface"].get_widget("button4")
self.__widgets["button_ups_list"] = self.__widgets["interface"].get_widget("combobox1")
self.__widgets["button_ups_command_list"] = self.__widgets["interface"].get_widget("combobox3")
self.__widgets["button_ups_command_apply"] = self.__widgets["interface"].get_widget("button3")
self.__widgets["button_authentication"] = self.__widgets["interface"].get_widget("checkbutton1")
self.__widgets["entry_login"] = self.__widgets["interface"].get_widget("entry2")
self.__widgets["entry_password"] = self.__widgets["interface"].get_widget("entry3")
self.__widgets["login_password_frame"] = self.__widgets["interface"].get_widget("hbox2")
self.__widgets["entry_host"] = self.__widgets["interface"].get_widget("entry1")
self.__widgets["entry_port"] = self.__widgets["interface"].get_widget("spinbutton1")
self.__widgets["progress_battery_charge"] = self.__widgets["interface"].get_widget("progressbar1")
self.__widgets["progress_ups_load"] = self.__widgets["interface"].get_widget("progressbar2")
self.__widgets["label_battery_runtime"] = self.__widgets["interface"].get_widget("label2")
self.__widgets["label_ups_infos_left"] = self.__widgets["interface"].get_widget("label15")
self.__widgets["label_ups_infos_right"] = self.__widgets["interface"].get_widget("label16")
self.__widgets["status_bar"] = self.__widgets["interface"].get_widget("statusbar1")
self.__widgets["ups_status_frame"] = self.__widgets["interface"].get_widget("frame1")
self.__widgets["ups_hostport_table"] = self.__widgets["interface"].get_widget("table1")
self.__widgets["main_window"].show()
# Define the callbacks
self.__callbacks = { "on_window1_destroy" : self.quit,
"on_imagemenuitem5_activate" : self.quit,
"on_imagemenuitem2_activate" : self.about,
"on_entry1_changed" : self.__host_changed,
"on_entry2_changed" : self.__login_pass_changed,
"on_entry3_changed" : self.__login_pass_changed,
"on_button1_clicked" : self.__gui_refresh_ups_list,
"on_button2_clicked" : self.__connect_to_ups,
"on_button3_clicked" : self.__apply_ups_command,
"on_button4_clicked" : self.__disconnect_from_ups,
"on_checkbutton1_toggled" : self.__use_authentication_changed
}
# Removes the dummy entry in the combobox
self.__widgets["button_ups_list"].remove_text( 0 )
self.__widgets["button_ups_command_list"].remove_text( 0 )
# Connect the callbacks
self.__widgets["interface"].signal_autoconnect( self.__callbacks )
def run( self ) :
gtk.main()
def about( self, widget=None ) :
dial = self.__widgets["interface"].get_widget( "aboutdialog1" )
dial.run()
dial.destroy()
def quit( self, widget=None ) :
try :
if self.__ups_thread.isAlive() :
self.__ups_thread.stop_thread()
self.__ups_thread.join()
except :
pass
gtk.main_quit()
def refresh_gui( self ) :
while gtk.events_pending() :
gtk.main_iteration( False )
return( True )
# If host string is modified, check if there is a value to activate the "Refresh" button.
def __host_changed( self, widget=None ) :
value = widget.get_text()
if value != "" :
self.__widgets["button_ups_refresh"].set_sensitive( True )
self.__widgets["button_authentication"].set_sensitive( True )
if self.__widgets["button_authentication"].toggled() :
self.__widgets["login_password_frame"].set_sensitive( True )
if self.__widgets["button_ups_list"].get_active() != -1 :
self.__widgets["button_ups_connect"].set_sensitive( True )
else :
self.__widgets["button_ups_refresh"].set_sensitive( False )
self.__widgets["button_ups_connect"].set_sensitive( False )
self.__widgets["button_authentication"].set_sensitive( False )
self.__widgets["login_password_frame"].set_sensitive( False )
def __use_authentication_changed( self, widget=None ) :
if widget.get_active() :
self.__widgets["login_password_frame"].set_sensitive( True )
# Clear UPS List
while self.__widgets["button_ups_list"].get_active() != -1 :
self.__widgets["button_ups_list"].remove_text( 0 )
self.__widgets["button_ups_list"].set_active( 0 )
self.__widgets["button_ups_connect"].set_sensitive( False )
if ( self.__widgets["entry_login"].get_text() == "" ) or ( self.__widgets["entry_password"].get_text() == "" ) :
self.__widgets["button_ups_refresh"].set_sensitive( False )
else :
self.__widgets["button_ups_refresh"].set_sensitive( True )
else :
self.__widgets["login_password_frame"].set_sensitive( False )
self.__widgets["button_ups_refresh"].set_sensitive( True )
def __login_pass_changed( self, widget=None ) :
# Get the values for login/pass fields in order to check that there is something typed
self.__host_changed( self.__widgets["entry_host"] )
def __gui_refresh_ups_list( self, widget=None ) :
host = self.__widgets["entry_host"].get_text()
port = int( self.__widgets["entry_port"].get_value() )
try :
# If the authentication is active, try to log into the UPS using login/password
if self.__widgets["button_authentication"].get_active() :
login = self.__widgets["entry_login"].get_text()
password = self.__widgets["entry_password"].get_text()
else :
login = None
password = None
self.__ups_handler = PyNUT.PyNUTClient( host=host, port=port, login=login, password=password )
result = self.__ups_handler.GetUPSList()
# Clear UPS List
while self.__widgets["button_ups_list"].get_active() != -1 :
self.__widgets["button_ups_list"].remove_text( 0 )
self.__widgets["button_ups_list"].set_active( 0 )
if len( result.keys() ) > 0 :
for current_ups in result.keys() :
self.__widgets["button_ups_list"].append_text( current_ups )
self.__widgets["button_ups_list"].set_active( 0 )
self.__widgets["button_ups_refresh"].set_sensitive( False )
self.__widgets["button_ups_connect"].set_sensitive( True )
self.__widgets["button_authentication"].set_sensitive( False )
self.__widgets["login_password_frame"].set_sensitive( False )
except :
self.status_message( "%s : %s" % ( sys.exc_info()[0], sys.exc_info()[1] ) )
def __gui_refresh_ups_commands( self, widget=None ) :
# Clear the command list
while self.__widgets["button_ups_command_list"].get_active() != -1 :
self.__widgets["button_ups_command_list"].remove_text( 0 )
self.__widgets["button_ups_command_list"].set_active( 0 )
self.__ups_commands = list()
try :
commands = self.__ups_handler.GetUPSCommands( self.__ups_name )
self.__ups_commands = commands.keys()
self.__ups_commands.sort()
for desc in self.__ups_commands :
self.__widgets["button_ups_command_list"].append_text( commands[desc] )
self.__widgets["button_ups_command_list"].set_active( 0 )
self.__widgets["button_ups_command_apply"].set_sensitive( True )
except :
self.__widgets["button_ups_command_apply"].set_sensitive( False )
def __disconnect_from_ups( self, widget=None ) :
if self.__ups_thread.isAlive() :
self.__ups_thread.stop_thread()
self.__ups_thread.join()
def __apply_ups_command( self, widget=None ) :
id = self.__widgets["button_ups_command_list"].get_active()
# Display a confirmation dialog
dial = gtk.MessageDialog( parent=self.__widgets["main_window"],
flags=gtk.DIALOG_MODAL,
type=gtk.MESSAGE_INFO,
buttons=gtk.BUTTONS_YES_NO,
message_format=None )
dial.set_markup( "<span size=\"x-large\"><b>Action confirmation</b></span>" )
msg = "Are you sur that you want to perform a <span foreground=\"#900000\"><b>%s</b></span> on <span foreground=\"#009000\"><b>%s</b></span> ?\n" % ( self.__ups_commands[id], self.__ups_name )
dial.format_secondary_markup( msg )
resp = dial.run()
dial.destroy()
if resp == gtk.RESPONSE_YES :
try :
self.__ups_handler.RunUPSCommand( self.__ups_name, self.__ups_commands[id] )
except :
self.error_message( "<span size=\"x-large\"><b>Send command failed</b></span>", "Something went wrong while sending command to server.\n\n<span foreground=\"#900000\">%s</span>" % sys.exc_info()[1] )
# When the 'connect' button is clicked...
def __connect_to_ups( self, widget=None ) :
# Get the selected UPS name
self.__ups_name = self.__widgets["button_ups_list"].get_active_text()
self.__ups_thread = ups_updater( self )
self.__ups_thread.start()
def error_message( self, message1 = "", message2 = "" ) :
dial = gtk.MessageDialog( parent=self.__widgets["main_window"], flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_WARNING,
buttons=gtk.BUTTONS_CLOSE, message_format=None )
dial.set_markup( message1 )
dial.format_secondary_markup( message2 )
dial.run()
dial.destroy()
def status_message( self, message = "" ) :
context_id = self.__widgets["status_bar"].get_context_id("Infos")
message_id = self.__widgets["status_bar"].push( context_id, message )
self.refresh_gui()
class ups_updater( threading.Thread ) :
__parent_class = None
__stop_thread = False
__ups_status_mapper = { "LB" : "<span color=\"#BB0000\"><b>Low batteries</b></span>",
"RB" : "<span color=\"#FF0000\"><b>Replace batteries !</b></span>",
"BYPASS" : "<span color=\"#BB0000\">Running bypass</span> <i>(no battery protection)</i>",
"CAL" : "Performing runtime calibration",
"OFF" : "<span color=\"#000090\">output offline</span> <i>(not providing power to the load)</i>",
"OVER" : "<span color=\"#BB0000\">Overloaded !</span> <i>(there is too much load for UPS)</i>",
"TRIM" : "Triming <i>(UPS is triming incoming voltage)</i>",
"BOOST" : "Boost <i>(UPS is boosting incoming voltage)</i>"
}
def __init__( self, parent_class ) :
threading.Thread.__init__( self )
self.__parent_class = parent_class
def run( self ) :
self.__parent_class.status_message( "Connecting to %s" % self.__parent_class._gui__ups_name )
self.__parent_class._gui__gui_refresh_ups_commands()
while not self.__stop_thread :
vars = {}
try :
vars = self.__parent_class._gui__ups_handler.GetUPSVars( self.__parent_class._gui__ups_name )
self.__parent_class.status_message( "Connected to %s" % self.__parent_class._gui__ups_name )
self.__parent_class._gui__widgets["ups_status_frame"].set_sensitive( True )
self.__parent_class._gui__widgets["ups_hostport_table"].set_sensitive( False )
self.__parent_class._gui__widgets["button_ups_connect"].hide()
self.__parent_class._gui__widgets["button_ups_disconnect"].show()
self.__parent_class._gui__widgets["button_authentication"].set_sensitive( False )
self.__parent_class._gui__widgets["login_password_frame"].set_sensitive( False )
# Update the battery charge progress bar
if not vars.has_key( "battery.charge" ) :
self.__parent_class._gui__widgets["progress_battery_charge"].set_fraction( 0.0 )
self.__parent_class._gui__widgets["progress_battery_charge"].set_text( "Not available" )
else :
charge = vars.get( "battery.charge", "0" )
self.__parent_class._gui__widgets["progress_battery_charge"].set_fraction( float( charge ) / 100.0 )
self.__parent_class._gui__widgets["progress_battery_charge"].set_text( "%s %%" % int( float( charge ) ) )
# Update the UPS load progress bar
if not vars.has_key( "ups.load" ) :
self.__parent_class._gui__widgets["progress_ups_load"].set_fraction( 0.0 )
self.__parent_class._gui__widgets["progress_ups_load"].set_text( "Not available" )
else :
load = vars.get( "ups.load", "0" )
self.__parent_class._gui__widgets["progress_ups_load"].set_fraction( float( load ) / 100.0 )
self.__parent_class._gui__widgets["progress_ups_load"].set_text( "%s %%" % int( float( load ) ) )
# Update the UPS remaining battery time
if not vars.has_key( "battery.runtime" ) :
self.__parent_class._gui__widgets["label_battery_runtime"].set_text( "Not available" )
else :
runtime = int( float( vars.get( "battery.runtime", "0" ) ) )
H = runtime / 3600
M = ( runtime - ( H * 3600 ) ) / 60
S = runtime - ( H * 3600 ) - ( M * 60 )
if H > 0 :
string = "%s hour(s) %s minutes %s seconds" % ( H, M, S )
elif ( H == 0 ) and ( M > 0 ) :
string = "%s minutes %s seconds" % ( M, S )
else :
string = "%s seconds" % S
self.__parent_class._gui__widgets["label_battery_runtime"].set_text( string )
text_left = ""
text_right = ""
# Update UPS informations fields
if vars.has_key("ups.status") :
text_left += "<b>UPS Status :</b>\n\n"
if vars["ups.status"].find( "OL" ) != -1 :
# UPS is online
text_right += "<span color=\"#009000\">Online</span>"
if vars["ups.status"].find( "OB" ) != -1 :
# UPS is on batteries
text_right += "<span color=\"#900000\">On batteries</span>"
# Check for additionnal informations
for k,v in self.__ups_status_mapper.iteritems() :
if vars["ups.status"].find(k) != -1 :
text_right += " - %s" % v
text_right += "\n\n"
text_left += "<b>UPS Model :</b>\n"
if vars.has_key("ups.mfr") :
text_right += "%s " % vars.get( "ups.mfr", "" )
if vars.has_key("ups.model") :
text_right += "%s\n" % vars.get( "ups.model", "" )
if vars.has_key("ups.serial") :
text_left += "<b>S/N :</b>\n"
text_right += "%s\n" % vars.get( "ups.serial", "" )
if vars.has_key("ups.id") :
text_left += "<b>Identifier :</b>\n"
text_right += "%s\n" % vars.get( "ups.id", "" )
if vars.has_key("ups.temperature") :
text_left += "<b>Temperature :</b>\n"
text_right += "%s\n" % int( float( vars.get( "ups.temperature", 0 ) ) )
if vars.has_key("battery.voltage") :
text_left += "<b>Battery voltage :</b>\n"
text_right += "%sv\n" % vars.get( "battery.voltage", "0" )
self.__parent_class._gui__widgets["label_ups_infos_left"].set_markup( text_left[:-1] )
self.__parent_class._gui__widgets["label_ups_infos_right"].set_markup( text_right[:-1] )
except :
self.__parent_class.status_message( repr(sys.exc_info()[1]) )
self.__parent_class._gui__widgets["ups_status_frame"].set_sensitive( False )
time.sleep( 1 )
# The thread stops...
self.__parent_class._gui__widgets["ups_status_frame"].set_sensitive( False )
self.__parent_class._gui__widgets["ups_hostport_table"].set_sensitive( True )
self.__parent_class._gui__widgets["button_ups_disconnect"].hide()
self.__parent_class._gui__widgets["button_ups_connect"].show()
self.__parent_class.status_message( "Disconnected from %s" % self.__parent_class._gui__ups_name )
# Clear all data fields
self.__parent_class._gui__widgets["label_ups_infos_right"].set_markup( "" )
self.__parent_class._gui__widgets["label_battery_runtime"].set_text( "" )
self.__parent_class._gui__widgets["progress_battery_charge"].set_fraction( 0.0 )
self.__parent_class._gui__widgets["progress_ups_load"].set_fraction( 0.0 )
self.__parent_class._gui__widgets["progress_battery_charge"].set_text( "0 %" )
self.__parent_class._gui__widgets["progress_ups_load"].set_text( "0 %" )
def stop_thread( self ) :
self.__stop_thread = True
if __name__ == "__main__" :
app = gui()
app.run()

View file

@ -0,0 +1,7 @@
NUT-Monitor is a graphical application to access and manager UPSes connected to
a NUT (Network UPS Tools) server.
This application (written in Python + GTK) uses the python-pynut class
(available at http://www.lestat.st)
David Goncalves <david@lestat.st>

View file

@ -0,0 +1,658 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Tue Jun 24 14:36:50 2008 -->
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<signal name="destroy" handler="on_window1_destroy"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkImageMenuItem" id="imagemenuitem2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-about</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_imagemenuitem2_activate"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="imagemenuitem5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-quit</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_imagemenuitem5_activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label_xalign">0.5</property>
<child>
<widget class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="top_padding">2</property>
<property name="bottom_padding">2</property>
<property name="left_padding">2</property>
<property name="right_padding">2</property>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Host / Port : </property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">UPS : </property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spinbutton1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="adjustment">3493 0 65535 1 10 10</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip_text">Get list of UPSs from server</property>
<property name="label" translatable="yes">gtk-refresh</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_button1_clicked"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<signal name="changed" handler="on_entry1_changed"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="combobox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="items" translatable="yes">&lt;None&gt;
</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="checkbutton1">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Use authentication</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_checkbutton1_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Login / Password : </property>
</widget>
</child>
<child>
<widget class="GtkEntry" id="entry2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<signal name="changed" handler="on_entry2_changed"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="visibility">False</property>
<signal name="changed" handler="on_entry3_changed"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="padding">4</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip" translatable="yes">Connect to the selected UPS</property>
<property name="label" translatable="yes">gtk-connect</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_button2_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button4">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-disconnect</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_button4_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Delay between refresh : </property>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="spinbutton2">
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip_text">Delay in seconds between refreshs</property>
<property name="adjustment">0.5 0.5 10 0.10000000000000001 10 10</property>
<property name="digits">1</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">4</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes"> NUT Server </property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label_xalign">0.5</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="top_padding">2</property>
<property name="bottom_padding">2</property>
<property name="left_padding">2</property>
<property name="right_padding">2</property>
<child>
<widget class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkComboBox" id="combobox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="items" translatable="yes">&lt;None&gt;
</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button3">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">gtk-apply</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_button3_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">UPS Commands : </property>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">4</property>
<child>
<widget class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">0</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
<child>
<placeholder/>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_padding">2</property>
<property name="y_padding">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label12">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">UPS informations : </property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="show_text">True</property>
<property name="text" translatable="yes">0 %</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Battery charge : </property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">UPS Load : </property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="show_text">True</property>
<property name="text" translatable="yes">0 %</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">0:00</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
</widget>
</child>
<child>
<placeholder/>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_padding">2</property>
<property name="y_padding">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Time remaining : </property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes"> UPS Status </property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusbar1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkAboutDialog" id="aboutdialog1">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">About UPS Monitor</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="has_separator">False</property>
<property name="program_name">NUT Monitor</property>
<property name="version">0.1beta</property>
<property name="copyright" translatable="yes">Copyright (c) David Goncalves</property>
<property name="comments" translatable="yes">GUI to manage UPS trough a NUT server</property>
<property name="website">http://www.lestat.st</property>
<property name="website_label" translatable="yes">www.lestat.st</property>
<property name="license" translatable="yes">Copyright (C) 2008 David Goncalves &lt;david@lestat.st&gt;
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</property>
<property name="authors">David Goncalves - &lt;david@lestat.st&gt;</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<placeholder/>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -0,0 +1,11 @@
[Desktop Entry]
Name=NUT Monitor
Name[fr]=Moniteur NUT
Comment=Network UPS Tools GUI client
Comment[fr]=Client graphique pour NUT (Network UPS Tools)
Categories=Application;Network;
Encoding=UTF-8
Exec=NUT-Monitor
Icon=nut-monitor.png
Terminal=false
Type=Application

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,238 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 David Goncalves <david@lestat.st>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# 2008-01-14 David Goncalves
# PyNUT is an abstraction class to access NUT (Network UPS Tools) server.
#
# 2008-06-09 David Goncalves
# Added 'GetRWVars' and 'SetRWVar' commands.
import telnetlib
class PyNUTClient :
""" Abstraction class to access NUT (Network UPS Tools) server """
__debug = None # Set class to debug mode (prints everything useful for debuging...)
__host = None
__port = None
__login = None
__password = None
__timeout = None
__srv_handler = None
__version = "1.0"
__release = "2008-06-09"
def __init__( self, host="127.0.0.1", port=3493, login=None, password=None, debug=False, timeout=5 ) :
""" Class initialization method
host : Host to connect (default to localhost)
port : Port where NUT listens for connections (default to 3493)
login : Login used to connect to NUT server (default to None for no authentication)
password : Password used when using authentication (default to None)
debug : Boolean, put class in debug mode (prints everything on console, default to False)
timeout : Timeout used to wait for network response
"""
self.__debug = debug
if self.__debug :
print( "[DEBUG] Class initialization..." )
print( "[DEBUG] -> Host = %s (port %s)" % ( host, port ) )
print( "[DEBUG] -> Login = '%s' / '%s'" % ( login, password ) )
self.__host = host
self.__port = port
self.__login = login
self.__password = password
self.__timeout = 5
self.__connect()
# Try to disconnect cleanly when class is deleted ;)
def __del__( self ) :
""" Class destructor method """
try :
self.__srv_handler.write( "LOGOUT\n" )
except :
pass
def __connect( self ) :
""" Connects to the defined server
If login/pass was specified, the class tries to authenticate. An error is raised
if something goes wrong.
"""
if self.__debug :
print( "[DEBUG] Connecting to host" )
self.__srv_handler = telnetlib.Telnet( self.__host, self.__port )
if self.__login != None :
self.__srv_handler.write( "USERNAME %s\n" % self.__login )
result = self.__srv_handler.read_until( "\n", self.__timeout )
if result[:2] != "OK" :
raise Exception, result.replace( "\n", "" )
if self.__password != None :
self.__srv_handler.write( "PASSWORD %s\n" % self.__password )
result = self.__srv_handler.read_until( "\n", self.__timeout )
if result[:2] != "OK" :
raise Exception, result.replace( "\n", "" )
def GetUPSList( self ) :
""" Returns the list of available UPS from the NUT server
The result is a dictionnary containing 'key->val' pairs of 'UPSName' and 'UPS Description'
"""
if self.__debug :
print( "[DEBUG] GetUPSList from server" )
self.__srv_handler.write( "LIST UPS\n" )
result = self.__srv_handler.read_until( "\n" )
if result != "BEGIN LIST UPS\n" :
raise Exception, result.replace( "\n", "" )
result = self.__srv_handler.read_until( "END LIST UPS\n" )
ups_list = {}
for line in result.split( "\n" ) :
if line[:3] == "UPS" :
ups, desc = line[4:-1].split( '"' )
ups_list[ ups.replace( " ", "" ) ] = desc
return( ups_list )
def GetUPSVars( self, ups="" ) :
""" Get all available vars from the specified UPS
The result is a dictionnary containing 'key->val' pairs of all
available vars.
"""
if self.__debug :
print( "[DEBUG] GetUPSVars called..." )
self.__srv_handler.write( "LIST VAR %s\n" % ups )
result = self.__srv_handler.read_until( "\n" )
if result != "BEGIN LIST VAR %s\n" % ups :
raise Exception, result.replace( "\n", "" )
ups_vars = {}
result = self.__srv_handler.read_until( "END LIST VAR %s\n" % ups )
offset = len( "VAR %s " % ups )
end_offset = 0 - ( len( "END LIST VAR %s\n" % ups ) + 1 )
for current in result[:end_offset].split( "\n" ) :
var = current[ offset: ].split( '"' )[0].replace( " ", "" )
data = current[ offset: ].split( '"' )[1]
ups_vars[ var ] = data
return( ups_vars )
def GetUPSCommands( self, ups="" ) :
""" Get all available commands for the specified UPS
The result is a dict object with command name as key and a description
of the command as value
"""
if self.__debug :
print( "[DEBUG] GetUPSCommands called..." )
self.__srv_handler.write( "LIST CMD %s\n" % ups )
result = self.__srv_handler.read_until( "\n" )
if result != "BEGIN LIST CMD %s\n" % ups :
raise Exception, result.replace( "\n", "" )
ups_cmds = {}
result = self.__srv_handler.read_until( "END LIST CMD %s\n" % ups )
offset = len( "CMD %s " % ups )
end_offset = 0 - ( len( "END LIST CMD %s\n" % ups ) + 1 )
for current in result[:end_offset].split( "\n" ) :
var = current[ offset: ].split( '"' )[0].replace( " ", "" )
# For each var we try to get the available description
try :
self.__srv_handler.write( "GET CMDDESC %s %s\n" % ( ups, var ) )
temp = self.__srv_handler.read_until( "\n" )
if temp[:7] != "CMDDESC" :
raise
else :
off = len( "CMDDESC %s %s " % ( ups, var ) )
desc = temp[off:-1].split('"')[1]
except :
desc = var
ups_cmds[ var ] = desc
return( ups_cmds )
def GetRWVars( self, ups="" ) :
""" Get a list of all writable vars from the selected UPS
The result is presented as a dictionnary containing 'key->val' pairs
"""
if self.__debug :
print( "[DEBUG] GetUPSVars from '%s'..." % ups )
self.__srv_handler.write( "LIST RW %s\n" % ups )
result = self.__srv_handler.read_until( "\n" )
if ( result != "BEGIN LIST RW %s\n" % ups ) :
raise Exception, result.replace( "\n", "" )
result = self.__srv_handler.read_until( "END LIST RW %s\n" % ups )
offset = len( "VAR %s" % ups )
end_offset = 0 - ( len( "END LIST RW %s\n" % ups ) + 1 )
rw_vars = {}
for current in result[:end_offset].split( "\n" ) :
var = current[ offset: ].split( '"' )[0].replace( " ", "" )
data = current[ offset: ].split( '"' )[1]
rw_vars[ var ] = data
return( rw_vars )
def SetRWVar( self, ups="", var="", value="" ):
""" Set a variable to the specified value on selected UPS
The variable must be a writable value (cf GetRWVars) and you must have the proper
rights to set it (maybe login/password).
"""
self.__srv_handler.write( "SET VAR %s %s %s\n" % ( ups, var, value ) )
result = self.__srv_handler.read_until( "\n" )
if ( result == "OK\n" ) :
return( "OK" )
else :
raise Exception, result
def RunUPSCommand( self, ups="", command="" ) :
""" Send a command to the specified UPS
Returns OK on success or raises an error
"""
if self.__debug :
print( "[DEBUG] RunUPSCommand called..." )
self.__srv_handler.write( "INSTCMD %s %s\n" % ( ups, command ) )
result = self.__srv_handler.read_until( "\n" )
if ( result == "OK\n" ) :
return( "OK" )
else :
raise Exception, result.replace( "\n", "" )

View file

@ -0,0 +1,43 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This source code is provided for testing/debuging purpose ;)
import PyNUT
import sys
if __name__ == "__main__" :
print( "PyNUTClient test..." )
nut = PyNUT.PyNUTClient( debug=True )
#nut = PyNUT.PyNUTClient( login="upsadmin", password="upsadmin", debug=True )
print( 80*"-" + "\nTesting 'GetUPSList' :")
result = nut.GetUPSList( )
print( "\033[01;33m%s\033[0m\n" % result )
print( 80*"-" + "\nTesting 'GetUPSVars' :")
result = nut.GetUPSVars( "dummy" )
print( "\033[01;33m%s\033[0m\n" % result )
print( 80*"-" + "\nTesting 'GetUPSCommands' :")
result = nut.GetUPSCommands( "dummy" )
print( "\033[01;33m%s\033[0m\n" % result )
print( 80*"-" + "\nTesting 'GetRWVars' :")
result = nut.GetRWVars( "dummy" )
print( "\033[01;33m%s\033[0m\n" % result )
print( 80*"-" + "\nTesting 'RunUPSCommand' (Test front panel) :")
try :
result = nut.RunUPSCommand( "UPS1", "test.panel.start" )
except :
result = sys.exc_info()[1]
print( "\033[01;33m%s\033[0m\n" % result )
print( 80*"-" + "\nTesting 'SetUPSVar' (set ups.id to test):")
try :
result = nut.SetRWVar( "UPS1", "ups.id", "test" )
except :
result = sys.exc_info()[1]
print( "\033[01;33m%s\033[0m\n" % result )