From 85760926d7d1f7ddaed9e5096bd0e9ebb70c3267 Mon Sep 17 00:00:00 2001 From: siggi Date: Tue, 3 Oct 2023 22:28:28 +0200 Subject: [PATCH] Add Power-Profile module --- .../modules/contrib/power-profile.py | 99 +++++++++++++++++++ requirements/modules/power-profile.txt | 2 + tests/modules/contrib/test_power-profile.py | 32 ++++++ themes/icons/ascii.json | 3 + themes/icons/awesome-fonts.json | 3 + 5 files changed, 139 insertions(+) create mode 100644 bumblebee_status/modules/contrib/power-profile.py create mode 100644 requirements/modules/power-profile.txt create mode 100644 tests/modules/contrib/test_power-profile.py diff --git a/bumblebee_status/modules/contrib/power-profile.py b/bumblebee_status/modules/contrib/power-profile.py new file mode 100644 index 0000000..2959391 --- /dev/null +++ b/bumblebee_status/modules/contrib/power-profile.py @@ -0,0 +1,99 @@ +# pylint: disable=C0111,R0903 +""" +Displays the current Power-Profile active + + +Left-Click or Right-Click as well as Scrolling up / down changes the active Power-Profile + +Prerequisites: + * dbus-python + * power-profiles-daemon +""" + +import dbus +import core.module +import core.widget +import core.input + + +class PowerProfileManager: + def __init__(self): + self.POWER_PROFILES_NAME = "net.hadess.PowerProfiles" + self.POWER_PROFILES_PATH = "/net/hadess/PowerProfiles" + self.PP_PROPERTIES_CURRENT_POWER_PROFILE = "ActiveProfile" + self.PP_PROPERTIES_ALL_POWER_PROFILES = "Profiles" + + self.DBUS_PROPERTIES = "org.freedesktop.DBus.Properties" + bus = dbus.SystemBus() + pp_proxy = bus.get_object(self.POWER_PROFILES_NAME, self.POWER_PROFILES_PATH) + self.pp_interface = dbus.Interface(pp_proxy, self.DBUS_PROPERTIES) + + def get_current_power_profile(self): + return self.pp_interface.Get( + self.POWER_PROFILES_NAME, self.PP_PROPERTIES_CURRENT_POWER_PROFILE + ) + + def __get_all_power_profile_names(self): + power_profiles = self.pp_interface.Get( + self.POWER_PROFILES_NAME, self.PP_PROPERTIES_ALL_POWER_PROFILES + ) + power_profiles_names = [] + for pp in power_profiles: + power_profiles_names.append(pp["Profile"]) + + return power_profiles_names + + def next_power_profile(self, event): + all_pp_names = self.__get_all_power_profile_names() + current_pp_index = self.__get_current_pp_index() + next_index = 0 + if current_pp_index != (len(all_pp_names) - 1): + next_index = current_pp_index + 1 + + self.pp_interface.Set( + self.POWER_PROFILES_NAME, + self.PP_PROPERTIES_CURRENT_POWER_PROFILE, + all_pp_names[next_index], + ) + + def prev_power_profile(self, event): + all_pp_names = self.__get_all_power_profile_names() + current_pp_index = self.__get_current_pp_index() + last_index = len(all_pp_names) - 1 + if current_pp_index is not 0: + last_index = current_pp_index - 1 + + self.pp_interface.Set( + self.POWER_PROFILES_NAME, + self.PP_PROPERTIES_CURRENT_POWER_PROFILE, + all_pp_names[last_index], + ) + + def __get_current_pp_index(self): + all_pp_names = self.__get_all_power_profile_names() + current_pp = self.get_current_power_profile() + return all_pp_names.index(current_pp) + + +class Module(core.module.Module): + def __init__(self, config, theme): + super().__init__(config, theme, core.widget.Widget(self.full_text)) + self.pp_manager = PowerProfileManager() + core.input.register( + self, button=core.input.WHEEL_UP, cmd=self.pp_manager.next_power_profile + ) + core.input.register( + self, button=core.input.WHEEL_DOWN, cmd=self.pp_manager.prev_power_profile + ) + core.input.register( + self, button=core.input.LEFT_MOUSE, cmd=self.pp_manager.next_power_profile + ) + core.input.register( + self, button=core.input.RIGHT_MOUSE, cmd=self.pp_manager.prev_power_profile + ) + + def full_text(self, widgets): + return self.pp_manager.get_current_power_profile() + + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/requirements/modules/power-profile.txt b/requirements/modules/power-profile.txt new file mode 100644 index 0000000..8f7d255 --- /dev/null +++ b/requirements/modules/power-profile.txt @@ -0,0 +1,2 @@ +dbus-python +power-profiles-daemon \ No newline at end of file diff --git a/tests/modules/contrib/test_power-profile.py b/tests/modules/contrib/test_power-profile.py new file mode 100644 index 0000000..43cb14f --- /dev/null +++ b/tests/modules/contrib/test_power-profile.py @@ -0,0 +1,32 @@ +from unittest.mock import patch, MagicMock +import unittest +import pytest + +import core.config +import modules.contrib.power_profile + +pytest.importorskip("dbus") + + +def build_powerprofile_module(): + config = core.config.Config([]) + return modules.contrib.power_profile.Module(config=config, theme=None) + + +class TestPowerProfileUnit(unittest.TestCase): + def __get_mock_dbus_get_method(self, mock_system_bus): + return ( + mock_system_bus.return_value.get_object.return_value.get_dbus_method.return_value + ) + + def test_load_module(self): + __import__("modules.contrib.power-profile") + + @patch("dbus.SystemBus") + def test_full_text(self, mock_system_bus): + mock_get = self.__get_mock_dbus_get_method(mock_system_bus) + mock_get.return_value = "balanced" + + module = build_powerprofile_module() + module.update() + assert module.widgets()[0].full_text() == "balanced" diff --git a/themes/icons/ascii.json b/themes/icons/ascii.json index d353386..4f48e4d 100644 --- a/themes/icons/ascii.json +++ b/themes/icons/ascii.json @@ -410,5 +410,8 @@ "speedtest": { "running": { "prefix": [".", "..", "...", ".."] }, "not-running": { "prefix": "[start]" } + }, + "power-profile": { + "prefix": "profile" } } diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index 60f8f51..7b86cb8 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -739,5 +739,8 @@ }, "thunderbird": { "prefix": "" + }, + "power-profile": { + "prefix": "\uF2C1" } }