mirror of
https://github.com/Steve-Tech/YAFI.git
synced 2026-04-20 01:00:37 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa5442d5fd | ||
|
|
09f072a150 | ||
|
|
f2cf2c7923 | ||
|
|
35f9c766b9 | ||
|
|
8b33f75b86 | ||
|
|
076f903fbc | ||
|
|
d65a033523 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -30,7 +30,7 @@ MANIFEST
|
|||||||
# Usually these files are written by a python script from a template
|
# 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.
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
*.manifest
|
*.manifest
|
||||||
*.spec
|
#*.spec
|
||||||
|
|
||||||
# Installer logs
|
# Installer logs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
@@ -175,3 +175,6 @@ cython_debug/
|
|||||||
|
|
||||||
# Flatpak builder
|
# Flatpak builder
|
||||||
.flatpak-builder/
|
.flatpak-builder/
|
||||||
|
|
||||||
|
# Binary files
|
||||||
|
*.bin
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
include yafi/ui/*.ui
|
|
||||||
include yafi/yafi.gresource
|
include yafi/yafi.gresource
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Yet Another Framework Interface
|
# Yet Another Framework Interface
|
||||||
|
|
||||||
YAFI is another GUI for the Framework Laptop Embedded Controller.
|
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.
|
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.
|
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
|
## Screenshots
|
||||||
|
|
||||||
### Fan Control and Temperature Monitoring
|
### Fan Control and Temperature Monitoring
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"build-commands": [
|
"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
5
pyinstaller/winyafi.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import os
|
||||||
|
os.environ["GDK_SCALE"] = "2"
|
||||||
|
|
||||||
|
from yafi import main
|
||||||
|
main()
|
||||||
44
pyinstaller/winyafi.spec
Executable file
44
pyinstaller/winyafi.spec
Executable 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
BIN
pyinstaller/yafi.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "yafi"
|
name = "yafi"
|
||||||
version = "0.1"
|
version = "0.3"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Steve-Tech" }
|
{ name="Steve-Tech" }
|
||||||
]
|
]
|
||||||
@@ -8,7 +8,7 @@ description = "Yet Another Framework Interface"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cros_ec_python >= 0.0.2",
|
"cros_ec_python >= 0.0.4",
|
||||||
"PyGObject"
|
"PyGObject"
|
||||||
]
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ class BatteryPage(Gtk.Box):
|
|||||||
|
|
||||||
chg_limit_enable = Gtk.Template.Child()
|
chg_limit_enable = Gtk.Template.Child()
|
||||||
chg_limit = Gtk.Template.Child()
|
chg_limit = Gtk.Template.Child()
|
||||||
|
chg_limit_label = Gtk.Template.Child()
|
||||||
chg_limit_scale = Gtk.Template.Child()
|
chg_limit_scale = Gtk.Template.Child()
|
||||||
bat_limit = Gtk.Template.Child()
|
bat_limit = Gtk.Template.Child()
|
||||||
|
bat_limit_label = Gtk.Template.Child()
|
||||||
bat_limit_scale = Gtk.Template.Child()
|
bat_limit_scale = Gtk.Template.Child()
|
||||||
chg_limit_override = Gtk.Template.Child()
|
chg_limit_override = Gtk.Template.Child()
|
||||||
chg_limit_override_btn = 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)
|
self.chg_limit_enable.set_active(ec_limit_enabled)
|
||||||
if ec_limit_enabled:
|
if ec_limit_enabled:
|
||||||
self.chg_limit_scale.set_value(ec_limit[0])
|
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_scale.set_value(ec_limit[1])
|
||||||
|
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
|
||||||
self.chg_limit.set_sensitive(True)
|
self.chg_limit.set_sensitive(True)
|
||||||
self.bat_limit.set_sensitive(True)
|
self.bat_limit.set_sensitive(True)
|
||||||
self.chg_limit_override.set_sensitive(True)
|
self.chg_limit_override.set_sensitive(True)
|
||||||
@@ -103,7 +107,7 @@ class BatteryPage(Gtk.Box):
|
|||||||
)
|
)
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
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)
|
self.chg_limit_enable.set_sensitive(False)
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
@@ -182,9 +186,24 @@ class BatteryPage(Gtk.Box):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _update_battery(self, app):
|
def _update_battery(self, app):
|
||||||
if ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER in app.no_support:
|
success = False
|
||||||
return 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:
|
try:
|
||||||
ec_extender = ec_commands.framework_laptop.get_battery_extender(
|
ec_extender = ec_commands.framework_laptop.get_battery_extender(
|
||||||
app.cros_ec
|
app.cros_ec
|
||||||
@@ -197,16 +216,17 @@ class BatteryPage(Gtk.Box):
|
|||||||
self.bat_ext_reset_time.set_subtitle(
|
self.bat_ext_reset_time.set_subtitle(
|
||||||
format_timedelta(ec_extender["reset_timedelta"])
|
format_timedelta(ec_extender["reset_timedelta"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
success = True
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(
|
app.no_support.append(
|
||||||
ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER
|
ec_commands.framework_laptop.EC_CMD_BATTERY_EXTENDER
|
||||||
)
|
)
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return app.current_page == 2
|
return app.current_page == 2 and success
|
||||||
|
|
||||||
def format_timedelta(timedelta):
|
def format_timedelta(timedelta):
|
||||||
days = f"{timedelta.days} days, " if timedelta.days else ""
|
days = f"{timedelta.days} days, " if timedelta.days else ""
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ class LedsPage(Gtk.Box):
|
|||||||
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
||||||
|
|
||||||
def add_colours(strings, led_id):
|
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(
|
supported_colours = ec_commands.leds.led_control_get_max_values(
|
||||||
app.cros_ec, led_id
|
app.cros_ec, led_id
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class YafiApplication(Adw.Application):
|
|||||||
developers=["Stephen Horvath"],
|
developers=["Stephen Horvath"],
|
||||||
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
||||||
license_type=Gtk.License.GPL_2_0,
|
license_type=Gtk.License.GPL_2_0,
|
||||||
version="0.1.0",
|
version="0.3",
|
||||||
website="https://github.com/Steve-Tech/YAFI",
|
website="https://github.com/Steve-Tech/YAFI",
|
||||||
)
|
)
|
||||||
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
<property name="title">Charge Limit</property>
|
<property name="title">Charge Limit</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="chg_limit_label"/>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScale" id="chg_limit_scale">
|
<object class="GtkScale" id="chg_limit_scale">
|
||||||
<property name="adjustment">
|
<property name="adjustment">
|
||||||
@@ -54,6 +57,9 @@
|
|||||||
<property name="title">Discharge Limit</property>
|
<property name="title">Discharge Limit</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="bat_limit_label"/>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScale" id="bat_limit_scale">
|
<object class="GtkScale" id="bat_limit_scale">
|
||||||
<property name="adjustment">
|
<property name="adjustment">
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
(4,3,"AdwActionRow",None,2,None,None,None,0,None,None),
|
(4,3,"AdwActionRow",None,2,None,None,None,0,None,None),
|
||||||
(4,4,"AdwActionRow","chg_limit",2,None,None,None,2,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,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,7,"GtkAdjustment",None,6,None,None,None,0,None,None),
|
||||||
(4,13,"AdwPreferencesGroup","bat_ext_group",2,None,None,None,5,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),
|
(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,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,33,"AdwActionRow","bat_limit",2,None,None,None,3,None,None),
|
||||||
(4,34,"GtkBox",None,33,None,None,None,0,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,36,"GtkAdjustment",None,35,None,None,None,0,None,None),
|
||||||
(4,37,"AdwActionRow","chg_limit_override",2,None,None,None,4,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),
|
(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,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,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,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,1,"GtkBox","HardwarePage",None,None,None,None,0,None,None),
|
||||||
(5,2,"GtkListBox",None,1,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),
|
(5,3,"AdwActionRow",None,2,None,None,None,0,None,None),
|
||||||
|
|||||||
Binary file not shown.
@@ -7,4 +7,8 @@
|
|||||||
<file preprocess="xml-stripblanks">ui/battery.ui</file>
|
<file preprocess="xml-stripblanks">ui/battery.ui</file>
|
||||||
<file preprocess="xml-stripblanks">ui/hardware.ui</file>
|
<file preprocess="xml-stripblanks">ui/hardware.ui</file>
|
||||||
</gresource>
|
</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>
|
</gresources>
|
||||||
|
|||||||
Reference in New Issue
Block a user