From 24cda1d947cb91359363f6f7e38bb48ca13ddb52 Mon Sep 17 00:00:00 2001 From: Trevor Murphy Date: Wed, 8 May 2013 23:28:24 -0400 Subject: [PATCH] Add a battery info segment. Default colors range from red (full battery) to white (no battery) but can be changed via the `battery' and `battery_gradient' settings. Default presentation is a formatted percentage string (with keyword `batt'). The `gamify' setting changes this to a sequence of video game hearts. Number of steps from 100% to 0% / number of video game heart icons is controlled by the `steps' setting (default 5). --- powerline/config_files/colors.json | 4 ++ .../colorschemes/tmux/default.json | 4 +- powerline/segments/common.py | 51 +++++++++++++++++++ tests/test_segments.py | 36 +++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/powerline/config_files/colors.json b/powerline/config_files/colors.json index c64b74c9..5b8a7645 100644 --- a/powerline/config_files/colors.json +++ b/powerline/config_files/colors.json @@ -101,6 +101,10 @@ "blue_red": [ [39, 74, 68, 67, 103, 97, 96, 132, 131, 167, 203, 197], ["19b4fe", "1bb2fc", "1db1fa", "1faff8", "22aef6", "24adf4", "26abf2", "29aaf0", "2ba9ee", "2da7ec", "30a6ea", "32a5e8", "34a3e6", "36a2e4", "39a0e2", "3b9fe1", "3d9edf", "409cdd", "429bdb", "449ad9", "4798d7", "4997d5", "4b96d3", "4d94d1", "5093cf", "5292cd", "5490cb", "578fc9", "598dc7", "5b8cc6", "5e8bc4", "6089c2", "6288c0", "6487be", "6785bc", "6984ba", "6b83b8", "6e81b6", "7080b4", "727eb2", "757db0", "777cae", "797aac", "7b79ab", "7e78a9", "8076a7", "8275a5", "8574a3", "8772a1", "89719f", "8c709d", "8e6e9b", "906d99", "926b97", "956a95", "976993", "996791", "9c668f", "9e658e", "a0638c", "a3628a", "a56188", "a75f86", "a95e84", "ac5c82", "ae5b80", "b05a7e", "b3587c", "b5577a", "b75678", "ba5476", "bc5374", "be5273", "c05071", "c34f6f", "c54e6d", "c74c6b", "ca4b69", "cc4967", "ce4865", "d14763", "d34561", "d5445f", "d7435d", "da415b", "dc4059", "de3f58", "e13d56", "e33c54", "e53a52", "e83950", "ea384e", "ec364c", "ee354a", "f13448", "f33246", "f53144", "f83042", "fa2e40"] + ], + "white_red": [ + [231, 223, 216, 209, 196], + ["ffffff", "fffe61", "fffcc4", "fffb28", "fff98b", "fff7ef", "fff651", "fff4b4", "fff318", "fff17b", "ffefdf", "ffee41", "ffeca4", "ffeb08", "ffe96b", "ffe7cf", "ffe631", "ffe494", "ffe2f8", "ffe15b", "ffdfbf", "ffde21", "ffdc84", "ffdae8", "ffd94b", "ffd7af", "ffd602", "ffd455", "ffd2aa", "ffd0fd", "ffcf50", "ffcda5", "ffcbf8", "ffca4b", "ffc8a0", "ffc6f3", "ffc546", "ffc39b", "ffc1ee", "ffc041", "ffbe96", "ffbce9", "ffbb3c", "ffb991", "ffb7e4", "ffb637", "ffb48c", "ffb2df", "ffb132", "ffaf87", "ffadda", "ffac2d", "ffaa82", "ffa8d5", "ffa728", "ffa57d", "ffa3d0", "ffa223", "ffa078", "ff9ecb", "ff9d1e", "ff9b73", "ff99c6", "ff9819", "ff966e", "ff94c1", "ff9314", "ff9169", "ff8fbc", "ff8e0f", "ff8c64", "ff8ab7", "ff890a", "ff875f", "ff81f4", "ff7c8a", "ff771f", "ff71b5", "ff6c4c", "ff66e1", "ff6177", "ff5c0c", "ff56a2", "ff5139", "ff4bce", "ff4664", "ff40f9", "ff3b8f", "ff3626", "ff30bb", "ff2b51", "ff25e6", "ff207c", "ff1b13", "ff15a8", "ff103e", "ff0ad3", "ff0569", "ff0000"] ] } } diff --git a/powerline/config_files/colorschemes/tmux/default.json b/powerline/config_files/colorschemes/tmux/default.json index 35686d32..9d1933f9 100644 --- a/powerline/config_files/colorschemes/tmux/default.json +++ b/powerline/config_files/colorschemes/tmux/default.json @@ -19,6 +19,8 @@ "network_load": { "fg": "gray8", "bg": "gray0" }, "network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" }, "system_load": { "fg": "gray8", "bg": "gray0" }, - "system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" } + "system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" }, + "battery": { "fg": "gray8", "bg": "gray0" }, + "battery_gradient": { "fg": "white_red", "bg": "gray0" } } } diff --git a/powerline/segments/common.py b/powerline/segments/common.py index 094c2c1b..9fdc2205 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -1003,3 +1003,54 @@ class NowPlayingSegment(object): 'total': now_playing[4], } now_playing = NowPlayingSegment() + + +if os.path.exists('/sys/class/power_supply/BAT0/capacity'): + def _get_capacity(): + with open('/sys/class/power_supply/BAT0/capacity', 'r') as f: + return int(float(f.readline().split()[0])) +else: + def _get_capacity(): + raise NotImplementedError + + +def battery(pl, format='{batt:3.0%}', steps=5, gamify=False): + '''Return battery charge status. + + :param int steps: + number of discrete steps to show between 0% and 100% capacity + :param bool gamify: + measure in hearts (♥) instead of percentages + + Highlight groups used: ``battery_gradient`` (gradient), ``battery``. + ''' + try: + capacity = _get_capacity() + except NotImplementedError: + pl.warn('Unable to get battery capacity.') + return None + ret = [] + denom = int(steps) + numer = int(denom * capacity / 100) + full_heart = '♥' + if gamify: + ret.append({ + 'contents': full_heart * numer, + 'draw_soft_divider': False, + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 99 + }) + ret.append({ + 'contents': full_heart * (denom - numer), + 'draw_soft_divider': False, + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 1 + }) + else: + batt = numer / float(denom) + ret.append({ + 'contents': format.format(batt=batt), + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': batt * 100 + }) + return ret diff --git a/tests/test_segments.py b/tests/test_segments.py index befad178..dd028116 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -340,6 +340,42 @@ class TestCommon(TestCase): # TODO pass + def test_battery(self): + pl = Pl() + + def _get_capacity(): + return 86 + + with replace_attr(common, '_get_capacity', _get_capacity): + self.assertEqual(common.battery(pl=pl), [{ + 'contents': '80%', + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 80.0 + }]) + self.assertEqual(common.battery(pl=pl, format='{batt:.2f}'), [{ + 'contents': '0.80', + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 80.0 + }]) + self.assertEqual(common.battery(pl=pl, steps=7), [{ + 'contents': '86%', + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 85.71428571428571 + }]) + self.assertEqual(common.battery(pl=pl, gamify=True), [ + { + 'contents': '♥♥♥♥', + 'draw_soft_divider': False, + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 99 + }, + { + 'contents': '♥', + 'draw_soft_divider': False, + 'highlight_group': ['battery_gradient', 'battery'], + 'gradient_level': 1 + } + ]) class TestVim(TestCase): def test_mode(self):