How do I get the current power consumption in the status bar? (Developing a status icon)

Instead of counting monkeys :-), I modified the second script from L. D. James's answer to show the current power consumption of my laptop in watts.

enter image description here

The script works with Ubuntu 16.04 and probably the only system specific thing is the file where the value of the current power consumption is stored. In my case I found it by the help of tlp:

$ sudo tlp stat | grep -P '\[m(W|A)\]'    # Output on Lenovo ThinkPad X230 Tablet
/sys/class/power_supply/BAT0/power_now                      =  11246 [mW]

$ sudo tlp stat | grep -P '\[m(W|A)\]'    # Output on Dell Vostro 3350 Laptop
/sys/class/power_supply/BAT0/power_now                      =  6700 [mA]

Note some devices provide the current power consumption in watts, but some devices provide the current values of the voltage and the current (amps) - and the script covers these cases.

Further I created the GitHub Project PowerNow and added additional options: to execute htop, powertop or tlp stat within a gnome-terminal.

enter image description here

Installation of the Python script powerNow and optionally Startup Applications (and ~/Desktop) .desktop files:

  • Copy the script to /usr/local/bin to make it accessible as shell command system wide:

    sudo wget https://raw.githubusercontent.com/pa4080/powerNow/master/powerNow.py -O /usr/local/bin/powerNow
    sudo chmod +x /usr/local/bin/powerNow
    
  • Copy the script to ~/bin to make it accessible only for the current user:

    wget https://raw.githubusercontent.com/pa4080/powerNow/master/powerNow.py -O $HOME/bin/powerNow
    chmod +x $HOME/bin/powerNow
    
  • Copy the desktop file to ~/Desktop (the script is required):

    wget https://raw.githubusercontent.com/pa4080/powerNow/master/powerNow.desktop -O $HOME/Desktop/powerNow.desktop
    chmod +x $HOME/Desktop/powerNow.desktop
    
  • Copy the desktop file to ~/.config/autostart (the script is required):

    wget https://raw.githubusercontent.com/pa4080/powerNow/master/powerNow.desktop -O $HOME/.config/autostart/powerNow.desktop
    chmod +x $HOME/.config/autostart/powerNow.desktop
    

Ubuntu provides a set of libraries and examples for using them to for a migration of simple menus and a consistent interface.

The examples in the document linked above includes version is the following languages:

  • C
  • PYGI
  • PYGTK
  • C#
  • Vala
  • Haskell

A python` example from the page is:

#!/usr/bin/env python
#
# Copyright 2009-2012 Canonical Ltd.
#
# Authors: Neil Jagdish Patel <[email protected]>
#          Jono Bacon <[email protected]>
#          David Planella <[email protected]>
#
# This program is free software: you can redistribute it and/or modify it 
# under the terms of either or both of the following licenses:
#
# 1) the GNU Lesser General Public License version 3, as published by the 
# Free Software Foundation; and/or
# 2) the GNU Lesser General Public License version 2.1, as published by 
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but 
# WITHOUT ANY WARRANTY; without even the implied warranties of 
# MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the applicable version of the GNU Lesser General Public 
# License for more details.
#
# You should have received a copy of both the GNU Lesser General Public 
# License version 3 and version 2.1 along with this program.  If not, see 
# <http://www.gnu.org/licenses/>
#

from gi.repository import Gtk
from gi.repository import AppIndicator3 as appindicator


def menuitem_response(w, buf):
  print buf

if __name__ == "__main__":
  ind = appindicator.Indicator.new (
                        "example-simple-client",
                        "indicator-messages",
                        appindicator.IndicatorCategory.APPLICATION_STATUS)
  ind.set_status (appindicator.IndicatorStatus.ACTIVE)
  ind.set_attention_icon ("indicator-messages-new")

  # create a menu
  menu = Gtk.Menu()

  # create some 
  for i in range(3):
    buf = "Test-undermenu - %d" % i

    menu_items = Gtk.MenuItem(buf)

    menu.append(menu_items)

    # this is where you would connect your menu item up with a function:

    # menu_items.connect("activate", menuitem_response, buf)

    # show the items
    menu_items.show()

  ind.set_menu(menu)

  Gtk.main()

You could use a program from the list as a wrapper for your script so that clicking on the item will call your script.


Making Icon and text dynamic

(Taken from: How can I write a dynamically updated panel app / indicator?)

This example suggests using GObject. Call gobject.threads_init()an application initialization. Then launch your threads normally, but make sure the threads never do any GUI task directly. Instead, you use gobject.idle_add to schedule GUI task directly. (The above is an exact quote from the link included in case the link stops working.)

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread

class Indicator():
    def __init__(self):
        self.app = 'test123'
        iconpath = "/opt/abouttime/icon/indicator_icon.png"
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())
        self.indicator.set_label("1 Monkey", self.app)
        # the thread:
        self.update = Thread(target=self.show_seconds)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        menu = Gtk.Menu()
        # menu item 1
        item_1 = Gtk.MenuItem('Menu item')
        # item_about.connect('activate', self.about)
        menu.append(item_1)
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)

        menu.show_all()
        return menu

    def show_seconds(self):
        t = 2
        while True:
            time.sleep(1)
            mention = str(t)+" Monkeys"
            # apply the interface update using  GObject.idle_add()
            GObject.idle_add(
                self.indicator.set_label,
                mention, self.app,
                priority=GObject.PRIORITY_DEFAULT
                )
            t += 1

    def stop(self, source):
        Gtk.main_quit()

Indicator()
# this is where we call GObject.threads_init()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()