我很想知道我的笔记本一直消耗多少电量。
因此,我想要一个指示器,可以持续(可能间隔 1 秒)监控当前功耗(以 mA 为单位测量的电流或以 W 为单位测量的电力),并将其显示在我的 Ubuntu 16.04 的 Unity 面板中。
答案1
笔记: 目前,无法通过软件方式测量交流适配器上的笔记本电脑或台式电脑的功耗。即使是其他操作系统(如 Windows),也需要外部硬件传感器来提供该信息。如果您想要台式电脑的指示器,这个答案对您不起作用
我编写了一个指示器,用于监测瓦特和毫安培的能耗。使用方法非常简单:
python /path/to/power-flow-indicator
或者从与脚本相同的目录:
./power-flow-indicator
默认情况下,输出以瓦特显示,但--amps
选项允许以毫安显示输出:
python power-flow-indicator --amps
将-h
显示相同的信息:
usage: power-flow-indicator [-h] [--amps]
optional arguments:
-h, --help show this help message and exit
--amps display output in milliamps
获取指标
指标源代码位于GitHub. 如果您已经git
安装了,您可以通过以下方式克隆存储库:
git clone https://github.com/SergKolo/power-flow-indicator.git
或者,可以通过以下方式获取 zip 文件
wget https://github.com/SergKolo/power-flow-indicator/archive/master.zip
源代码
笔记:该指标需要图标。最好克隆 git 仓库或获取 zip 包,而不是单独复制源代码。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author: Serg Kolo , contact: [email protected]
# Date: July 21, 2012
# Purpose: Indicator that displays power
# consumption of laptop battery
#
# Written for: http://askubuntu.com/q/801003/295286
# Tested on: Ubuntu 16.04 LTS
#
#
#
# Licensed under The MIT License (MIT).
# See included LICENSE file or the notice below.
#
# Copyright © 2016 Sergiy Kolodyazhnyy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import gi
gi.require_version('AppIndicator3', '0.1')
from gi.repository import GLib as glib
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Gtk as gtk
import os
import dbus
import subprocess
import argparse
class LockKeyStatusIndicator(object):
def __init__(self, show_amps):
self.show_amps = show_amps
self.app = appindicator.Indicator.new(
'power-flow-indicator', "",
appindicator.IndicatorCategory.APPLICATION_STATUS)
self.app.set_status(appindicator.IndicatorStatus.ACTIVE)
self.icon_path = os.path.dirname( os.path.realpath(__file__) )
self.app.set_icon( os.path.join(self.icon_path,"pwi_icon.png" ))
self.update_label()
self.app_menu = gtk.Menu()
self.quit_app = gtk.MenuItem('Quit')
self.quit_app.connect('activate', self.quit)
self.quit_app.show()
self.app_menu.append(self.quit_app)
self.app.set_menu(self.app_menu)
def run(self):
try:
gtk.main()
except KeyboardInterrupt:
pass
def quit(self, data=None):
gtk.main_quit()
def run_cmd(self, cmdlist):
new_env = dict( os.environ )
new_env['LC_ALL'] = 'C'
try:
stdout = subprocess.check_output(cmdlist,env=new_env)
except subprocess.CalledProcessError:
pass
else:
if stdout:
return stdout
def run_dbus_method(self, bus_type, obj, path, interface, method, arg):
if bus_type == "session":
bus = dbus.SessionBus()
if bus_type == "system":
bus = dbus.SystemBus()
proxy = bus.get_object(obj, path)
method = proxy.get_dbus_method(method, interface)
if arg:
return method(arg)
else:
return method()
def get_power_info(self):
battery_path = None
battery_info = []
energy_rate = None
voltage = None
current = None
on_battery = None
for line in self.run_cmd(['upower', '-e']).decode().split('\n'):
if 'battery_BAT' in line:
battery_path = line
break
self.run_dbus_method('system', 'org.freedesktop.UPower',
battery_path, 'org.freedesktop.UPower.Device',
'Refresh', 'None')
for entry in self.run_cmd(
['upower', '-i', battery_path]).decode().split('\n'):
if 'state' in entry:
if entry.replace(" ", "").split(':')[1] == 'discharging':
on_battery = True
if 'energy-rate' in entry:
energy_rate = entry.replace(" ", "").split(':')[1][:-1]
print energy_rate
if 'voltage' in entry:
voltage = entry.replace(" ", "").split(':')[1]
current = round(
1000 * float(energy_rate[:-1]) / float(voltage[:-1]), 4)
if on_battery:
return str(round(float(energy_rate),2)) + 'W', str(int(current)) + 'mA'
else:
return 'on ac', 'on ac'
def update_label(self):
cwd = os.getcwd()
red_icon = os.path.join(cwd, 'red.png')
green_icon = os.path.join(cwd, 'green.png')
if self.show_amps:
label_text = self.get_power_info()[1]
else:
label_text = self.get_power_info()[0]
self.app.set_label(label_text, "")
glib.timeout_add_seconds(1, self.set_app_label)
def set_app_label(self):
self.update_label()
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--amps", help="display output in milliamps", action="store_true")
args = parser.parse_args()
indicator = LockKeyStatusIndicator(args.amps)
indicator.run()
if __name__ == '__main__':
main()