7 Commits
0.1 ... 0.3

Author SHA1 Message Date
Stephen Horvath
fa5442d5fd Release 0.3 2025-04-13 15:30:04 +10:00
Stephen Horvath
09f072a150 PyInstaller changes for PawnIO 2025-04-13 15:23:20 +10:00
Stephen Horvath
f2cf2c7923 Read the EC for the battery limiter 2025-04-13 12:52:02 +10:00
Stephen Horvath
35f9c766b9 Show battery limiter percentage & fix icons for pip 2025-04-13 11:55:06 +10:00
Stephen Horvath
8b33f75b86 Release 0.2 2025-03-24 21:38:13 +10:00
Stephen Horvath
076f903fbc Add PyInstaller spec for Windows 2025-03-24 20:50:34 +10:00
Stephen Horvath
d65a033523 Fix led colours being added multiple times 2025-03-24 20:47:26 +10:00
15 changed files with 127 additions and 37 deletions

5
.gitignore vendored
View File

@@ -30,7 +30,7 @@ MANIFEST
# 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
#*.spec
# Installer logs
pip-log.txt
@@ -175,3 +175,6 @@ cython_debug/
# Flatpak builder
.flatpak-builder/
# Binary files
*.bin

View File

@@ -1,2 +1 @@
include yafi/ui/*.ui
include yafi/yafi.gresource

View File

@@ -1,7 +1,7 @@
# Yet Another Framework Interface
YAFI is another GUI for the Framework Laptop Embedded Controller.
It is written in Python with a GTK4 Adwaita theme, and uses the `CrOS_EC_Python` library to communicate with the EC.
It is written in Python with a GTK4 Adwaita theme, and uses the [`CrOS_EC_Python`](https://github.com/Steve-Tech/CrOS_EC_Python) library to communicate with the EC.
It has support for fan control, temperature monitoring, LED control, and battery limiting.
@@ -36,6 +36,11 @@ Install the package with `pip install yafi`.
Pipx is also supported.
### Windows
It is possible to run YAFI on Windows using [gvsbuild](https://github.com/wingtk/gvsbuild/) and installing YAFI via pip. You will also need to copy `WinRing0x64.dll` and `WinRing0x64.sys` to either the same
directory as `python.exe`, or to `C:\Windows\System32`.
## Screenshots
### Fan Control and Temperature Monitoring

View File

@@ -41,7 +41,7 @@
]
},
"build-commands": [
"pip3 install --prefix=${FLATPAK_DEST} --no-cache-dir \"cros_ec_python>=0.0.2\""
"pip3 install --prefix=${FLATPAK_DEST} --no-cache-dir \"cros_ec_python>=0.0.4\""
]
}
]

5
pyinstaller/winyafi.py Normal file
View File

@@ -0,0 +1,5 @@
import os
os.environ["GDK_SCALE"] = "2"
from yafi import main
main()

44
pyinstaller/winyafi.spec Executable file
View File

@@ -0,0 +1,44 @@
# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_data_files
datas = [('LpcCrOSEC.bin', '.')]
datas += collect_data_files('yafi')
a = Analysis(
['winyafi.py'],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=['cros_ec_python'],
hookspath=[],
hooksconfig={"gi":{"module-versions": {"Gtk": "4.0"}}},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=2,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='winyafi',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['yafi.ico'],
uac_admin=True,
)

BIN
pyinstaller/yafi.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,6 +1,6 @@
[project]
name = "yafi"
version = "0.1"
version = "0.3"
authors = [
{ name="Steve-Tech" }
]
@@ -8,7 +8,7 @@ description = "Yet Another Framework Interface"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"cros_ec_python >= 0.0.2",
"cros_ec_python >= 0.0.4",
"PyGObject"
]
classifiers = [

View File

@@ -31,8 +31,10 @@ class BatteryPage(Gtk.Box):
chg_limit_enable = Gtk.Template.Child()
chg_limit = Gtk.Template.Child()
chg_limit_label = Gtk.Template.Child()
chg_limit_scale = Gtk.Template.Child()
bat_limit = Gtk.Template.Child()
bat_limit_label = Gtk.Template.Child()
bat_limit_scale = Gtk.Template.Child()
chg_limit_override = Gtk.Template.Child()
chg_limit_override_btn = Gtk.Template.Child()
@@ -56,7 +58,9 @@ class BatteryPage(Gtk.Box):
self.chg_limit_enable.set_active(ec_limit_enabled)
if ec_limit_enabled:
self.chg_limit_scale.set_value(ec_limit[0])
self.chg_limit_label.set_label(f"{ec_limit[0]}%")
self.bat_limit_scale.set_value(ec_limit[1])
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
self.chg_limit.set_sensitive(True)
self.bat_limit.set_sensitive(True)
self.chg_limit_override.set_sensitive(True)
@@ -103,7 +107,7 @@ class BatteryPage(Gtk.Box):
)
except ec_exceptions.ECError as e:
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT)
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
self.chg_limit_enable.set_sensitive(False)
else:
raise e
@@ -182,9 +186,24 @@ class BatteryPage(Gtk.Box):
)
def _update_battery(self, app):
if ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER in app.no_support:
return False
success = False
# Charge Limiter
if not ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL in app.no_support:
try:
ec_limit = ec_commands.framework_laptop.get_charge_limit(app.cros_ec)
self.chg_limit_label.set_label(f"{ec_limit[0]}%")
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
success = True
except ec_exceptions.ECError as e:
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
else:
raise e
# Battery Extender
if not ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER in app.no_support:
try:
ec_extender = ec_commands.framework_laptop.get_battery_extender(
app.cros_ec
@@ -197,16 +216,17 @@ class BatteryPage(Gtk.Box):
self.bat_ext_reset_time.set_subtitle(
format_timedelta(ec_extender["reset_timedelta"])
)
success = True
except ec_exceptions.ECError as e:
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
app.no_support.append(
ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER
)
return False
else:
raise e
return app.current_page == 2
return app.current_page == 2 and success
def format_timedelta(timedelta):
days = f"{timedelta.days} days, " if timedelta.days else ""

View File

@@ -95,6 +95,8 @@ class LedsPage(Gtk.Box):
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
def add_colours(strings, led_id):
# Auto and Off should already be present
if strings.get_n_items() <= 2:
supported_colours = ec_commands.leds.led_control_get_max_values(
app.cros_ec, led_id
)

View File

@@ -121,7 +121,7 @@ class YafiApplication(Adw.Application):
developers=["Stephen Horvath"],
issue_url="https://github.com/Steve-Tech/YAFI/issues",
license_type=Gtk.License.GPL_2_0,
version="0.1.0",
version="0.3",
website="https://github.com/Steve-Tech/YAFI",
)
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])

View File

@@ -29,6 +29,9 @@
<property name="title">Charge Limit</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="chg_limit_label"/>
</child>
<child>
<object class="GtkScale" id="chg_limit_scale">
<property name="adjustment">
@@ -54,6 +57,9 @@
<property name="title">Discharge Limit</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="bat_limit_label"/>
</child>
<child>
<object class="GtkScale" id="bat_limit_scale">
<property name="adjustment">

View File

@@ -60,7 +60,7 @@
(4,3,"AdwActionRow",None,2,None,None,None,0,None,None),
(4,4,"AdwActionRow","chg_limit",2,None,None,None,2,None,None),
(4,5,"GtkBox",None,4,None,None,None,0,None,None),
(4,6,"GtkScale","chg_limit_scale",5,None,None,None,0,None,None),
(4,6,"GtkScale","chg_limit_scale",5,None,None,None,1,None,None),
(4,7,"GtkAdjustment",None,6,None,None,None,0,None,None),
(4,13,"AdwPreferencesGroup","bat_ext_group",2,None,None,None,5,None,None),
(4,27,"AdwSpinRow","bat_ext_trigger",13,None,None,None,5,None,None),
@@ -71,7 +71,7 @@
(4,32,"AdwSwitchRow","bat_ext_enable",13,None,None,None,1,None,None),
(4,33,"AdwActionRow","bat_limit",2,None,None,None,3,None,None),
(4,34,"GtkBox",None,33,None,None,None,0,None,None),
(4,35,"GtkScale","bat_limit_scale",34,None,None,None,0,None,None),
(4,35,"GtkScale","bat_limit_scale",34,None,None,None,1,None,None),
(4,36,"GtkAdjustment",None,35,None,None,None,0,None,None),
(4,37,"AdwActionRow","chg_limit_override",2,None,None,None,4,None,None),
(4,38,"GtkBox",None,37,None,None,None,0,None,None),
@@ -79,6 +79,8 @@
(4,40,"AdwSwitchRow","chg_limit_enable",2,None,None,None,1,None,None),
(4,41,"AdwActionRow","bat_ext_trigger_time",13,None,None,None,3,None,None),
(4,42,"AdwActionRow","bat_ext_reset_time",13,None,None,None,4,None,None),
(4,43,"GtkLabel","chg_limit_label",5,None,None,None,0,None,None),
(4,44,"GtkLabel","bat_limit_label",34,None,None,None,0,None,None),
(5,1,"GtkBox","HardwarePage",None,None,None,None,0,None,None),
(5,2,"GtkListBox",None,1,None,None,None,0,None,None),
(5,3,"AdwActionRow",None,2,None,None,None,0,None,None),

Binary file not shown.

View File

@@ -7,4 +7,8 @@
<file preprocess="xml-stripblanks">ui/battery.ui</file>
<file preprocess="xml-stripblanks">ui/hardware.ui</file>
</gresource>
<gresource prefix="/au/stevetech/yafi/icons/scalable/actions">
<file alias="au.stevetech.yafi.svg" preprocess="xml-stripblanks">../data/icons/hicolor/scalable/apps/au.stevetech.yafi.svg</file>
<file alias="au.stevetech.yafi-symbolic.svg" preprocess="xml-stripblanks">../data/icons/hicolor/symbolic/apps/au.stevetech.yafi-symbolic.svg</file>
</gresource>
</gresources>