Skip to content

Instantly share code, notes, and snippets.

@markizano
Last active July 6, 2017 18:20
Show Gist options
  • Save markizano/af61b42f17be2d0261c6d54acc4d53e8 to your computer and use it in GitHub Desktop.
Save markizano/af61b42f17be2d0261c6d54acc4d53e8 to your computer and use it in GitHub Desktop.
System Tray Icon Widget.
#!/usr/bin/env python2.7
# Depends on oxygen-icon-theme. Change /usr/share/icons/oxygen to your desired theme.
import code
import gtk
import gobject
import threading
import time
import os, sys
import signal
DEBUG = os.environ.get('DEBUG', False)
ALERT_WAIT = 300 # Number of seconds to wait before alerting for low battery again.
ALERT_THRESHOLD = 10 # Percent at which this applet should alert for low battery.
BATTERY_ERROR = '/usr/share/icons/oxygen/32x32/status/battery-missing.png'
BATTERY10 = '/usr/share/icons/oxygen/32x32/status/battery-low.png'
BATTERY20 = '/usr/share/icons/oxygen/32x32/status/battery-caution.png'
BATTERY40 = '/usr/share/icons/oxygen/32x32/status/battery-040.png'
BATTERY60 = '/usr/share/icons/oxygen/32x32/status/battery-060.png'
BATTERY80 = '/usr/share/icons/oxygen/32x32/status/battery-080.png'
BATTERY100 = '/usr/share/icons/oxygen/32x32/status/battery-100.png'
BATTERY_CHARGING10 = '/usr/share/icons/oxygen/32x32/status/battery-charging-low.png'
BATTERY_CHARGING20 = '/usr/share/icons/oxygen/32x32/status/battery-charging-caution.png'
BATTERY_CHARGING40 = '/usr/share/icons/oxygen/32x32/status/battery-charging-040.png'
BATTERY_CHARGING60 = '/usr/share/icons/oxygen/32x32/status/battery-charging-060.png'
BATTERY_CHARGING80 = '/usr/share/icons/oxygen/32x32/status/battery-charging-080.png'
BATTERY_CHARGING100 = '/usr/share/icons/oxygen/32x32/status/battery-charging.png'
def message(data=None):
"Function to display messages to the user."
msg=gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, data)
msg.run()
msg.destroy()
Main.alerting = False
def get_battery_info():
'''
Checks /sys for battery info and returns as a data structure.
'''
result = {}
with open('/sys/class/power_supply/BAT0/uevent') as fd:
for line in fd:
try:
name, value = line.strip().split('=')
except ValueError:
name = line.strip().split('=').pop()
value = None
result[name.replace('POWER_SUPPLY_', '')] = value
return result
def update_icon():
'''
Checks the battery and upates the icon as necessary.
Alerts me if needed.
'''
battery = get_battery_info()
energy_now = int(battery['ENERGY_NOW'])
energy_full = int(battery['ENERGY_FULL'])
charging = battery['STATUS'] != 'Discharging'
energy_pcent = int( float(energy_now) / float(energy_full) * 100.0 )
if energy_pcent < ALERT_THRESHOLD:
if not Main.alerting:
if Main.alerted <= time.time() - ALERT_WAIT:
Main.alerting = True
Main.alerted = time.time()
message('Battery under %d!!!' % ALERT_THRESHOLD)
if charging:
BATTERY_OPTIONS = dict(
[ (x, BATTERY_CHARGING100) for x in range(81, 101) ]
+ [ (x, BATTERY_CHARGING80) for x in range(61, 80) ]
+ [ (x, BATTERY_CHARGING60) for x in range(41, 60) ]
+ [ (x, BATTERY_CHARGING40) for x in range(21, 40) ]
+ [ (x, BATTERY_CHARGING20) for x in range(11, 20) ]
+ [ (x, BATTERY_CHARGING10) for x in range(0, 10) ]
)
else:
BATTERY_OPTIONS = dict(
[ (x, BATTERY100) for x in range(81, 101) ]
+ [ (x, BATTERY80) for x in range(61, 80) ]
+ [ (x, BATTERY60) for x in range(41, 60) ]
+ [ (x, BATTERY40) for x in range(21, 40) ]
+ [ (x, BATTERY20) for x in range(11, 20) ]
+ [ (x, BATTERY10) for x in range(0, 10) ]
)
BATTERY_ICON = BATTERY_OPTIONS.get(int(energy_pcent), BATTERY_ERROR)
Main.icon.set_from_file(BATTERY_ICON)
return True
class Main(object):
icon = None
alerting = False
alerted = 0
@staticmethod
def sigint(sig=None):
sys.exit(127)
@staticmethod
def sigterm(sig=None):
sys.exit(128)
@staticmethod
def main():
signal.signal(2, Main.sigint)
signal.signal(15, Main.sigterm)
Main.icon = gtk.status_icon_new_from_file(BATTERY_ERROR)
update_icon()
gobject.timeout_add(1000, update_icon)
gtk.main()
return 0
if __name__ == '__main__':
try:
sys.exit(Main.main())
except KeyboardInterrupt:
sys.exit(126)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment