mirror of
https://github.com/morgan9e/linux-sys-telemetry
synced 2026-04-13 15:55:04 +09:00
Fix
This commit is contained in:
87
org.batteryd/battery-viewer
Normal file → Executable file
87
org.batteryd/battery-viewer
Normal file → Executable file
@@ -167,7 +167,7 @@ class BatteryChart(Gtk.DrawingArea):
|
||||
t_span = t_max - t_min
|
||||
|
||||
energies = [s[2] for s in self.samples]
|
||||
e_min = min(energies)
|
||||
e_min = 0
|
||||
e_max = max(energies)
|
||||
if e_max <= e_min:
|
||||
e_max = e_min + 1
|
||||
@@ -395,6 +395,7 @@ class SessionRow(Adw.ActionRow):
|
||||
t_start = datetime.fromtimestamp(start_ts).strftime('%H:%M')
|
||||
t_end = datetime.fromtimestamp(end_ts).strftime('%H:%M')
|
||||
duration = end_ts - start_ts
|
||||
hours = duration / 3600
|
||||
|
||||
if status == 'Discharging':
|
||||
icon = 'battery-level-50-symbolic'
|
||||
@@ -406,20 +407,71 @@ class SessionRow(Adw.ActionRow):
|
||||
icon = 'battery-level-100-symbolic'
|
||||
arrow = '→'
|
||||
|
||||
subtitle = f'{t_start} – {t_end} · {format_duration(duration)}'
|
||||
if hours > 0 and status in ('Discharging', 'Charging'):
|
||||
rate = abs(end_level - start_level) / hours
|
||||
subtitle += f' · {rate:.1f}%/hr'
|
||||
|
||||
self.set_title(status)
|
||||
self.set_subtitle(f'{t_start} – {t_end} · {format_duration(duration)}')
|
||||
self.set_subtitle(subtitle)
|
||||
|
||||
img = Gtk.Image.new_from_icon_name(icon)
|
||||
img.set_pixel_size(24)
|
||||
self.add_prefix(img)
|
||||
|
||||
label = Gtk.Label()
|
||||
label.set_markup(f'{start_level:.0f}% {arrow} {end_level:.0f}%')
|
||||
delta = end_level - start_level
|
||||
if status == 'Discharging':
|
||||
label.set_markup(f'−{abs(delta):.0f}%')
|
||||
elif status == 'Charging':
|
||||
label.set_markup(f'+{abs(delta):.0f}%')
|
||||
else:
|
||||
label.set_markup(f'{abs(delta):.0f}%')
|
||||
label.add_css_class('caption')
|
||||
label.set_valign(Gtk.Align.CENTER)
|
||||
self.add_suffix(label)
|
||||
|
||||
|
||||
class GapRow(Adw.ActionRow):
|
||||
"""Inferred gap between sessions (suspend/shutdown)."""
|
||||
|
||||
def __init__(self, prev_end_ts, prev_end_level, next_start_ts, next_start_level):
|
||||
super().__init__()
|
||||
|
||||
t_start = datetime.fromtimestamp(prev_end_ts).strftime('%H:%M')
|
||||
t_end = datetime.fromtimestamp(next_start_ts).strftime('%H:%M')
|
||||
duration = next_start_ts - prev_end_ts
|
||||
delta = next_start_level - prev_end_level
|
||||
|
||||
if abs(delta) < 0.5:
|
||||
kind = 'Shutdown / Hibernate'
|
||||
icon = 'system-shutdown-symbolic'
|
||||
elif delta > 0:
|
||||
kind = 'Suspended (charged)'
|
||||
icon = 'battery-level-50-charging-symbolic'
|
||||
else:
|
||||
kind = 'Suspended'
|
||||
icon = 'media-playback-pause-symbolic'
|
||||
|
||||
self.set_title(kind)
|
||||
self.set_subtitle(f'{t_start} – {t_end} · {format_duration(duration)}')
|
||||
self.add_css_class('dim-label')
|
||||
|
||||
img = Gtk.Image.new_from_icon_name(icon)
|
||||
img.set_pixel_size(24)
|
||||
self.add_prefix(img)
|
||||
|
||||
if abs(delta) >= 0.5:
|
||||
label = Gtk.Label()
|
||||
if delta > 0:
|
||||
label.set_markup(f'+{abs(delta):.0f}%')
|
||||
else:
|
||||
label.set_markup(f'−{abs(delta):.0f}%')
|
||||
label.add_css_class('caption')
|
||||
label.set_valign(Gtk.Align.CENTER)
|
||||
self.add_suffix(label)
|
||||
|
||||
|
||||
# ── Main window ───────────────────────────────────────────
|
||||
|
||||
class BatteryWindow(Adw.ApplicationWindow):
|
||||
@@ -572,14 +624,41 @@ class BatteryWindow(Adw.ApplicationWindow):
|
||||
self.session_group.set_margin_top(16)
|
||||
self.content.append(self.session_group)
|
||||
|
||||
# merge adjacent sessions with same status and small gaps
|
||||
MERGE_GAP = 180 # 3 minutes — merge if same status and gap < this
|
||||
GAP_THRESHOLD = 180 # show gap row if gap >= this between different statuses
|
||||
|
||||
merged = []
|
||||
for s in sessions:
|
||||
start_ts, end_ts, start_lvl, end_lvl, status = s
|
||||
if merged:
|
||||
p_start, p_end, p_slvl, p_elvl, p_status = merged[-1]
|
||||
gap = start_ts - p_end
|
||||
if p_status == status and gap < MERGE_GAP:
|
||||
# extend previous session
|
||||
merged[-1] = (p_start, end_ts, p_slvl, end_lvl, status)
|
||||
continue
|
||||
merged.append(s)
|
||||
|
||||
prev = None
|
||||
for s in merged:
|
||||
start_ts, end_ts, start_lvl, end_lvl, status = s
|
||||
if end_ts - start_ts < 30:
|
||||
prev = s
|
||||
continue
|
||||
|
||||
if prev is not None:
|
||||
_, prev_end, _, prev_end_lvl, _ = prev
|
||||
gap = start_ts - prev_end
|
||||
if gap > GAP_THRESHOLD:
|
||||
gap_row = GapRow(prev_end, prev_end_lvl, start_ts, start_lvl)
|
||||
self.session_group.add(gap_row)
|
||||
|
||||
row = SessionRow(start_ts, end_ts, start_lvl, end_lvl, status)
|
||||
self.session_group.add(row)
|
||||
prev = s
|
||||
|
||||
if not sessions:
|
||||
if not merged:
|
||||
empty = Adw.ActionRow(title='No sessions recorded')
|
||||
empty.add_css_class('dim-label')
|
||||
self.session_group.add(empty)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/python3 -sP
|
||||
"""
|
||||
batteryd — battery tracking daemon
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Desktop Entry]
|
||||
Name=ScreenTime
|
||||
Name=Screentime Viewer
|
||||
Comment=View your screen time usage
|
||||
Exec=screentime-viewer
|
||||
Icon=preferences-system-time-symbolic
|
||||
0
screentimed/screentime-viewer
Normal file → Executable file
0
screentimed/screentime-viewer
Normal file → Executable file
0
screentimed/screentimed
Normal file → Executable file
0
screentimed/screentimed
Normal file → Executable file
Reference in New Issue
Block a user