from xml.etree import ElementTree import dbus import re def undbusify_dict_inner(tup): k, v = tup k = str(k) if type(v) == dbus.String: v = str(v) elif type(v) == dbus.Double: v = float(v) elif type(v) == dbus.UInt32 or type(v) == dbus.UInt64 or type(v) == dbus.Int64: v = int(v) elif type(v) == dbus.Boolean: v = bool(v) return k, v def undbusify_dict(d): return dict(map(undbusify_dict_inner, d.items())) def get_upower_devices(bus): obj = bus.get_object("org.freedesktop.UPower", "/org/freedesktop/UPower/devices") iface = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable") for child in ElementTree.fromstring(iface.Introspect()): yield child.attrib["name"] def get_upower_device_props(bus, device): obj = bus.get_object( "org.freedesktop.UPower", f"/org/freedesktop/UPower/devices/{device}" ) return undbusify_dict( obj.GetAll( "org.freedesktop.UPower.Device", dbus_interface="org.freedesktop.DBus.Properties", ) ) def device_pred(device: str) -> bool: return re.match("gaming_input_hid_.*_battery", device) bus = dbus.SystemBus() devices = filter(device_pred, get_upower_devices(bus)) for device in devices: props = get_upower_device_props(bus, device) pretty_device_name = ( props["Vendor"] + " " * bool(props["Vendor"]) * bool(props["Model"]) + props["Model"] ) percentage = props["Percentage"] print(pretty_device_name, percentage)