Индикатор для системной службы NUT
authorRoman Bazalevsky <rvb@perseus.rvb-home.lan>
Sat, 30 Nov 2013 11:26:25 +0000 (15:26 +0400)
committerRoman Bazalevsky <rvb@perseus.rvb-home.lan>
Sat, 30 Nov 2013 11:26:25 +0000 (15:26 +0400)
indicator-nut.py [new file with mode: 0755]

diff --git a/indicator-nut.py b/indicator-nut.py
new file mode 100755 (executable)
index 0000000..1fd48e9
--- /dev/null
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+
+import sys
+import gtk
+import appindicator
+
+import imaplib
+import re
+
+import os
+import pynotify
+
+PING_FREQUENCY = 10 # seconds
+
+def exec_command(command):
+  stream = os.popen(command)
+  out = stream.read()
+  out = re.split('\n',out);
+  res = []
+  for newline in out:
+    if len(newline)==0:
+      continue;
+    elif newline.startswith("Error:"):
+      res=[];
+      break;
+    else:
+      res.append(newline)
+  return res
+
+class CheckNUT:
+
+    def __init__(self):
+        self.ind = appindicator.Indicator("nut-indicator",
+                                          "gpm-ups-100-charging",                                        
+                                         appindicator.CATEGORY_APPLICATION_STATUS)
+        self.ind.set_status(appindicator.STATUS_ACTIVE)
+        self.ind.set_attention_icon("gpm-ups-000")
+
+       hosts = sys.argv[1:]
+
+       if len(hosts)==0:
+          hosts = {'localhost'}
+
+        self.upses=[]
+        for host in hosts : 
+          command = "upsc -l {0}".format(host)
+          try:
+            local_upses=exec_command(command)
+            for ups in local_upses:
+              self.upses.append('{0}@{1}'.format(ups,host))
+          except:
+            pass
+
+        if self.upses == []:
+          print "No connected ups'es found!\n"
+          sys.exit(1)
+          
+        self.menu_setup()
+        self.ind.set_menu(self.menu)
+
+        if not pynotify.init ("nut-indicator"):
+          self.disable_notify=1
+        else:
+          self.disable_notify=0
+
+        self.ups_dictionary = {}
+        self.ups_dictionary['battery charge'] = 'Battery charge %'
+        self.ups_dictionary['input voltage'] = 'Input voltage'
+        self.ups_dictionary['output voltage'] = 'Output voltage'
+        self.ups_dictionary['ups load'] = 'UPS load %'
+        self.ups_dictionary['ups status'] = 'UPS status'
+
+        self.ups_value_dictionary = {}
+        self.ups_value_dictionary['ups status'] = {}
+        self.ups_value_dictionary['ups status']['OL'] = {1,'online'}
+        self.ups_value_dictionary['ups status']['OB'] = {0,'on battery'}
+        self.ups_value_dictionary['ups status']['LB'] = {-1,'low batter'}
+
+    def menu_setup(self):
+        self.menu = gtk.Menu()
+
+        self.menuitems = {}
+        for ups in self.upses:
+          print ups;
+          menu_item = gtk.MenuItem(ups)
+          menu_item.connect("activate",self.call_check_local_ups,ups)
+          menu_item.show()
+          self.menu.append(menu_item)
+          self.menuitems[ups]=menu_item
+
+        separator = gtk.SeparatorMenuItem()
+        separator.show()
+        self.menu.append(separator)
+
+        self.quit_item = gtk.MenuItem("Quit")
+        self.quit_item.connect("activate", self.quit)
+        self.quit_item.show()
+        self.menu.append(self.quit_item)
+
+    def main(self):
+        self.check_ups()
+        gtk.timeout_add(PING_FREQUENCY * 1000, self.check_ups)
+        gtk.main()
+
+    def quit(self, widget):
+        sys.exit(0)
+
+    def call_check_local_ups(self,item,ups):
+        return self.check_local_ups(ups,1)
+
+    def check_local_ups(self,ups,notify):
+        command = "upsc {0}".format(ups)
+        res = exec_command(command)
+        status="?"
+        battery="?"
+        ups_status="?"
+        text=""
+        minstatus=1
+        for newline in res:
+          paramname,paramvalue = newline.split(': ',1)
+          paramname = paramname.replace('.',' ')
+          try:
+            status,paramvalue = self.ups_value_dictionary[paramname][paramvalue]
+            if status<minstatus:
+              status=minstatus
+          except:
+            pass
+          try:
+            printname = self.ups_dictionary[paramname]
+            text="{0}\n{1} = {2}".format(text,printname,paramvalue)
+          except:
+            pass
+            
+          if paramname=="battery charge":
+            battery=paramvalue
+          elif paramname=="ups status":
+            ups_status=paramvalue
+
+        if battery=='?':
+          self.menuitems[ups].get_child().set_text('{0}: {1}'.format(ups,ups_status))
+        else:
+          self.menuitems[ups].get_child().set_text('{0}: {1}, {2}%'.format(ups,ups_status,battery))
+        if (notify==1 or minstatus<0) and self.disable_notify==0:
+          n = pynotify.Notification(ups,text)
+          helper = gtk.Button()
+          icon = helper.render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG)
+          n.set_icon_from_pixbuf(icon)
+          n.show()
+        return minstatus
+
+    def check_ups(self):
+
+        min_status=1;
+
+        for ups in self.upses:
+          status=self.check_local_ups(ups,0)
+          if status<min_status:
+            min_status=status
+
+        if status < 0:
+            self.ind.set_status(appindicator.STATUS_ATTENTION)
+            self.ind.set_attention_icon("gpm-ups-000")
+        elif status==0:
+            self.ind.set_status(appindicator.STATUS_ATTENTION)
+            self.ind.set_attention_icon("gpm-ups-060")
+        else:
+            self.ind.set_status(appindicator.STATUS_ACTIVE)
+        return True
+
+if __name__ == "__main__":
+    indicator = CheckNUT()
+    indicator.main()
+