pax_global_header00006660000000000000000000000064144332077030014515gustar00rootroot0000000000000052 comment=bdb3ee086f091c7434ae978b15069b3a5604b6dc powersupply-0.9.0/000077500000000000000000000000001443320770300141345ustar00rootroot00000000000000powersupply-0.9.0/.gitignore000066400000000000000000000033251443320770300161270ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ /.idea *.glade~ /buildpowersupply-0.9.0/LICENSE000066400000000000000000000020561443320770300151440ustar00rootroot00000000000000MIT License Copyright (c) 2019 Martijn Braam Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. powersupply-0.9.0/README.rst000066400000000000000000000001261443320770300156220ustar00rootroot00000000000000Powersupply =========== Graphical power_supply status tool for Linux mobile platformspowersupply-0.9.0/build-aux/000077500000000000000000000000001443320770300160265ustar00rootroot00000000000000powersupply-0.9.0/build-aux/meson/000077500000000000000000000000001443320770300171475ustar00rootroot00000000000000powersupply-0.9.0/build-aux/meson/postinstall.py000066400000000000000000000011221443320770300220710ustar00rootroot00000000000000#!/usr/bin/env python3 from os import environ, path from subprocess import call prefix = environ.get('MESON_INSTALL_PREFIX', '/usr/local') datadir = path.join(prefix, 'share') destdir = environ.get('DESTDIR', '') if not destdir: print('Updating icon cache...') call(['gtk-update-icon-cache', '-qtf', path.join(datadir, 'icons', 'hicolor')]) print('Updating desktop database') call(['update-desktop-database', '-q', path.join(datadir, 'applications')]) print('Compiling GSettings schemas...') call(['glib-compile-schemas', path.join(datadir, 'glib-2.0', 'schemas')])powersupply-0.9.0/data/000077500000000000000000000000001443320770300150455ustar00rootroot00000000000000powersupply-0.9.0/data/meson.build000066400000000000000000000005461443320770300172140ustar00rootroot00000000000000install_data('nl.brixit.powersupply.desktop', install_dir: join_paths(get_option('datadir'), 'applications'), ) install_data(['nl.brixit.powersupply.appdata.xml'], install_dir : get_option('datadir') / 'metainfo') install_data('nl.brixit.powersupply.svg', install_dir: join_paths(get_option('datadir'), 'icons/hicolor/scalable/apps') )powersupply-0.9.0/data/nl.brixit.powersupply.appdata.xml000066400000000000000000000027411443320770300235250ustar00rootroot00000000000000 nl.brixit.powersupply CC0-1.0 MIT Powersupply Linux power subsystem debugger

An application that displays the state of various batteries and powersupplies in mobile platforms.

