pax_global_header 0000666 0000000 0000000 00000000064 14433207703 0014515 g ustar 00root root 0000000 0000000 52 comment=bdb3ee086f091c7434ae978b15069b3a5604b6dc
powersupply-0.9.0/ 0000775 0000000 0000000 00000000000 14433207703 0014134 5 ustar 00root root 0000000 0000000 powersupply-0.9.0/.gitignore 0000664 0000000 0000000 00000003325 14433207703 0016127 0 ustar 00root root 0000000 0000000 # 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~
/build powersupply-0.9.0/LICENSE 0000664 0000000 0000000 00000002056 14433207703 0015144 0 ustar 00root root 0000000 0000000 MIT 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.rst 0000664 0000000 0000000 00000000126 14433207703 0015622 0 ustar 00root root 0000000 0000000 Powersupply
===========
Graphical power_supply status tool for Linux mobile platforms powersupply-0.9.0/build-aux/ 0000775 0000000 0000000 00000000000 14433207703 0016026 5 ustar 00root root 0000000 0000000 powersupply-0.9.0/build-aux/meson/ 0000775 0000000 0000000 00000000000 14433207703 0017147 5 ustar 00root root 0000000 0000000 powersupply-0.9.0/build-aux/meson/postinstall.py 0000664 0000000 0000000 00000001122 14433207703 0022071 0 ustar 00root root 0000000 0000000 #!/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/ 0000775 0000000 0000000 00000000000 14433207703 0015045 5 ustar 00root root 0000000 0000000 powersupply-0.9.0/data/meson.build 0000664 0000000 0000000 00000000546 14433207703 0017214 0 ustar 00root root 0000000 0000000 install_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.xml 0000664 0000000 0000000 00000002741 14433207703 0023525 0 ustar 00root root 0000000 0000000
nl.brixit.powersupplyCC0-1.0MITPowersupplyLinux power subsystem debugger
An application that displays the state of various batteries and powersupplies in mobile platforms.
nl.brixit.powersupply.desktoppowersupplyhttp://brixitcdn.net/metainfo/powersupply.pnghttps://gitlab.com/MartijnBraam/powersupplyhttps://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.desktop 0000664 0000000 0000000 00000000440 14433207703 0022757 0 ustar 00root root 0000000 0000000 [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.svg 0000664 0000000 0000000 00000037466 14433207703 0022127 0 ustar 00root root 0000000 0000000
powersupply-0.9.0/meson.build 0000664 0000000 0000000 00000000406 14433207703 0016276 0 ustar 00root root 0000000 0000000 project('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/ 0000775 0000000 0000000 00000000000 14433207703 0016545 5 ustar 00root root 0000000 0000000 powersupply-0.9.0/powersupply/__init__.py 0000664 0000000 0000000 00000000000 14433207703 0020644 0 ustar 00root root 0000000 0000000 powersupply-0.9.0/powersupply/__main__.py 0000664 0000000 0000000 00000045101 14433207703 0020640 0 ustar 00root root 0000000 0000000 import 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.build 0000664 0000000 0000000 00000001477 14433207703 0020720 0 ustar 00root root 0000000 0000000 pkgdatadir = 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.py 0000664 0000000 0000000 00000003516 14433207703 0023027 0 ustar 00root root 0000000 0000000 import 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.glade 0000664 0000000 0000000 00000164217 14433207703 0022167 0 ustar 00root root 0000000 0000000
powersupply-0.9.0/powersupply/powersupply.gresource.xml 0000664 0000000 0000000 00000000241 14433207703 0023672 0 ustar 00root root 0000000 0000000
powersupply.glade