Add ac-charging indication for battery segment
This commit is contained in:
parent
090cd1397c
commit
f098ed2fe0
|
@ -51,7 +51,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "O",
|
"full_heart": "O",
|
||||||
"empty_heart": "O"
|
"empty_heart": "O",
|
||||||
|
"online": "C",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "♥",
|
"full_heart": "♥",
|
||||||
"empty_heart": "♥"
|
"empty_heart": "♥",
|
||||||
|
"online": "⚡︎",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "💙",
|
"full_heart": "💙",
|
||||||
"empty_heart": "💛"
|
"empty_heart": "💛",
|
||||||
|
"online": "⚡️",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "♥",
|
"full_heart": "♥",
|
||||||
"empty_heart": "♥"
|
"empty_heart": "♥",
|
||||||
|
"online": "⚡︎",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "♥",
|
"full_heart": "♥",
|
||||||
"empty_heart": "♥"
|
"empty_heart": "♥",
|
||||||
|
"online": "⚡︎",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -51,7 +51,9 @@
|
||||||
"powerline.segments.common.bat.battery": {
|
"powerline.segments.common.bat.battery": {
|
||||||
"args": {
|
"args": {
|
||||||
"full_heart": "♥",
|
"full_heart": "♥",
|
||||||
"empty_heart": "♥"
|
"empty_heart": "♥",
|
||||||
|
"online": "⚡︎",
|
||||||
|
"offline": " "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"powerline.segments.common.sys.uptime": {
|
"powerline.segments.common.sys.uptime": {
|
||||||
|
|
|
@ -12,7 +12,7 @@ from powerline.lib.shell import run_cmd
|
||||||
# segment is imported into powerline.segments.common module.
|
# segment is imported into powerline.segments.common module.
|
||||||
|
|
||||||
|
|
||||||
def _get_battery(pl):
|
def _fetch_battery_info(pl):
|
||||||
try:
|
try:
|
||||||
import dbus
|
import dbus
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -55,23 +55,31 @@ def _get_battery(pl):
|
||||||
dbus.Interface(dev, dbus_interface=devinterface).Get(
|
dbus.Interface(dev, dbus_interface=devinterface).Get(
|
||||||
devtype_name,
|
devtype_name,
|
||||||
'Percentage'
|
'Percentage'
|
||||||
)
|
),
|
||||||
|
dbus.Interface(dev, dbus_interface=devinterface).Get(
|
||||||
|
devtype_name,
|
||||||
|
'State'
|
||||||
|
) == 1
|
||||||
)
|
)
|
||||||
pl.debug('Not using DBUS+UPower as no batteries were found')
|
pl.debug('Not using DBUS+UPower as no batteries were found')
|
||||||
|
|
||||||
if os.path.isdir('/sys/class/power_supply'):
|
if os.path.isdir('/sys/class/power_supply'):
|
||||||
linux_bat_fmt = '/sys/class/power_supply/{0}/capacity'
|
linux_bat_fmt = '/sys/class/power_supply/{0}/capacity'
|
||||||
|
linux_ac_fmt = '/sys/class/power_supply/{0}/online'
|
||||||
for linux_bat in os.listdir('/sys/class/power_supply'):
|
for linux_bat in os.listdir('/sys/class/power_supply'):
|
||||||
cap_path = linux_bat_fmt.format(linux_bat)
|
cap_path = linux_bat_fmt.format(linux_bat)
|
||||||
|
online_path = linux_ac_fmt.format(linux_bat)
|
||||||
if linux_bat.startswith('BAT') and os.path.exists(cap_path):
|
if linux_bat.startswith('BAT') and os.path.exists(cap_path):
|
||||||
pl.debug('Using /sys/class/power_supply with battery {0}', linux_bat)
|
pl.debug('Using /sys/class/power_supply with battery {0}', linux_bat)
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
with open(cap_path, 'r') as f:
|
with open(cap_path, 'r') as f:
|
||||||
return int(float(f.readline().split()[0]))
|
_capacity = int(float(f.readline().split()[0]))
|
||||||
|
with open(online_path, 'r') as f:
|
||||||
return _get_capacity
|
_ac_powered = f.readline() == 1
|
||||||
pl.debug('Not using /sys/class/power_supply as no batteries were found')
|
return _capacity, _ac_powered
|
||||||
|
return _get_battery_status
|
||||||
|
pl.debug('Not using /sys/class/power_supply as no batteries were found')
|
||||||
else:
|
else:
|
||||||
pl.debug('Not using /sys/class/power_supply: no directory')
|
pl.debug('Not using /sys/class/power_supply: no directory')
|
||||||
|
|
||||||
|
@ -86,12 +94,12 @@ def _get_battery(pl):
|
||||||
|
|
||||||
BATTERY_PERCENT_RE = re.compile(r'(\d+)%')
|
BATTERY_PERCENT_RE = re.compile(r'(\d+)%')
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
battery_summary = run_cmd(pl, ['pmset', '-g', 'batt'])
|
battery_summary = run_cmd(pl, ['pmset', '-g', 'batt'])
|
||||||
battery_percent = BATTERY_PERCENT_RE.search(battery_summary).group(1)
|
battery_percent = BATTERY_PERCENT_RE.search(battery_summary).group(1)
|
||||||
return int(battery_percent)
|
ac_charging = 'AC' in battery_summary
|
||||||
|
return int(battery_percent), ac_charging
|
||||||
return _get_capacity
|
return _get_battery_status
|
||||||
else:
|
else:
|
||||||
pl.debug('Not using pmset: executable not found')
|
pl.debug('Not using pmset: executable not found')
|
||||||
|
|
||||||
|
@ -110,11 +118,11 @@ def _get_battery(pl):
|
||||||
for battery in wmi.InstancesOf('Win32_Battery'):
|
for battery in wmi.InstancesOf('Win32_Battery'):
|
||||||
pl.debug('Using win32com.client with Win32_Battery')
|
pl.debug('Using win32com.client with Win32_Battery')
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
# http://msdn.microsoft.com/en-us/library/aa394074(v=vs.85).aspx
|
# http://msdn.microsoft.com/en-us/library/aa394074(v=vs.85).aspx
|
||||||
return battery.EstimatedChargeRemaining
|
return battery.EstimatedChargeRemaining, battery.BatteryStatus == 6
|
||||||
|
|
||||||
return _get_capacity
|
return _get_battery_status
|
||||||
pl.debug('Not using win32com.client as no batteries were found')
|
pl.debug('Not using win32com.client as no batteries were found')
|
||||||
from ctypes import Structure, c_byte, c_ulong, byref
|
from ctypes import Structure, c_byte, c_ulong, byref
|
||||||
if sys.platform == 'cygwin':
|
if sys.platform == 'cygwin':
|
||||||
|
@ -136,41 +144,41 @@ def _get_battery(pl):
|
||||||
('BatteryFullLifeTime', c_ulong)
|
('BatteryFullLifeTime', c_ulong)
|
||||||
]
|
]
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
powerclass = PowerClass()
|
powerclass = PowerClass()
|
||||||
result = library_loader.kernel32.GetSystemPowerStatus(byref(powerclass))
|
result = library_loader.kernel32.GetSystemPowerStatus(byref(powerclass))
|
||||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx
|
||||||
if result:
|
if result:
|
||||||
return None
|
return None
|
||||||
return powerclass.BatteryLifePercent
|
return powerclass.BatteryLifePercent, powerclass.ACLineStatus == 1
|
||||||
|
|
||||||
if _get_capacity() is None:
|
if _get_battery_status() is None:
|
||||||
pl.debug('Not using GetSystemPowerStatus because it failed')
|
pl.debug('Not using GetSystemPowerStatus because it failed')
|
||||||
else:
|
else:
|
||||||
pl.debug('Using GetSystemPowerStatus')
|
pl.debug('Using GetSystemPowerStatus')
|
||||||
|
|
||||||
return _get_capacity
|
return _get_battery_status
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
global _get_capacity
|
global _get_battery_status
|
||||||
|
|
||||||
def _failing_get_capacity(pl):
|
def _failing_get_status(pl):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_get_capacity = _get_battery(pl)
|
_get_battery_status = _fetch_battery_info(pl)
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
_get_capacity = _failing_get_capacity
|
_get_battery_status = _failing_get_status
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pl.exception('Exception while obtaining battery capacity getter: {0}', str(e))
|
pl.exception('Exception while obtaining battery status: {0}', str(e))
|
||||||
_get_capacity = _failing_get_capacity
|
_get_battery_status = _failing_get_status
|
||||||
return _get_capacity(pl)
|
return _get_battery_status(pl)
|
||||||
|
|
||||||
|
|
||||||
def battery(pl, format='{capacity:3.0%}', steps=5, gamify=False, full_heart='O', empty_heart='O'):
|
def battery(pl, format='{ac_state} {capacity:3.0%}', steps=5, gamify=False, full_heart='O', empty_heart='O', online='C', offline=' '):
|
||||||
'''Return battery charge status.
|
'''Return battery charge status.
|
||||||
|
|
||||||
:param str format:
|
:param str format:
|
||||||
|
@ -189,21 +197,32 @@ def battery(pl, format='{capacity:3.0%}', steps=5, gamify=False, full_heart='O',
|
||||||
another gradient level and highlighting group, so it is OK for it to be
|
another gradient level and highlighting group, so it is OK for it to be
|
||||||
the same as full_heart as long as necessary highlighting groups are
|
the same as full_heart as long as necessary highlighting groups are
|
||||||
defined.
|
defined.
|
||||||
|
:param str online:
|
||||||
|
If computer is connected to a power supply this symbol is prepended to the segment.
|
||||||
|
:param str offline:
|
||||||
|
If computer is NOT connected to a power supply this symbol is prepended to the segment.
|
||||||
|
|
||||||
``battery_gradient`` and ``battery`` groups are used in any case, first is
|
``battery_gradient`` and ``battery`` groups are used in any case, first is
|
||||||
preferred.
|
preferred.
|
||||||
|
|
||||||
Highlight groups used: ``battery_full`` or ``battery_gradient`` (gradient) or ``battery``, ``battery_empty`` or ``battery_gradient`` (gradient) or ``battery``.
|
Highlight groups used: ``battery_full`` or ``battery_gradient`` (gradient) or ``battery``, ``battery_empty`` or ``battery_gradient`` (gradient) or ``battery``, ``battery_online`` or ``battery_ac_state`` or ``battery_gradient`` (gradient) or ``battery``, ``battery_offline`` or ``battery_ac_state`` or ``battery_gradient`` (gradient) or ``battery``.
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
capacity = _get_capacity(pl)
|
capacity, ac_powered = _get_battery_status(pl)
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
pl.info('Unable to get battery capacity.')
|
pl.info('Unable to get battery status.')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
if gamify:
|
if gamify:
|
||||||
denom = int(steps)
|
denom = int(steps)
|
||||||
numer = int(denom * capacity / 100)
|
numer = int(denom * capacity / 100)
|
||||||
|
ret.append({
|
||||||
|
'contents': online if ac_powered else offline,
|
||||||
|
'draw_inner_divider': False,
|
||||||
|
'highlight_groups': ['battery_online' if ac_powered else 'battery_offline', 'battery_ac_state', 'battery_gradient', 'battery'],
|
||||||
|
'gradient_level': 0,
|
||||||
|
})
|
||||||
ret.append({
|
ret.append({
|
||||||
'contents': full_heart * numer,
|
'contents': full_heart * numer,
|
||||||
'draw_inner_divider': False,
|
'draw_inner_divider': False,
|
||||||
|
@ -220,7 +239,7 @@ def battery(pl, format='{capacity:3.0%}', steps=5, gamify=False, full_heart='O',
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
ret.append({
|
ret.append({
|
||||||
'contents': format.format(capacity=(capacity / 100.0)),
|
'contents': format.format(ac_state=(online if ac_powered else offline), capacity=(capacity / 100.0)),
|
||||||
'highlight_groups': ['battery_gradient', 'battery'],
|
'highlight_groups': ['battery_gradient', 'battery'],
|
||||||
# Gradients are “least alert – most alert” by default, capacity has
|
# Gradients are “least alert – most alert” by default, capacity has
|
||||||
# the opposite semantics.
|
# the opposite semantics.
|
||||||
|
|
|
@ -881,12 +881,12 @@ class TestBat(TestCommon):
|
||||||
def test_battery(self):
|
def test_battery(self):
|
||||||
pl = Pl()
|
pl = Pl()
|
||||||
|
|
||||||
def _get_capacity(pl):
|
def _get_battery_status(pl):
|
||||||
return 86
|
return 86, False
|
||||||
|
|
||||||
with replace_attr(self.module, '_get_capacity', _get_capacity):
|
with replace_attr(self.module, '_get_battery_status', _get_battery_status):
|
||||||
self.assertEqual(self.module.battery(pl=pl), [{
|
self.assertEqual(self.module.battery(pl=pl), [{
|
||||||
'contents': '86%',
|
'contents': ' 86%',
|
||||||
'highlight_groups': ['battery_gradient', 'battery'],
|
'highlight_groups': ['battery_gradient', 'battery'],
|
||||||
'gradient_level': 14,
|
'gradient_level': 14,
|
||||||
}])
|
}])
|
||||||
|
@ -896,11 +896,17 @@ class TestBat(TestCommon):
|
||||||
'gradient_level': 14,
|
'gradient_level': 14,
|
||||||
}])
|
}])
|
||||||
self.assertEqual(self.module.battery(pl=pl, steps=7), [{
|
self.assertEqual(self.module.battery(pl=pl, steps=7), [{
|
||||||
'contents': '86%',
|
'contents': ' 86%',
|
||||||
'highlight_groups': ['battery_gradient', 'battery'],
|
'highlight_groups': ['battery_gradient', 'battery'],
|
||||||
'gradient_level': 14,
|
'gradient_level': 14,
|
||||||
}])
|
}])
|
||||||
self.assertEqual(self.module.battery(pl=pl, gamify=True), [
|
self.assertEqual(self.module.battery(pl=pl, gamify=True), [
|
||||||
|
{
|
||||||
|
'contents': ' ',
|
||||||
|
'draw_inner_divider': False,
|
||||||
|
'highlight_groups': ['battery_offline', 'battery_ac_state', 'battery_gradient', 'battery'],
|
||||||
|
'gradient_level': 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'contents': 'OOOO',
|
'contents': 'OOOO',
|
||||||
'draw_inner_divider': False,
|
'draw_inner_divider': False,
|
||||||
|
@ -915,6 +921,12 @@ class TestBat(TestCommon):
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assertEqual(self.module.battery(pl=pl, gamify=True, full_heart='+', empty_heart='-', steps='10'), [
|
self.assertEqual(self.module.battery(pl=pl, gamify=True, full_heart='+', empty_heart='-', steps='10'), [
|
||||||
|
{
|
||||||
|
'contents': ' ',
|
||||||
|
'draw_inner_divider': False,
|
||||||
|
'highlight_groups': ['battery_offline', 'battery_ac_state', 'battery_gradient', 'battery'],
|
||||||
|
'gradient_level': 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'contents': '++++++++',
|
'contents': '++++++++',
|
||||||
'draw_inner_divider': False,
|
'draw_inner_divider': False,
|
||||||
|
@ -929,6 +941,34 @@ class TestBat(TestCommon):
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_battery_with_ac_online(self):
|
||||||
|
pl = Pl()
|
||||||
|
|
||||||
|
def _get_battery_status(pl):
|
||||||
|
return 86, True
|
||||||
|
|
||||||
|
with replace_attr(self.module, '_get_battery_status', _get_battery_status):
|
||||||
|
self.assertEqual(self.module.battery(pl=pl, online='C', offline=' '), [
|
||||||
|
{
|
||||||
|
'contents': 'C 86%',
|
||||||
|
'highlight_groups': ['battery_gradient', 'battery'],
|
||||||
|
'gradient_level': 14,
|
||||||
|
}])
|
||||||
|
|
||||||
|
def test_battery_with_ac_offline(self):
|
||||||
|
pl = Pl()
|
||||||
|
|
||||||
|
def _get_battery_status(pl):
|
||||||
|
return 86, False
|
||||||
|
|
||||||
|
with replace_attr(self.module, '_get_battery_status', _get_battery_status):
|
||||||
|
self.assertEqual(self.module.battery(pl=pl, online='C', offline=' '), [
|
||||||
|
{
|
||||||
|
'contents': ' 86%',
|
||||||
|
'highlight_groups': ['battery_gradient', 'battery'],
|
||||||
|
'gradient_level': 14,
|
||||||
|
}])
|
||||||
|
|
||||||
|
|
||||||
class TestVim(TestCase):
|
class TestVim(TestCase):
|
||||||
def test_mode(self):
|
def test_mode(self):
|
||||||
|
|
Loading…
Reference in New Issue