fix battery usage
This commit is contained in:
@@ -15,10 +15,8 @@ from fabric.river.widgets import (
|
|||||||
RiverActiveWindow,
|
RiverActiveWindow,
|
||||||
get_river_connection,
|
get_river_connection,
|
||||||
)
|
)
|
||||||
from fabric.utils import (
|
|
||||||
invoke_repeater,
|
|
||||||
)
|
|
||||||
from fabric.widgets.circularprogressbar import CircularProgressBar
|
from fabric.widgets.circularprogressbar import CircularProgressBar
|
||||||
|
from bar.services.system_stats import SystemStatsService
|
||||||
|
|
||||||
from bar.config import VINYL, BATTERY, BAR_HEIGHT, WINDOW_TITLE
|
from bar.config import VINYL, BATTERY, BAR_HEIGHT, WINDOW_TITLE
|
||||||
|
|
||||||
@@ -134,14 +132,16 @@ class StatusBar(Window):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
invoke_repeater(1000, self.update_progress_bars)
|
# Create system stats service with signal-based updates
|
||||||
|
self.system_stats_service = SystemStatsService(update_interval=3000)
|
||||||
|
self.system_stats_service.connect("stats-changed", self.update_progress_bars)
|
||||||
|
|
||||||
# Set the bar height
|
# Set the bar height
|
||||||
self.set_size_request(-1, BAR_HEIGHT)
|
self.set_size_request(-1, BAR_HEIGHT)
|
||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
def update_progress_bars(self):
|
def update_progress_bars(self, service, cpu_percent, memory_percent):
|
||||||
self.ram_progress_bar.value = psutil.virtual_memory().percent / 100
|
"""Update progress bars when system stats change"""
|
||||||
self.cpu_progress_bar.value = psutil.cpu_percent() / 100
|
self.cpu_progress_bar.value = cpu_percent
|
||||||
return True
|
self.ram_progress_bar.value = memory_percent
|
||||||
|
|||||||
@@ -1,38 +1,13 @@
|
|||||||
import psutil
|
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
from fabric.widgets.box import Box
|
from fabric.widgets.box import Box
|
||||||
from fabric.widgets.label import Label
|
from fabric.widgets.label import Label
|
||||||
from fabric.widgets.image import Image
|
from fabric.widgets.image import Image
|
||||||
from fabric import Fabricator
|
from bar.services.battery import BatteryService
|
||||||
|
|
||||||
|
|
||||||
class BatteryProvider:
|
|
||||||
def __init__(self):
|
|
||||||
self.bat_percent = 0.0
|
|
||||||
self.bat_charging = None
|
|
||||||
|
|
||||||
self._update()
|
|
||||||
GLib.timeout_add_seconds(1, self._update)
|
|
||||||
|
|
||||||
def _update(self):
|
|
||||||
battery = psutil.sensors_battery()
|
|
||||||
if battery is None:
|
|
||||||
self.bat_percent = 0.0
|
|
||||||
self.bat_charging = None
|
|
||||||
else:
|
|
||||||
self.bat_percent = battery.percent
|
|
||||||
self.bat_charging = battery.power_plugged
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_battery(self):
|
|
||||||
return (self.bat_percent, self.bat_charging)
|
|
||||||
|
|
||||||
|
|
||||||
class Battery(Box):
|
class Battery(Box):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(name="battery-widget", orientation="h", spacing=4, **kwargs)
|
super().__init__(name="battery-widget", orientation="h", spacing=4, **kwargs)
|
||||||
self.bat_provider = BatteryProvider()
|
|
||||||
|
|
||||||
self.bat_icon = Image(
|
self.bat_icon = Image(
|
||||||
name="bat-icon", icon_name="battery-full-symbolic", icon_size=16
|
name="bat-icon", icon_name="battery-full-symbolic", icon_size=16
|
||||||
@@ -40,18 +15,17 @@ class Battery(Box):
|
|||||||
|
|
||||||
self.bat_label = Label(name="bat-label", label="100%")
|
self.bat_label = Label(name="bat-label", label="100%")
|
||||||
|
|
||||||
self.bat_fabricator = Fabricator(
|
# Create battery service with signal-based updates
|
||||||
poll_from=lambda *_: self.bat_provider.get_battery(),
|
self.battery_service = BatteryService(update_interval=10000) # Check every 10 seconds
|
||||||
on_changed=self.update_battery,
|
self.battery_service.connect("battery-changed", self.update_battery)
|
||||||
interval=1000,
|
|
||||||
stream=False,
|
|
||||||
default_value=(100, False),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.children = [self.bat_icon, self.bat_label]
|
self.children = [self.bat_icon, self.bat_label]
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
GLib.idle_add(self.update_battery, None, self.bat_provider.get_battery())
|
# Initialize with current battery status
|
||||||
|
initial_percent = self.battery_service.percent
|
||||||
|
initial_charging = self.battery_service.charging
|
||||||
|
GLib.idle_add(self.update_battery, None, initial_percent, initial_charging)
|
||||||
|
|
||||||
def _icon_lookup(self, bat, charging):
|
def _icon_lookup(self, bat, charging):
|
||||||
# Round to nearest 10 for level-based icons
|
# Round to nearest 10 for level-based icons
|
||||||
@@ -62,19 +36,16 @@ class Battery(Box):
|
|||||||
else:
|
else:
|
||||||
return f"battery-level-{level}-symbolic"
|
return f"battery-level-{level}-symbolic"
|
||||||
|
|
||||||
def update_battery(self, sender, battery_data):
|
def update_battery(self, service, percent, charging):
|
||||||
value, charging = battery_data
|
"""Update battery display when battery status changes"""
|
||||||
|
icon_name = self._icon_lookup(percent, charging)
|
||||||
icon_name = self._icon_lookup(value, charging)
|
|
||||||
self.bat_icon.set_property("icon-name", icon_name)
|
self.bat_icon.set_property("icon-name", icon_name)
|
||||||
|
|
||||||
self.bat_label.set_text(f"{int(value)}%")
|
self.bat_label.set_text(f"{int(percent)}%")
|
||||||
|
|
||||||
if value < 20 and not charging:
|
if percent < 20 and not charging:
|
||||||
self.bat_label.add_style_class("battery-low")
|
self.bat_label.add_style_class("battery-low")
|
||||||
self.bat_icon.add_style_class("battery-low")
|
self.bat_icon.add_style_class("battery-low")
|
||||||
else:
|
else:
|
||||||
self.bat_label.remove_style_class("battery-low")
|
self.bat_label.remove_style_class("battery-low")
|
||||||
self.bat_icon.remove_style_class("battery-low")
|
self.bat_icon.remove_style_class("battery-low")
|
||||||
|
|
||||||
return True
|
|
||||||
|
|||||||
@@ -13,10 +13,29 @@ from fabric.widgets.stack import Stack
|
|||||||
from ..widgets.circle_image import CircleImage
|
from ..widgets.circle_image import CircleImage
|
||||||
import bar.modules.icons as icons
|
import bar.modules.icons as icons
|
||||||
from bar.services.mpris import MprisPlayerManager, MprisPlayer
|
from bar.services.mpris import MprisPlayerManager, MprisPlayer
|
||||||
|
from fabric import Fabricator
|
||||||
|
|
||||||
# from bar.modules.cavalcade import SpectrumRender
|
# from bar.modules.cavalcade import SpectrumRender
|
||||||
|
|
||||||
|
|
||||||
|
def get_player_progress(fabricator, mpris_player):
|
||||||
|
"""Get player progress for Fabricator"""
|
||||||
|
if not mpris_player:
|
||||||
|
return (0, 0, 0.0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
current = mpris_player.position
|
||||||
|
except Exception:
|
||||||
|
current = 0
|
||||||
|
try:
|
||||||
|
total = int(mpris_player.length or 0)
|
||||||
|
except Exception:
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
progress = current / total if total > 0 else 0.0
|
||||||
|
return (current, total, progress)
|
||||||
|
|
||||||
|
|
||||||
def get_player_icon_markup_by_name(player_name):
|
def get_player_icon_markup_by_name(player_name):
|
||||||
if player_name:
|
if player_name:
|
||||||
pn = player_name.lower()
|
pn = player_name.lower()
|
||||||
|
|||||||
72
bar/services/battery.py
Normal file
72
bar/services/battery.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import psutil
|
||||||
|
from fabric.core.service import Service, Signal
|
||||||
|
from fabric.utils import invoke_repeater
|
||||||
|
|
||||||
|
|
||||||
|
class BatteryService(Service):
|
||||||
|
@Signal
|
||||||
|
def battery_changed(self, percent: float, charging: bool) -> None:
|
||||||
|
"""Signal emitted when battery status changes"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, update_interval=10000, **kwargs): # Check every 10 seconds
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self._percent = 0.0
|
||||||
|
self._charging = False
|
||||||
|
self._update_interval = update_interval
|
||||||
|
self._timer_id = None
|
||||||
|
|
||||||
|
# Start periodic updates
|
||||||
|
self.start_monitoring()
|
||||||
|
|
||||||
|
def start_monitoring(self):
|
||||||
|
"""Start monitoring battery status"""
|
||||||
|
if self._timer_id is None:
|
||||||
|
# Get initial values
|
||||||
|
self._update_battery()
|
||||||
|
# Set up periodic updates
|
||||||
|
self._timer_id = invoke_repeater(self._update_interval, self._update_battery)
|
||||||
|
|
||||||
|
def stop_monitoring(self):
|
||||||
|
"""Stop monitoring battery status"""
|
||||||
|
if self._timer_id is not None:
|
||||||
|
from gi.repository import GLib
|
||||||
|
GLib.source_remove(self._timer_id)
|
||||||
|
self._timer_id = None
|
||||||
|
|
||||||
|
def _update_battery(self):
|
||||||
|
"""Update battery status and emit signal if changed"""
|
||||||
|
try:
|
||||||
|
# Use the same pattern as the example
|
||||||
|
bat_sen = psutil.sensors_battery()
|
||||||
|
if not bat_sen:
|
||||||
|
# No battery sensor available (desktop systems)
|
||||||
|
new_percent = 100.0 # Assume plugged in
|
||||||
|
new_charging = True
|
||||||
|
else:
|
||||||
|
new_percent = bat_sen.percent
|
||||||
|
new_charging = bat_sen.power_plugged
|
||||||
|
|
||||||
|
# Only emit signal if values changed
|
||||||
|
percent_changed = abs(new_percent - self._percent) > 0.5
|
||||||
|
charging_changed = new_charging != self._charging
|
||||||
|
|
||||||
|
if percent_changed or charging_changed:
|
||||||
|
self._percent = new_percent
|
||||||
|
self._charging = new_charging
|
||||||
|
self.battery_changed(new_percent, new_charging)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error updating battery status: {e}")
|
||||||
|
|
||||||
|
return True # Keep the timer running
|
||||||
|
|
||||||
|
@property
|
||||||
|
def percent(self):
|
||||||
|
"""Get current battery percentage"""
|
||||||
|
return self._percent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def charging(self):
|
||||||
|
"""Get current charging status"""
|
||||||
|
return self._charging
|
||||||
65
bar/services/system_stats.py
Normal file
65
bar/services/system_stats.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import psutil
|
||||||
|
from fabric.core.service import Service, Signal
|
||||||
|
from fabric.utils import invoke_repeater
|
||||||
|
|
||||||
|
|
||||||
|
class SystemStatsService(Service):
|
||||||
|
@Signal
|
||||||
|
def stats_changed(self, cpu_percent: float, memory_percent: float) -> None:
|
||||||
|
"""Signal emitted when system stats change"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, update_interval=3000, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self._cpu_percent = 0.0
|
||||||
|
self._memory_percent = 0.0
|
||||||
|
self._update_interval = update_interval
|
||||||
|
self._timer_id = None
|
||||||
|
|
||||||
|
# Start periodic updates
|
||||||
|
self.start_monitoring()
|
||||||
|
|
||||||
|
def start_monitoring(self):
|
||||||
|
"""Start monitoring system stats"""
|
||||||
|
if self._timer_id is None:
|
||||||
|
# Get initial values
|
||||||
|
self._update_stats()
|
||||||
|
# Set up periodic updates
|
||||||
|
self._timer_id = invoke_repeater(self._update_interval, self._update_stats)
|
||||||
|
|
||||||
|
def stop_monitoring(self):
|
||||||
|
"""Stop monitoring system stats"""
|
||||||
|
if self._timer_id is not None:
|
||||||
|
from gi.repository import GLib
|
||||||
|
GLib.source_remove(self._timer_id)
|
||||||
|
self._timer_id = None
|
||||||
|
|
||||||
|
def _update_stats(self):
|
||||||
|
"""Update system stats and emit signal if changed"""
|
||||||
|
try:
|
||||||
|
new_cpu = psutil.cpu_percent()
|
||||||
|
new_memory = psutil.virtual_memory().percent
|
||||||
|
|
||||||
|
# Only emit signal if values changed significantly (reduce noise)
|
||||||
|
cpu_changed = abs(new_cpu - self._cpu_percent) > 1.0
|
||||||
|
memory_changed = abs(new_memory - self._memory_percent) > 1.0
|
||||||
|
|
||||||
|
if cpu_changed or memory_changed:
|
||||||
|
self._cpu_percent = new_cpu
|
||||||
|
self._memory_percent = new_memory
|
||||||
|
self.stats_changed(new_cpu / 100, new_memory / 100)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error updating system stats: {e}")
|
||||||
|
|
||||||
|
return True # Keep the timer running
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cpu_percent(self):
|
||||||
|
"""Get current CPU percentage"""
|
||||||
|
return self._cpu_percent / 100
|
||||||
|
|
||||||
|
@property
|
||||||
|
def memory_percent(self):
|
||||||
|
"""Get current memory percentage"""
|
||||||
|
return self._memory_percent / 100
|
||||||
Reference in New Issue
Block a user