By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

 __init__.py

View raw Download
text/plain • 3.21 kiB
Python script, Unicode text, UTF-8 text executable
        
            
1
"""
2
D-Bus laptop battery monitor applet for the Panorama panel.
3
Copyright 2025, roundabout-host.com <vlad@roundabout-host.com>
4
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public Licence as published by
7
the Free Software Foundation, either version 3 of the Licence, or
8
(at your option) any later version.
9
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public Licence for more details.
14
15
You should have received a copy of the GNU General Public Licence
16
along with this program. If not, see <https://www.gnu.org/licenses/>.
17
"""
18
19
from __future__ import annotations
20
21
import panorama_panel
22
import locale
23
from pathlib import Path
24
from pydbus import SystemBus
25
26
import gi
27
gi.require_version("Gtk", "4.0")
28
29
from gi.repository import Gtk, Gdk, GLib
30
31
32
module_directory = Path(__file__).resolve().parent
33
34
locale.bindtextdomain("panorama-battery-monitor", module_directory / "locale")
35
_ = lambda x: locale.dgettext("panorama-battery-monitor", x)
36
37
38
def get_battery_icon(fraction, charging):
39
if fraction < 1/32:
40
base_icon = "battery-empty"
41
elif fraction < 1/16:
42
base_icon = "battery-caution"
43
elif fraction < 1/4:
44
base_icon = "battery-low"
45
elif fraction < 1/2:
46
base_icon = "battery-medium"
47
elif fraction < 7/8:
48
base_icon = "battery-good"
49
else:
50
base_icon = "battery-full"
51
52
if charging:
53
return base_icon + "-charging"
54
55
return base_icon
56
57
58
class BatteryMonitor(panorama_panel.Applet):
59
name = _("Laptop battery")
60
description = _("Check laptop battery charge")
61
62
def __init__(self, orientation=Gtk.Orientation.HORIZONTAL, config=None):
63
super().__init__(orientation=orientation, config=config)
64
if config is None:
65
config = {}
66
67
self.bus = SystemBus()
68
self.upower = self.bus.get("org.freedesktop.UPower")
69
70
self.button = Gtk.MenuButton()
71
self.icon = Gtk.Image(pixel_size=config.get("icon_size", 24))
72
self.button.set_child(self.icon)
73
self.append(self.button)
74
75
self.update_batteries()
76
GLib.timeout_add_seconds(10, self.update_batteries)
77
78
def update_batteries(self):
79
total_energy = max_energy = 0
80
any_charging = False
81
82
for device_path in self.upower.EnumerateDevices():
83
device = self.bus.get("org.freedesktop.UPower", device_path)
84
85
# Filter only batteries
86
if device.Type == 2:
87
# This is in Wh but we don't care
88
total_energy += device.Energy
89
max_energy += device.EnergyFull
90
91
if device.State == 1:
92
any_charging = True
93
94
print(total_energy, max_energy)
95
96
self.button.set_tooltip_text(f"{locale.format_string("%d", total_energy / max_energy * 1000)}‰")
97
98
self.icon.set_from_icon_name(get_battery_icon(total_energy / max_energy, any_charging))
99
100
return True
101
102
def get_config(self):
103
return {
104
"icon_size": self.icon.get_pixel_size(),
105
}
106
107
def shutdown(self, app):
108
self.publishing.unpublish()
109