Created
July 9, 2019 11:10
-
-
Save nicoe/31c3c7a0bf15f8d982adea4c8e2fd417 to your computer and use it in GitHub Desktop.
A battery block with notification for i3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# Copyright (C) 2016 James Murphy | |
# Licensed under the GPL version 2 only | |
# | |
# A battery indicator blocklet script for i3blocks | |
import gi | |
import re | |
import pathlib | |
import tempfile | |
from subprocess import check_output | |
gi.require_version('Gio', '2.0') | |
from gi.repository import Gio | |
SIZE = 32 | |
ICON_PREFIX = pathlib.Path(f'/usr/share/icons/gnome/{SIZE}x{SIZE}/status/') | |
def notify(new_status): | |
if not new_status: | |
return | |
if 'low' in new_status: | |
priority = Gio.NotificationPriority.URGENT | |
message = "Battery LOW" | |
icon = ICON_PREFIX / 'battery-caution.png' | |
elif 'charging' in new_status: | |
priority = Gio.NotificationPriority.NORMAL | |
message = "Battery charging" | |
icon = ICON_PREFIX / 'battery-low-charging.png' | |
elif 'discharging' in new_status: | |
priority = Gio.NotificationPriority.NORMAL | |
message = "Battery discharging" | |
icon = ICON_PREFIX / 'battery-low.png' | |
else: | |
priority = Gio.NotificationPriority.LOW | |
message = "Battery normal" | |
icon = ICON_PREFIX / 'battery-good.png' | |
application = Gio.Application.new( | |
'battery.notification', Gio.ApplicationFlags.FLAGS_NONE) | |
application.register() | |
notification = Gio.Notification.new(message) | |
notification.set_priority(priority) | |
notification.set_icon(Gio.FileIcon.new(Gio.File.new_for_path(str(icon)))) | |
application.send_notification(None, notification) | |
def get_status(): | |
tmpdir = pathlib.Path(tempfile.gettempdir()) / 'battery-block' | |
if not tmpdir.exists(): | |
tmpdir.mkdir() | |
return set(f.name for f in tmpdir.iterdir()) | |
def set_status(status): | |
tmpdir = pathlib.Path(tempfile.gettempdir()) / 'battery-block' | |
if not tmpdir.exists(): | |
tmpdir.mkdir() | |
try: | |
(tmpdir / status).touch(exist_ok=False) | |
except FileExistsError: | |
pass | |
try: | |
if status == 'charging': | |
(tmpdir / 'discharging').unlink() | |
elif status == 'discharging': | |
(tmpdir / 'charging').unlink() | |
elif status == 'low': | |
(tmpdir / 'normal').unlink() | |
elif status == 'normal': | |
(tmpdir / 'low').unlink() | |
except FileNotFoundError: | |
pass | |
status = check_output(['acpi', '-ab'], universal_newlines=True) | |
previous_status = get_status() | |
if not status: | |
# stands for no battery found | |
fulltext = "<span color='red'><span font='Font Awesome 5 Free'>\uf00d \uf240</span></span>" | |
percentleft = 100 | |
else: | |
# if there is more than one battery in one laptop, the percentage left is | |
# available for each battery separately, although state and remaining | |
# time for overall block is shown in the status of the first battery | |
batteries = status.splitlines() | |
state_batteries = [] | |
commasplitstatus_batteries = [] | |
percentleft_batteries = [] | |
time = "" | |
plugged = False | |
for battery in batteries: | |
if not battery: | |
continue | |
if battery.startswith('Battery'): | |
state_batteries.append(battery.split(": ")[1].split(", ")[0]) | |
commasplitstatus = battery.split(", ") | |
if not time: | |
time = commasplitstatus[-1].strip() | |
# check if it matches a time | |
time = re.match(r"(\d+):(\d+)", time) | |
if time: | |
time = ":".join(time.groups()) | |
timeleft = " ({})".format(time) | |
else: | |
timeleft = "" | |
p = int(commasplitstatus[1].rstrip("%\n")) | |
if p > 0: | |
percentleft_batteries.append(p) | |
commasplitstatus_batteries.append(commasplitstatus) | |
elif battery.startswith('Adapter'): | |
plugged = plugged or battery.endswith('on-line') | |
state = state_batteries[0] | |
commasplitstatus = commasplitstatus_batteries[0] | |
if percentleft_batteries: | |
percentleft = int( | |
sum(percentleft_batteries) / len(percentleft_batteries)) | |
else: | |
percentleft = 0 | |
fulltext = '' | |
if state == "Charging" or plugged: | |
fulltext += '<span font="Font Awesome 5 Free">\uf0e7</span> ' | |
set_status('charging') | |
else: | |
set_status('discharging') | |
def battery_icon(percent): | |
if 10 < percent < 30: | |
color = '#FF3300' | |
else: | |
color = '#FFFFFF' | |
fa = chr(int('f170', 16) + (percent // 10) % 10) | |
tmpl = '<span color="{}"><span font="Material Design Icons">{}</span></span>' | |
return tmpl.format(color, fa) | |
if percentleft < 10: | |
set_status('low') | |
else: | |
set_status('normal') | |
fulltext += battery_icon(percentleft) | |
fulltext += timeleft | |
if previous_status: | |
notify(get_status() - previous_status) | |
print(fulltext) | |
print(fulltext) | |
if percentleft < 10: | |
exit(33) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment