License added
[indicator-nut.git] / indicator-nut.py
1 #!/usr/bin/env python
2
3 import sys
4 import gtk
5 import appindicator
6
7 import imaplib
8 import re
9
10 import os
11 import pynotify
12
13 PING_FREQUENCY = 10 # seconds
14
15 def exec_command(command):
16   stream = os.popen(command)
17   out = stream.read()
18   out = re.split('\n',out);
19   res = []
20   for newline in out:
21     if len(newline)==0:
22       continue;
23     elif newline.startswith("Error:"):
24       res=[];
25       break;
26     else:
27       res.append(newline)
28   return res
29
30 class CheckNUT:
31
32     def __init__(self):
33         self.ind = appindicator.Indicator("nut-indicator",
34                                           "gpm-ups-100-charging",                                        
35                                           appindicator.CATEGORY_APPLICATION_STATUS)
36         self.ind.set_status(appindicator.STATUS_ACTIVE)
37         self.ind.set_attention_icon("gpm-ups-000")
38
39         hosts = sys.argv[1:]
40
41         if len(hosts)==0:
42           hosts = {'localhost'}
43
44         self.upses=[]
45         for host in hosts : 
46           command = "upsc -l {0}".format(host)
47           try:
48             local_upses=exec_command(command)
49             for ups in local_upses:
50               self.upses.append('{0}@{1}'.format(ups,host))
51           except:
52             pass
53
54         if self.upses == []:
55           print "No connected ups'es found!\n"
56           sys.exit(1)
57           
58         self.menu_setup()
59         self.ind.set_menu(self.menu)
60
61         if not pynotify.init ("nut-indicator"):
62           self.disable_notify=1
63         else:
64           self.disable_notify=0
65
66         self.ups_dictionary = {}
67         self.ups_dictionary['battery charge'] = 'Battery charge %'
68         self.ups_dictionary['input voltage'] = 'Input voltage'
69         self.ups_dictionary['output voltage'] = 'Output voltage'
70         self.ups_dictionary['ups load'] = 'UPS load %'
71         self.ups_dictionary['ups status'] = 'UPS status'
72
73         self.ups_value_dictionary = {}
74         self.ups_value_dictionary['ups status'] = {}
75         self.ups_value_dictionary['ups status']['OL'] = {1,'online'}
76         self.ups_value_dictionary['ups status']['OB'] = {0,'on battery'}
77         self.ups_value_dictionary['ups status']['LB'] = {-1,'low batter'}
78
79     def menu_setup(self):
80         self.menu = gtk.Menu()
81
82         self.menuitems = {}
83         for ups in self.upses:
84           print ups;
85           menu_item = gtk.MenuItem(ups)
86           menu_item.connect("activate",self.call_check_local_ups,ups)
87           menu_item.show()
88           self.menu.append(menu_item)
89           self.menuitems[ups]=menu_item
90
91         separator = gtk.SeparatorMenuItem()
92         separator.show()
93         self.menu.append(separator)
94
95         self.quit_item = gtk.MenuItem("Quit")
96         self.quit_item.connect("activate", self.quit)
97         self.quit_item.show()
98         self.menu.append(self.quit_item)
99
100     def main(self):
101         self.check_ups()
102         gtk.timeout_add(PING_FREQUENCY * 1000, self.check_ups)
103         gtk.main()
104
105     def quit(self, widget):
106         sys.exit(0)
107
108     def call_check_local_ups(self,item,ups):
109         return self.check_local_ups(ups,1)
110
111     def check_local_ups(self,ups,notify):
112         command = "upsc {0}".format(ups)
113         res = exec_command(command)
114         status="?"
115         battery="?"
116         ups_status="?"
117         text=""
118         minstatus=1
119         for newline in res:
120           paramname,paramvalue = newline.split(': ',1)
121           paramname = paramname.replace('.',' ')
122           try:
123             status,paramvalue = self.ups_value_dictionary[paramname][paramvalue]
124             if status<minstatus:
125               status=minstatus
126           except:
127             pass
128           try:
129             printname = self.ups_dictionary[paramname]
130             text="{0}\n{1} = {2}".format(text,printname,paramvalue)
131           except:
132             pass
133             
134           if paramname=="battery charge":
135             battery=paramvalue
136           elif paramname=="ups status":
137             ups_status=paramvalue
138
139         if battery=='?':
140           self.menuitems[ups].get_child().set_text('{0}: {1}'.format(ups,ups_status))
141         else:
142           self.menuitems[ups].get_child().set_text('{0}: {1}, {2}%'.format(ups,ups_status,battery))
143         if (notify==1 or minstatus<0) and self.disable_notify==0:
144           n = pynotify.Notification(ups,text)
145           helper = gtk.Button()
146           icon = helper.render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG)
147           n.set_icon_from_pixbuf(icon)
148           n.show()
149         return minstatus
150
151     def check_ups(self):
152
153         min_status=1;
154
155         for ups in self.upses:
156           status=self.check_local_ups(ups,0)
157           if status<min_status:
158             min_status=status
159
160         if status < 0:
161             self.ind.set_status(appindicator.STATUS_ATTENTION)
162             self.ind.set_attention_icon("gpm-ups-000")
163         elif status==0:
164             self.ind.set_status(appindicator.STATUS_ATTENTION)
165             self.ind.set_attention_icon("gpm-ups-060")
166         else:
167             self.ind.set_status(appindicator.STATUS_ACTIVE)
168         return True
169
170 if __name__ == "__main__":
171     indicator = CheckNUT()
172     indicator.main()
173