nl.brixit.powersupply.desktop powersupply http://brixitcdn.net/metainfo/powersupply.png https://gitlab.com/MartijnBraam/powersupply https://gitlab.com/MartijnBraam/powersupply/-/issues Fix buildsystem metadata issues and add better support for external batteries. Display data from current_now and usb_type on the USB supply. Initial release that includes metadata
powersupply-0.9.0/data/nl.brixit.powersupply.desktop000066400000000000000000000004401443320770300227570ustar00rootroot00000000000000[Desktop Entry] Name=Powersupply Encoding=UTF-8 Version=1.0 Type=Application Terminal=false Exec=powersupply GenericName=Power info Icon=nl.brixit.powersupply Categories=GTK;GNOME;Utility X-DBUS-ServiceName=nl.brixit.powersupply StartupNotify=true X-Purism-FormFactor=Workstation;Mobile; powersupply-0.9.0/data/nl.brixit.powersupply.svg000066400000000000000000000374661443320770300221270ustar00rootroot00000000000000 Adwaita Icon Template image/svg+xml GNOME Design Team Adwaita Icon Template powersupply-0.9.0/meson.build000066400000000000000000000004061443320770300162760ustar00rootroot00000000000000project('powersupply', version: '0.9.0', meson_version: '>= 0.50.0', default_options: ['warning_level=2']) dependency('libhandy-1', version: '>=1.0.0') subdir('powersupply') subdir('data') meson.add_install_script('build-aux/meson/postinstall.py')powersupply-0.9.0/powersupply/000077500000000000000000000000001443320770300165455ustar00rootroot00000000000000powersupply-0.9.0/powersupply/__init__.py000066400000000000000000000000001443320770300206440ustar00rootroot00000000000000powersupply-0.9.0/powersupply/__main__.py000066400000000000000000000451011443320770300206400ustar00rootroot00000000000000import glob import threading import time import logging import os import re import gi from powersupply.platform_internals import AXP803, PMI8998 gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib, GObject, Gio, GdkPixbuf gi.require_version('Handy', '1') from gi.repository import Handy logging.basicConfig(level=logging.DEBUG) class ExternalBattery: def __init__(self): self.name = None self.present = False self.status = None self.capacity = None self.voltage = None self.current = None self.health = None self.temp = None class PowerStatus: def __init__(self): self.battery_present = None self.battery_charging = None self.battery_capacity = None self.battery_voltage = None self.battery_current = None self.battery_health = None self.battery_temp = None self.supply_type = None self.usb_present = None self.usb_current_limit = None self.usb_current = None self.usb_voltage = None self.usb_type = None self.ac_present = None self.typec = None self.typec_revision = None self.typec_pd_revision = None self.typec_pr = None self.typec_dr = None self.typec_operation_mode = None self.ext = [] class DataPoller(threading.Thread): def __init__(self, callback): threading.Thread.__init__(self) self.callback = callback self.regex_enum = re.compile(r'\[([^\]]+)\]') self.opmode = { 'default': 'Default', '1.5A': '1.5A no PD', '3A': '3A no PD', '3.0A': '3.0A no PD', 'usb_power_delivery': 'PD', } def run(self): supplies = self.get_supply_types() print("Supplies found: {}".format(", ".join(supplies.keys()))) battery_present = os.path.join(supplies['bat'][0], 'present') battery_status = os.path.join(supplies['bat'][0], 'status') battery_health = os.path.join(supplies['bat'][0], 'health') battery_capacity = os.path.join(supplies['bat'][0], 'capacity') battery_voltage = os.path.join(supplies['bat'][0], 'voltage_now') battery_temp = os.path.join(supplies['bat'][0], 'temp') battery_current = os.path.join(supplies['bat'][0], 'current_now') if not os.path.isfile(battery_present): battery_present = None if not os.path.isfile(battery_status): battery_status = None if not os.path.isfile(battery_health): battery_health = None if not os.path.isfile(battery_capacity): battery_capacity = None if not os.path.isfile(battery_voltage): battery_voltage = None if not os.path.isfile(battery_temp): battery_temp = None if not os.path.isfile(battery_current): battery_current = None supply_type = 'USB' if 'usb' in supplies: usb_present = os.path.join(supplies['usb'][0], 'present') if not os.path.isfile(usb_present): usb_present = os.path.join(supplies['usb'][0], 'online') if not os.path.isfile(usb_present): usb_present = None usb_current_limit = os.path.join(supplies['usb'][0], 'input_current_limit') if not os.path.isfile(usb_current_limit): usb_current_limit = os.path.join(supplies['usb'][0], 'current_max') if not os.path.isfile(usb_current_limit): usb_current_limit = None usb_voltage = os.path.join(supplies['usb'][0], 'voltage_now') if not os.path.isfile(usb_voltage): usb_voltage = None usb_current = os.path.join(supplies['usb'][0], 'current_now') if not os.path.isfile(usb_current): usb_current = None usb_status = os.path.join(supplies['usb'][0], 'status') if not os.path.isfile(usb_status): usb_status = None usb_type = os.path.join(supplies['usb'][0], 'usb_type') if not os.path.isfile(usb_type): usb_type = None elif 'ac' in supplies: supply_type = 'AC' if 'ac' in supplies: ac_present = os.path.join(supplies['ac'][0], 'online') platform = None if os.path.isfile('/proc/device-tree/compatible'): compatible = self.read_sysfs_str('/proc/device-tree/compatible') if 'sun50i-a64' in compatible: # Probably Allwinner A64 with AXP803 platform = AXP803() if os.path.isdir('/sys/class/power_supply/pmi8998_charger'): platform = PMI8998() while True: ps = PowerStatus() ps.supply_type = supply_type ps.battery_present = self.read_sysfs(battery_present) == 1 if battery_present is not None else True ps.usb_present = 'usb' in supplies and self.read_sysfs(usb_present) == 1 ps.ac_present = 'ac' in supplies and self.read_sysfs(ac_present) == 1 ps.battery_health = self.read_sysfs_str(battery_health) ps.battery_capacity = self.read_sysfs(battery_capacity) bat_volt = self.read_sysfs(battery_voltage) / 1000000.0 ps.battery_voltage = bat_volt if bat_volt > 0 else None ps.battery_current = self.read_sysfs(battery_current) / 1000000.0 if 'usb' in supplies: ucl = self.read_sysfs(usb_current_limit) if ucl: ps.usb_current_limit = ucl / 1000000.0 uv = self.read_sysfs(usb_voltage) if uv: ps.usb_voltage = uv / 1000000.0 uc = self.read_sysfs(usb_current) if uc: ps.usb_current = uc / 1000000.0 ut = self.read_sysfs_enum(usb_type) if ut: ps.usb_type = ut if battery_temp: bt = self.read_sysfs(battery_temp) if bt is None: ps.battery_temp = None else: ps.battery_temp = bt / 10.0 if os.path.isdir('/sys/class/typec/port0'): ps.typec = True ps.typec_revision = self.read_sysfs_str('/sys/class/typec/port0/usb_typec_revision') ps.typec_pd_revision = self.read_sysfs_str('/sys/class/typec/port0/usb_power_delivery_revision') ps.typec_pr = self.read_sysfs_enum('/sys/class/typec/port0/power_role').title() ps.typec_dr = self.read_sysfs_enum('/sys/class/typec/port0/data_role').title() opmode = self.read_sysfs_str('/sys/class/typec/port0/power_operation_mode') ps.typec_operation_mode = self.opmode[opmode] if platform: ps = platform.process(ps) if self.read_sysfs_str(battery_status) == "Unknown": if 'usb' in supplies and usb_status: ps.battery_charging = self.read_sysfs_str(usb_status) == "Charging" else: ps.battery_charging = ps.battery_current >= 0 if ps.battery_current < 0: ps.battery_current *= -1.0 else: ps.battery_charging = self.read_sysfs_str(battery_status) == "Charging" for ebat in supplies['bat'][1:]: name = 'External battery' if os.path.isfile(os.path.join(ebat, 'device/name')): with open(os.path.join(ebat, 'device/name'), 'r') as handle: name = handle.read().strip() elif os.path.isfile(os.path.join(ebat, 'model_name')): with open(os.path.join(ebat, 'model_name'), 'r') as name_handle: name = name_handle.read().strip() if os.path.isfile(os.path.join(ebat, 'manufacturer')): with open(os.path.join(ebat, 'manufacturer'), 'r') as manuf_handle: name = '{} {}'.format(manuf_handle.read().strip(), name) names = { 'kb151': 'Keyboard case', 'ip5xxx-battery': 'Keyboard case' } if name in names: name = names[name] ext = ExternalBattery() ext.name = name ext.present = True ext.health = 'N/A' ebat_present = os.path.join(ebat, 'present') ebat_online = os.path.join(ebat, 'online') ebat_status = os.path.join(ebat, 'status') ebat_health = os.path.join(ebat, 'health') ebat_capacity = os.path.join(ebat, 'capacity') ebat_capacity_level = os.path.join(ebat, 'capacity_level') ebat_voltage = os.path.join(ebat, 'voltage_now') ebat_current = os.path.join(ebat, 'current_now') ebat_temp = os.path.join(ebat, 'temp') if os.path.isfile(ebat_present): ext.present = self.read_sysfs_str(ebat_present) == '1' elif os.path.isfile(ebat_online): ext.present = self.read_sysfs_str(ebat_online) == '1' ext.status = self.read_sysfs_str(ebat_status) if os.path.isfile(ebat_health): ext.health = self.read_sysfs_str(ebat_health) if os.path.isfile(ebat_capacity): ext.capacity = '{}%'.format(self.read_sysfs(ebat_capacity)) elif os.path.isfile(ebat_capacity_level): ext.capacity = self.read_sysfs_str(ebat_capacity_level) if os.path.isfile(ebat_voltage): ext.voltage = self.read_sysfs(ebat_voltage) / 1000000.0 if os.path.isfile(ebat_current): ext.current = self.read_sysfs(ebat_current) / 1000000.0 ps.ext.append(ext) GLib.idle_add(self.callback, ps) time.sleep(1) def read_sysfs(self, path, default=None): if path is None: return 0 if not os.path.isfile(path): return default with open(path) as handle: return int(handle.read().strip()) def read_sysfs_str(self, path): if path is None: return "" with open(path) as handle: return handle.read().strip() def read_sysfs_enum(self, path): if path is None: return None try: with open(path) as handle: raw = handle.read().strip() except: return None match = self.regex_enum.findall(raw) if len(match) > 0: return match[0] else: return None def get_supply_types(self): result = {} mapping = { 'Battery': 'bat', 'Mains': 'ac', 'USB': 'usb' } for path in glob.glob('/sys/class/power_supply/*'): if not os.path.isfile(os.path.join(path, 'type')): print("Ignoring {} because it doesn't have a `type` file".format(path)) continue with open(os.path.join(path, 'type')) as handle: type = handle.read().strip() if type in mapping: type = mapping[type] if type not in result: result[type] = [] result[type].append(path) result[type] = list(sorted(result[type])) for type in result: print(f'{type}:') for path in result[type]: print(' ' + path.replace('/sys/class/power_supply/', '')) return result class PowersupplyApplication(Gtk.Application): def __init__(self, application_id, flags): Gtk.Application.__init__(self, application_id=application_id, flags=flags) self.connect("activate", self.new_window) def new_window(self, *args): AppWindow(self) class AppWindow: def __init__(self, application): self.application = application builder = Gtk.Builder() builder.add_from_resource('/nl/brixit/powersupply/powersupply.glade') builder.connect_signals(Handler(builder)) window = builder.get_object("main_window") window.set_application(self.application) window.show_all() Gtk.main() class Handler: def __init__(self, builder): self.builder = builder self.window = builder.get_object('main_window') self.main_box = builder.get_object('main_box') self.supply_type = builder.get_object('supply_type') self.bat_capacity = builder.get_object('bat_capacity') self.bat_voltage = builder.get_object('bat_voltage') self.bat_status = builder.get_object('bat_status') self.bat_health = builder.get_object('bat_health') self.bat_temp = builder.get_object('bat_temp') self.usb_charger = builder.get_object('usb_charger') self.usb_voltage = builder.get_object('usb_voltage') self.usb_current = builder.get_object('usb_current') self.usb_current_row = builder.get_object('usb_current_row') self.usb_current_limit = builder.get_object('usb_current_limit') self.usb_type = builder.get_object('usb_type') self.usb_type_row = builder.get_object('usb_type_row') self.typec = builder.get_object('typec') self.typec_revision = builder.get_object('typec_revision') self.typec_pd_revision = builder.get_object('typec_pd_revision') self.typec_pr = builder.get_object('typec_pr') self.typec_dr = builder.get_object('typec_dr') self.typec_operation_mode = builder.get_object('typec_operation_mode') self.boxes = {} thread = DataPoller(self.data_update) thread.daemon = True thread.start() def on_quit(self, *args): Gtk.main_quit() def do_box(self, name, content): if name in self.boxes: for label in content: self.boxes[name][label].set_text(content[label]) return box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) heading = Gtk.Label(label=name, xalign=0.0) heading.set_margin_bottom(6) box.add(heading) listbox = Gtk.ListBox() box.add(listbox) listbox.get_style_context().add_class('content') self.boxes[name] = {} for label in content: row = Gtk.Box() row.set_margin_top(8) row.set_margin_bottom(8) row.set_margin_start(8) row.set_margin_end(8) dl = Gtk.Label(label=label, xalign=0.0) row.pack_start(dl, False, False, 0) vl = Gtk.Label(label=content[label]) row.pack_end(vl, False, False, 0) vl.get_style_context().add_class('dim-label') self.boxes[name][label] = vl listbox.add(row) self.main_box.add(box) self.main_box.show_all() def data_update(self, result): if not isinstance(result, PowerStatus): return self.supply_type.set_text(result.supply_type) if result.battery_present: if result.battery_charging: bat_status = 'Charging' else: bat_status = 'Discharging' if result.battery_voltage is not None and result.battery_current is not None: power = result.battery_voltage * result.battery_current bat_status += ' ({:0.2f}W)'.format(power) else: bat_status = 'Not present' self.bat_status.set_text(bat_status) self.bat_capacity.set_text('{}%'.format(result.battery_capacity)) self.bat_voltage.set_text('{:0.2f}V'.format(result.battery_voltage)) if result.battery_temp: self.bat_temp.set_text('{:0.1f}°C'.format(result.battery_temp)) else: self.bat_temp.set_text('') self.bat_health.set_text(result.battery_health) if result.usb_present: if result.usb_current_limit is None: self.usb_current_limit.set_text("") else: self.usb_current_limit.set_text('{:0.1f}A'.format(result.usb_current_limit)) if result.usb_voltage is None: self.usb_voltage.set_text('') else: self.usb_voltage.set_text('{:0.2f}V'.format(result.usb_voltage)) if result.usb_current is None: self.usb_current.set_text('') self.usb_current_row.hide() else: self.usb_current_row.show() self.usb_current.set_text('{:0.2f}A'.format(result.usb_current)) if result.usb_type is None: self.usb_type.set_text('') self.usb_type_row.hide() else: self.usb_type_row.show() self.usb_type.set_text(result.usb_type) self.usb_charger.set_text('Connected') elif result.ac_present: self.usb_charger.set_text('Connected') self.usb_current_limit.set_text('') self.usb_voltage.set_text('') self.usb_current_row.hide() self.usb_type_row.hide() else: self.usb_current_limit.set_text('') self.usb_voltage.set_text('') self.usb_charger.set_text('Not connected') self.usb_current.set_text('') self.usb_current_row.hide() self.usb_type_row.hide() if result.typec: self.typec_revision.set_text(result.typec_revision) self.typec_pd_revision.set_text(result.typec_pd_revision) self.typec_pr.set_text(result.typec_pr) self.typec_dr.set_text(result.typec_dr) self.typec_operation_mode.set_text(result.typec_operation_mode) self.typec.show_all() else: self.typec.hide() for ext in result.ext: content = { 'Capacity': ext.capacity, } if ext.voltage is not None: content['Voltage'] = f'{ext.voltage}V' if ext.current is not None and ext.voltage is not None: w = abs(ext.voltage * ext.current) content['Status'] = f'{ext.status} ({w:.2f}W)' else: content['Status'] = ext.status content['Health'] = ext.health self.do_box(ext.name, content) def main(version): # To make sure libhandy is actually loaded in python Handy.init() app = PowersupplyApplication("nl.brixit.powersupply", Gio.ApplicationFlags.FLAGS_NONE) app.run() if __name__ == '__main__': main('dev') powersupply-0.9.0/powersupply/meson.build000066400000000000000000000014771443320770300207200ustar00rootroot00000000000000pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) moduledir = join_paths(pkgdatadir, 'powersupply') gnome = import('gnome') gnome.compile_resources('powersupply', 'powersupply.gresource.xml', gresource_bundle: true, install: true, install_dir: pkgdatadir, ) python = import('python') conf = configuration_data() conf.set('PYTHON', python.find_installation('python3').path()) conf.set('VERSION', meson.project_version()) conf.set('pkgdatadir', pkgdatadir) configure_file( input: 'powersupply.in', output: 'powersupply', configuration: conf, install: true, install_mode: 'rwxr-xr-x', install_dir: get_option('bindir') ) sources = [ '__init__.py', '__main__.py', 'platform_internals.py', ] install_data(sources, install_dir: moduledir)powersupply-0.9.0/powersupply/platform_internals.py000066400000000000000000000035161443320770300230270ustar00rootroot00000000000000import glob import os class Platform: def process(self, ps): return ps def read_sysfs(self, path): with open(path) as handle: return int(handle.read().strip()) def read_sysfs_str(self, path): with open(path) as handle: return handle.read().strip() def find_iio_device(self, name): if not os.path.isdir('/sys/bus/iio'): return None for path in glob.glob('/sys/bus/iio/devices/iio*'): compat_file = os.path.join(path, 'of_node/compatible') if not os.path.isfile(compat_file): continue with open(compat_file) as handle: compatible = handle.read().strip() if name in compatible: return path class AXP803(Platform): def __init__(self): """ in_current1 is the current going IN the battery while charging in_current2 is the current going OUT the battery while discharging """ self.axp_adc = self.find_iio_device('axp813-adc') self.current1 = os.path.join(self.axp_adc, 'in_current1_raw') self.current2 = os.path.join(self.axp_adc, 'in_current2_raw') def process(self, ps): current1 = self.read_sysfs(self.current1) current2 = self.read_sysfs(self.current2) if current1 > current2: ps.battery_current = current1 / 1000.0 else: ps.battery_current = current2 / 1000.0 return ps class PMI8998(Platform): def __init__(self): self.health = '/sys/class/power_supply/pmi8998_charger/health' def process(self, ps): if ps.battery_current: ps.battery_current = -1 * ps.battery_current # Battery health is in the pmic directory instead ps.battery_health = self.read_sysfs_str(self.health) return ps powersupply-0.9.0/powersupply/powersupply.glade000066400000000000000000001642171443320770300221670ustar00rootroot00000000000000 False 480 640 True False vertical True False Powersupply True False True 0 True True True False none True False True False 16 16 16 16 vertical 16 True False vertical True False start 6 Battery False True 0 True False none False True True True False 8 8 8 8 True False Capacity False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Voltage False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Status False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Health False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Temperature False True 0 True False N/A middle False True end 1 False True 1 False True 0 True False vertical True False start 6 USB False True 0 True False none False True True True False 8 8 8 8 8 8 True False Charger False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Voltage False True 0 True False N/A middle False True end 1 True True False 8 8 8 8 8 8 True False Current False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Current limit False True 0 True False N/A middle False True end 1 True True False 8 8 8 8 8 8 True False Type False True 0 True False N/A middle False True end 1 False True 1 False True 1 True False vertical True False start 6 Type-C False True 0 True False none False True True True False 8 8 8 8 8 8 True False Type-C revision False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False PD revision False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Power role False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Data role False True 0 True False N/A middle False True end 1 True True True False 8 8 8 8 8 8 True False Operation mode False True 0 True False N/A middle False True end 1 False True 1 False True 2 True True 1 powersupply-0.9.0/powersupply/powersupply.gresource.xml000066400000000000000000000002411443320770300236720ustar00rootroot00000000000000 powersupply.glade powersupply-0.9.0/powersupply/powersupply.in000066400000000000000000000006621443320770300215120ustar00rootroot00000000000000#!@PYTHON@ import os import sys import signal VERSION = '@VERSION@' pkgdatadir = '@pkgdatadir@' sys.path.insert(1, pkgdatadir) signal.signal(signal.SIGINT, signal.SIG_DFL) if __name__ == '__main__': import gi from gi.repository import Gio resource = Gio.Resource.load(os.path.join(pkgdatadir, 'powersupply.gresource')) resource._register() from powersupply import __main__ sys.exit(__main__.main(VERSION))