Compare commits
55 Commits
0.3
...
43de4d979d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43de4d979d | ||
|
|
d1ea86f694 | ||
|
|
aa8e05f676 | ||
|
|
f45cb3db36 | ||
|
|
a91556e3e6 | ||
|
|
f8f043cf48 | ||
|
|
8453f41914 | ||
|
|
a0ba66ab99 | ||
|
|
7c89b4197f | ||
|
|
c9b659e22a | ||
|
|
3e7873de8f | ||
|
|
988aabea07 | ||
|
|
804ae3fcb6 | ||
|
|
a97148f7a5 | ||
|
|
8b10c49ed4 | ||
|
|
f31054c18b | ||
|
|
2b50f0816f | ||
|
|
1fc4b94237 | ||
|
|
90a994a685 | ||
|
|
7b123da001 | ||
|
|
c8fd626446 | ||
|
|
0f6fee40ae | ||
|
|
4a788c2395 | ||
|
|
d2f34c9b5a | ||
|
|
4958722edd | ||
|
|
23b54ee397 | ||
|
|
73bb7abf6e | ||
|
|
9f0fabb91f | ||
|
|
a31f851707 | ||
|
|
70d3788dd6 | ||
|
|
f3b74ccc02 | ||
|
|
335a0881b3 | ||
|
|
c39a88b7db | ||
|
|
ba78392b24 | ||
|
|
c1205c7661 | ||
|
|
973ff26fa7 | ||
|
|
4a8dfbad47 | ||
|
|
2a0675d3be | ||
|
|
55580535db | ||
|
|
8fcb2098cb | ||
|
|
3c55f8fdd6 | ||
|
|
b5dfa93dcf | ||
|
|
154be557ed | ||
|
|
624fed2c71 | ||
|
|
f50a11deaa | ||
|
|
923c06a3f1 | ||
|
|
4aa15708be | ||
|
|
1c6131c61d | ||
|
|
3129e10de2 | ||
|
|
875c06dad1 | ||
|
|
ad099ff5e7 | ||
|
|
5f514ab6bb | ||
|
|
1dd85c5fa3 | ||
|
|
2c02c00268 | ||
|
|
e7b4e4d194 |
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
github: [Steve-Tech]
|
||||
thanks_dev: u/gh/steve-tech
|
||||
8
.github/workflows/flatpak.yml
vendored
@@ -2,18 +2,18 @@ name: Flatpak Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-47
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
- uses: actions/checkout@v6
|
||||
- name: Build Flatpak
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: yafi-${{ github.sha }}.flatpak
|
||||
manifest-path: au.stevetech.yafi.json
|
||||
|
||||
30
.github/workflows/pyinstaller-linux.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: PyInstaller Build Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pyinstaller-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# We shouldn't use actions/setup-python since PyGObject is compiled against the system Python
|
||||
- name: Install System Dependencies
|
||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 libglib2.0-bin python3-tk
|
||||
version: 0
|
||||
- name: Install PyInstaller
|
||||
run: pip install pyinstaller
|
||||
- name: Build YAFI via Pip
|
||||
run: pip install .
|
||||
- name: Build with PyInstaller
|
||||
# pyinstaller doesn't find the GTK libraries after caching?
|
||||
run: LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu pyinstaller yafi.spec -- --onefile
|
||||
working-directory: pyinstaller
|
||||
- name: Upload PyInstaller Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
path: pyinstaller/dist/YAFI
|
||||
name: yafi-linux-${{ github.sha }}
|
||||
62
.github/workflows/pyinstaller-windows.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: PyInstaller Build Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pyinstaller-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.14'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Cache GTK4
|
||||
id: cache-gtk4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: C:\gtk
|
||||
key: Gvsbuild_2026.2.0
|
||||
|
||||
- name: Download GTK4 Gvsbuild zip
|
||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||
run: Start-BitsTransfer -Source https://github.com/wingtk/gvsbuild/releases/download/2026.2.0/GTK4_Gvsbuild_2026.2.0_x64.zip -Destination Gvsbuild.zip
|
||||
|
||||
- name: Extract Gvsbuild zip
|
||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||
run: Expand-Archive -Path Gvsbuild.zip -DestinationPath C:\gtk -Force
|
||||
|
||||
- name: Add GTK bin to PATH
|
||||
run: echo "C:\gtk\bin" | Out-File -Append -Encoding ascii $env:GITHUB_PATH
|
||||
|
||||
- name: Install PyGObject wheel
|
||||
run: pip install --force-reinstall (Resolve-Path C:\gtk\wheels\PyGObject*.whl) (Resolve-Path C:\gtk\wheels\pycairo*.whl)
|
||||
|
||||
- name: Install PyInstaller
|
||||
run: pip install pyinstaller
|
||||
|
||||
- name: Build YAFI via Pip
|
||||
run: pip install .
|
||||
|
||||
- name: Build with PyInstaller (ZIP)
|
||||
run: python -m PyInstaller yafi.spec
|
||||
working-directory: pyinstaller
|
||||
|
||||
- name: Upload PyInstaller Artifact (ZIP)
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
path: pyinstaller/dist/YAFI/*
|
||||
name: yafi-windows-${{ github.sha }}
|
||||
|
||||
- name: Build with PyInstaller (Standalone)
|
||||
run: python -m PyInstaller yafi.spec --noconfirm -- --onefile
|
||||
working-directory: pyinstaller
|
||||
|
||||
- name: Upload PyInstaller Artifact (Standalone)
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
path: pyinstaller/dist/YAFI.exe
|
||||
name: yafi-windows-standalone-${{ github.sha }}
|
||||
1
.gitignore
vendored
@@ -178,3 +178,4 @@ cython_debug/
|
||||
|
||||
# Binary files
|
||||
*.bin
|
||||
!pyinstaller/LpcCrOSEC.bin
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# CrOS_EC_Python udev rules
|
||||
|
||||
# LPC Access
|
||||
KERNEL=="port", TAG+="uaccess"
|
||||
|
||||
# /dev/cros_ec Access
|
||||
KERNEL=="cros_ec", TAG+="uaccess"
|
||||
53
README.md
@@ -7,9 +7,25 @@ It has support for fan control, temperature monitoring, LED control, and battery
|
||||
|
||||
## Installation
|
||||
|
||||
### udev Rules (MUST READ)
|
||||
You can download the latest release from the [Releases page](https://github.com/Steve-Tech/YAFI/releases).
|
||||
|
||||
To allow YAFI to communicate with the EC, you need to copy the [`60-cros_ec_python.rules`](https://github.com/Steve-Tech/YAFI/blob/main/60-cros_ec_python.rules) file to `/etc/udev/rules.d/` and reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||
There are builds for Flatpak, and PyInstaller for portable execution on Linux or Windows.
|
||||
|
||||
YAFI is also available on [Flathub](https://flathub.org/en/apps/au.stevetech.yafi): `flatpak install flathub au.stevetech.yafi`.
|
||||
|
||||
### Linux
|
||||
|
||||
To allow YAFI to communicate with the EC, you will need to enable user access to the `/dev/cros_ec` device. You can do this by running `echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" | sudo tee /etc/udev/rules.d/60-yafi.rules`, and then reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||
|
||||
You can also do this by running `curl -Lfs yafi.stevetech.au/udev.sh | sudo sh` which will run the [`add-udev-rules.sh`](add-udev-rules.sh) script.
|
||||
|
||||
### Windows
|
||||
|
||||
If your Laptop's BIOS supports Framework's EC driver, there is no need to install any third-party drivers. YAFI should also work without administrator privileges.
|
||||
|
||||
Otherwise, YAFI supports the [PawnIO](https://pawnio.eu/) driver, and will be automatically used if installed and there is no Framework driver available. YAFI will need to be run as administrator to communicate with the driver.
|
||||
|
||||
## Building
|
||||
|
||||
### Flatpak
|
||||
|
||||
@@ -21,14 +37,12 @@ You can also create a flatpak bundle with `flatpak-builder --repo=repo build au.
|
||||
|
||||
#### System Dependencies
|
||||
|
||||
The following system dependencies are required for `PyGObject`:
|
||||
This project requires PyGObject, and the introspection data for GTK4 and Adwaita.
|
||||
On Debian/Ubuntu, you can install these with:
|
||||
|
||||
- `python3-dev`
|
||||
- `libcairo2-dev`
|
||||
- `libgirepository-2.0-dev`
|
||||
- `gir1.2-adw-1`
|
||||
|
||||
There's probably more, but I happened to have them installed.
|
||||
```bash
|
||||
sudo apt install python3-gi gir1.2-gtk-4.0 gir1.2-adw-1
|
||||
```
|
||||
|
||||
#### Install
|
||||
|
||||
@@ -38,8 +52,7 @@ 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`.
|
||||
It is possible to run YAFI on Windows using [gvsbuild](https://github.com/wingtk/gvsbuild/) and installing YAFI via pip, but it can be complicated and is therefore not recommended.
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -51,23 +64,27 @@ directory as `python.exe`, or to `C:\Windows\System32`.
|
||||
|
||||

|
||||
|
||||
### Battery Limiting
|
||||
### Battery Statistics
|
||||
|
||||

|
||||
|
||||
### Battery Limiting
|
||||
|
||||

|
||||
|
||||
#### Battery Extender
|
||||
|
||||

|
||||

|
||||
|
||||
### Hardware Info
|
||||
|
||||

|
||||

|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `[Errno 13] Permission denied: '/dev/cros_ec'`
|
||||
|
||||
This error occurs when the udev rules are not installed or not working. Make sure you have copied the `60-cros_ec_python.rules` file to `/etc/udev/rules.d/` and reloaded the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||
This error occurs when the udev rules are not installed or not working. Make sure you have installed the udev rules as described in the [Linux Installation](#linux) section.
|
||||
|
||||
### `Could not auto detect device, check you have the required permissions, or specify manually.`
|
||||
|
||||
@@ -75,3 +92,9 @@ This error occurs when `/dev/cros_ec` is not found, and the `CrOS_EC_Python` lib
|
||||
You can either update your kernel to have a working `cros_ec_dev` driver, or run YAFI as root.
|
||||
|
||||
It can also occur if you do not have a CrOS EC, like on non Framework laptops.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
YAFI is not affiliated with Framework Computer Inc. in any way.
|
||||
|
||||
YAFI is licensed under the [GPL-2.0-or-later license](COPYING), and comes with no warranty or guarantee of any kind. Use at your own risk.
|
||||
|
||||
7
add-udev-rules.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo Installing udev rules for YAFI to /etc/udev/rules.d/60-yafi.rules
|
||||
echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" > /etc/udev/rules.d/60-yafi.rules
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger
|
||||
echo udev rules installed successfully.
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"id" : "au.stevetech.yafi",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "48",
|
||||
"runtime-version" : "49",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "yafi",
|
||||
"finish-args" : [
|
||||
"--device=all",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland"
|
||||
"--socket=wayland",
|
||||
"--share=ipc"
|
||||
],
|
||||
"cleanup" : [
|
||||
"/include",
|
||||
@@ -21,6 +22,7 @@
|
||||
"*.a"
|
||||
],
|
||||
"modules" : [
|
||||
"python3-cros_ec_python.json",
|
||||
{
|
||||
"name" : "yafi",
|
||||
"builddir" : true,
|
||||
@@ -31,18 +33,6 @@
|
||||
"path" : "."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cros_ec_python",
|
||||
"buildsystem": "simple",
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
]
|
||||
},
|
||||
"build-commands": [
|
||||
"pip3 install --prefix=${FLATPAK_DEST} --no-cache-dir \"cros_ec_python>=0.0.4\""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ Comment=Yet Another Framework Interface
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
Keywords=GTK;
|
||||
Keywords=Framework;EC;Embedded Controller;
|
||||
StartupNotify=true
|
||||
DBusActivatable=true
|
||||
|
||||
@@ -7,11 +7,25 @@
|
||||
<name>Yet Another Framework Interface</name>
|
||||
<summary>YAFI is another GUI for the Framework Laptop Embedded Controller</summary>
|
||||
<description>
|
||||
<p>It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.</p>
|
||||
<p>It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.</p>
|
||||
<p>YAFI has the capability for the following features:</p>
|
||||
<ul>
|
||||
<li>Fan control and temperature monitoring</li>
|
||||
<li>LED control</li>
|
||||
<li>Battery statistics</li>
|
||||
<li>Battery limiting</li>
|
||||
<li>Hardware information</li>
|
||||
</ul>
|
||||
|
||||
<p>You will need to install the udev rules to allow non-root access to the EC device. See the README for more information.</p>
|
||||
|
||||
<p>Alternatively, you can run <code>curl -Lfs yafi.stevetech.au/udev.sh | sudo sh</code> to install the udev rules.</p>
|
||||
|
||||
<p>YAFI is not affiliated with Framework Computer Inc. in any way.</p>
|
||||
</description>
|
||||
|
||||
<developer id="au.stevetech">
|
||||
<name>Stephen Horvath</name>
|
||||
<name translate="no">Stephen Horvath</name>
|
||||
</developer>
|
||||
|
||||
<!-- Required: Should be a link to the upstream homepage for the component -->
|
||||
@@ -27,7 +41,7 @@
|
||||
<!-- Should provide a web link to an online user's reference, a software manual or help page -->
|
||||
<!-- <url type="help">https://example.org/help</url> -->
|
||||
<!-- URLs of this type should point to a webpage showing information on how to donate to the described software project -->
|
||||
<!-- <url type="donation">https://example.org/donate</url> -->
|
||||
<url type="donation">https://github.com/sponsors/Steve-Tech</url>
|
||||
<!-- This could for example be an HTTPS URL to an online form or a page describing how to contact the developer -->
|
||||
<!-- <url type="contact">https://example.org/contact</url> -->
|
||||
<!-- URLs of this type should point to a webpage showing information on how to contribute to the described software project -->
|
||||
@@ -42,42 +56,104 @@
|
||||
|
||||
<!-- Applications should set a brand color in both light and dark variants like so -->
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#ff00ff</color>
|
||||
<color type="primary" scheme_preference="dark">#993d3d</color>
|
||||
<color type="primary" scheme_preference="light">#7c916f</color>
|
||||
<color type="primary" scheme_preference="dark">#282000</color>
|
||||
</branding>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/1-thermal.png</image>
|
||||
<caption>The Thermal page</caption>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/1-thermals.png</image>
|
||||
<caption>Fan Control and Temperature Monitoring</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/2-leds.png</image>
|
||||
<caption>The LED page</caption>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/2-leds.png</image>
|
||||
<caption>LED Control</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/3-battery.png</image>
|
||||
<caption>The Battery page</caption>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/3-battery.png</image>
|
||||
<caption>Battery Statistics</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/4-hardware.png</image>
|
||||
<caption>The Hardware page</caption>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4-battery-limit.png</image>
|
||||
<caption>Battery Limiting</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4a-battery-ext.png</image>
|
||||
<caption>Battery Extender</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/5-hardware.png</image>
|
||||
<caption>Hardware Info</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<release version="0.1.0" date="2025-03-20">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.1.0</url>
|
||||
<description translate="no">
|
||||
<p>First release</p>
|
||||
<release version="1.0" date="2026-03-21">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/1.0</url>
|
||||
<description>
|
||||
<p>The following changes have been made:</p>
|
||||
<ul>
|
||||
<li>Added Thermal page</li>
|
||||
<li>Added LED page</li>
|
||||
<li>Added Battery page</li>
|
||||
<li>Added Hardware page</li>
|
||||
<li>New logo matching the GNOME style!</li>
|
||||
<li>Errored temperature sensors will now show as 'Error'.</li>
|
||||
<li>Fix for battery page when battery isn't present.</li>
|
||||
<li>Fix some minor UI bugs.</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.7" date="2025-12-25">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.7</url>
|
||||
<description>
|
||||
<p>YAFI now supports modifying fan set points.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.6" date="2025-09-28">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.6</url>
|
||||
<description>
|
||||
<p>The following changes have been made:</p>
|
||||
<ul>
|
||||
<li>YAFI now has a new logo!</li>
|
||||
<li>The advanced LED settings now detect available LEDs.</li>
|
||||
<li>The ALS and lid open sensor has been added.</li>
|
||||
<li>Stuttering has been reduced when opening the about dialog.</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.5" date="2025-09-16">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.5</url>
|
||||
<description>
|
||||
<p>The following bugs have been fixed:</p>
|
||||
<ul>
|
||||
<li>LED page crashing when encountering unsupported LEDs.</li>
|
||||
<li>Scaling issues on Windows.</li>
|
||||
<li>Minimum charge limiter doesn't work.</li>
|
||||
</ul>
|
||||
<p>This release also adds a traceback to the debug info, when there is an error during initialisation.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.4" date="2025-09-06">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.4</url>
|
||||
<description>
|
||||
<p>This release also adds a new battery statistics page.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.3" date="2025-04-13">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.3</url>
|
||||
<description>
|
||||
<p>YAFI now shows the battery limiter value.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.2" date="2025-03-24">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.2</url>
|
||||
<description>
|
||||
<p>This fixes an LED list bug.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.1" date="2025-03-20">
|
||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.1</url>
|
||||
<description>
|
||||
<p>This is the first release of YAFI.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
|
||||
</component>
|
||||
|
||||
@@ -1,36 +1,92 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1755 4883 c-120 -22 -418 -180 -609 -322 -118 -89 -148 -118 -177
|
||||
-177 -23 -48 -24 -57 -27 -314 -1 -146 -7 -294 -13 -330 -18 -110 -78 -222
|
||||
-163 -303 -46 -43 -69 -58 -305 -197 -191 -112 -222 -139 -257 -214 -33 -73
|
||||
-39 -145 -39 -461 0 -297 5 -360 33 -440 25 -73 77 -118 257 -224 88 -51 187
|
||||
-111 220 -132 123 -79 192 -169 245 -319 8 -21 14 -110 16 -230 8 -403 9 -423
|
||||
29 -460 32 -61 56 -88 134 -148 234 -181 550 -347 676 -356 75 -5 116 12 306
|
||||
125 181 108 307 175 330 176 8 1 35 5 61 11 70 14 174 5 251 -23 38 -13 164
|
||||
-81 281 -149 286 -168 312 -173 494 -90 41 19 75 34 77 34 4 0 201 110 243
|
||||
135 45 27 147 100 213 153 51 40 83 75 104 113 l30 54 6 310 c5 280 8 315 27
|
||||
365 58 156 137 245 295 336 246 140 346 205 376 243 35 44 60 106 67 166 2 22
|
||||
8 74 13 115 9 78 7 442 -4 520 -12 97 -16 116 -27 150 -16 52 -61 113 -105
|
||||
142 -21 14 -126 78 -233 141 -107 64 -209 128 -225 144 -51 48 -101 115 -128
|
||||
173 -48 105 -56 163 -56 454 -1 262 -1 270 -25 321 -24 53 -65 100 -124 145
|
||||
-19 14 -46 34 -60 46 -42 32 -190 128 -257 164 -250 138 -384 177 -476 140
|
||||
-19 -8 -101 -54 -184 -104 -316 -188 -340 -198 -480 -199 -153 -1 -181 10
|
||||
-501 201 -178 106 -237 128 -309 115z m984 -848 c149 -19 308 -68 441 -135 68
|
||||
-34 181 -100 190 -110 3 -3 21 -17 40 -30 52 -37 75 -57 166 -148 150 -151
|
||||
281 -364 345 -562 33 -102 32 -99 56 -210 18 -86 26 -378 13 -455 -5 -27 -12
|
||||
-68 -15 -90 -16 -102 -64 -250 -117 -364 -211 -450 -634 -764 -1113 -828 -113
|
||||
-15 -425 -7 -455 12 -4 2 -22 7 -41 10 -150 26 -404 140 -531 239 -14 12 -41
|
||||
32 -59 46 -115 85 -291 299 -371 449 -78 148 -144 353 -165 516 -10 76 -10
|
||||
311 0 390 15 117 58 274 106 390 116 278 347 543 608 696 158 92 386 169 549
|
||||
184 38 4 70 8 72 9 5 6 229 -2 281 -9z"/>
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
||||
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
||||
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
||||
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
||||
<g filter="url(#filter0_i_293_18)">
|
||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_293_18)">
|
||||
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#404040"/>
|
||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.06" stop-color="#606060"/>
|
||||
<stop offset="0.94" stop-color="#606060"/>
|
||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||
<stop offset="1" stop-color="#404040"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#404040"/>
|
||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.06" stop-color="#606060"/>
|
||||
<stop offset="0.94" stop-color="#606060"/>
|
||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||
<stop offset="1" stop-color="#404040"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AFAFAF"/>
|
||||
<stop offset="0.04" stop-color="#F6F5F4"/>
|
||||
<stop offset="0.08" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.92" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.96" stop-color="#F6F5F4"/>
|
||||
<stop offset="1" stop-color="#AFAFAF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 8.6 KiB |
@@ -1,36 +1,4 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1755 4883 c-120 -22 -418 -180 -609 -322 -118 -89 -148 -118 -177
|
||||
-177 -23 -48 -24 -57 -27 -314 -1 -146 -7 -294 -13 -330 -18 -110 -78 -222
|
||||
-163 -303 -46 -43 -69 -58 -305 -197 -191 -112 -222 -139 -257 -214 -33 -73
|
||||
-39 -145 -39 -461 0 -297 5 -360 33 -440 25 -73 77 -118 257 -224 88 -51 187
|
||||
-111 220 -132 123 -79 192 -169 245 -319 8 -21 14 -110 16 -230 8 -403 9 -423
|
||||
29 -460 32 -61 56 -88 134 -148 234 -181 550 -347 676 -356 75 -5 116 12 306
|
||||
125 181 108 307 175 330 176 8 1 35 5 61 11 70 14 174 5 251 -23 38 -13 164
|
||||
-81 281 -149 286 -168 312 -173 494 -90 41 19 75 34 77 34 4 0 201 110 243
|
||||
135 45 27 147 100 213 153 51 40 83 75 104 113 l30 54 6 310 c5 280 8 315 27
|
||||
365 58 156 137 245 295 336 246 140 346 205 376 243 35 44 60 106 67 166 2 22
|
||||
8 74 13 115 9 78 7 442 -4 520 -12 97 -16 116 -27 150 -16 52 -61 113 -105
|
||||
142 -21 14 -126 78 -233 141 -107 64 -209 128 -225 144 -51 48 -101 115 -128
|
||||
173 -48 105 -56 163 -56 454 -1 262 -1 270 -25 321 -24 53 -65 100 -124 145
|
||||
-19 14 -46 34 -60 46 -42 32 -190 128 -257 164 -250 138 -384 177 -476 140
|
||||
-19 -8 -101 -54 -184 -104 -316 -188 -340 -198 -480 -199 -153 -1 -181 10
|
||||
-501 201 -178 106 -237 128 -309 115z m984 -848 c149 -19 308 -68 441 -135 68
|
||||
-34 181 -100 190 -110 3 -3 21 -17 40 -30 52 -37 75 -57 166 -148 150 -151
|
||||
281 -364 345 -562 33 -102 32 -99 56 -210 18 -86 26 -378 13 -455 -5 -27 -12
|
||||
-68 -15 -90 -16 -102 -64 -250 -117 -364 -211 -450 -634 -764 -1113 -828 -113
|
||||
-15 -425 -7 -455 12 -4 2 -22 7 -41 10 -150 26 -404 140 -531 239 -14 12 -41
|
||||
32 -59 46 -115 85 -291 299 -371 449 -78 148 -144 353 -165 516 -10 76 -10
|
||||
311 0 390 15 117 58 274 106 390 116 278 347 543 608 696 158 92 386 169 549
|
||||
184 38 4 70 8 72 9 5 6 229 -2 281 -9z"/>
|
||||
</g>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 0.895431 0.895431 0 2 0H3V1C3 1.55228 3.44772 2 4 2C4.55228 2 5 1.55228 5 1V0H7V1C7 1.55228 7.44772 2 8 2C8.55228 2 9 1.55228 9 1V0H11V1C11 1.55228 11.4477 2 12 2C12.5523 2 13 1.55228 13 1V0H14C15.1046 0 16 0.895431 16 2V14C16 15.1046 15.1046 16 14 16H13V15C13 14.4477 12.5523 14 12 14C11.4477 14 11 14.4477 11 15V16H9V15C9 14.4477 8.55228 14 8 14C7.44772 14 7 14.4477 7 15V16H5V15C5 14.4477 4.55228 14 4 14C3.44772 14 3 14.4477 3 15V16H2C0.895431 16 0 15.1046 0 14V2ZM5.23026 4.85673C5.04181 5.76259 4.56253 6.58395 3.86386 7.19836C3.37871 7.625 3.37871 8.375 3.86386 8.80164C4.56253 9.41605 5.04181 10.2374 5.23026 11.1433C5.36113 11.7723 6.01759 12.1473 6.6336 11.9449C7.52072 11.6535 8.47928 11.6535 9.3664 11.9449C9.98241 12.1473 10.6389 11.7723 10.7697 11.1433C10.9582 10.2374 11.4375 9.41605 12.1361 8.80164C12.6213 8.375 12.6213 7.625 12.1361 7.19836C11.4375 6.58395 10.9582 5.76259 10.7697 4.85673C10.6389 4.2277 9.98241 3.85271 9.3664 4.05509C8.47928 4.34654 7.52072 4.34654 6.6336 4.05509C6.01759 3.85271 5.36113 4.2277 5.23026 4.85673ZM8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
docs/1-thermals.png
Executable file → Normal file
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 160 KiB |
BIN
docs/2-leds.png
Executable file → Normal file
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 81 KiB |
BIN
docs/3-battery.png
Executable file → Normal file
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 154 KiB |
BIN
docs/4-battery-limit.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 90 KiB |
BIN
docs/4a-battery-ext.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
docs/5-hardware.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
3
flathub.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"only-arches": ["x86_64"]
|
||||
}
|
||||
92
logo.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
||||
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
||||
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
||||
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
||||
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
||||
<g filter="url(#filter0_i_293_18)">
|
||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_293_18)">
|
||||
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#404040"/>
|
||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.06" stop-color="#606060"/>
|
||||
<stop offset="0.94" stop-color="#606060"/>
|
||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||
<stop offset="1" stop-color="#404040"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#404040"/>
|
||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.06" stop-color="#606060"/>
|
||||
<stop offset="0.94" stop-color="#606060"/>
|
||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||
<stop offset="1" stop-color="#404040"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AFAFAF"/>
|
||||
<stop offset="0.04" stop-color="#F6F5F4"/>
|
||||
<stop offset="0.08" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.92" stop-color="#D0D0D0"/>
|
||||
<stop offset="0.96" stop-color="#F6F5F4"/>
|
||||
<stop offset="1" stop-color="#AFAFAF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
@@ -1,5 +1,5 @@
|
||||
project('yafi',
|
||||
version: '0.1.0',
|
||||
version: '1.0',
|
||||
meson_version: '>= 1.0.0',
|
||||
default_options: [ 'warning_level=2', 'werror=false', ],
|
||||
)
|
||||
|
||||
@@ -8,9 +8,11 @@ yafi/window.py
|
||||
yafi/thermals.py
|
||||
yafi/leds.py
|
||||
yafi/battery.py
|
||||
yafi/battery_limiter.py
|
||||
yafi/hardware.py
|
||||
yafi/ui/window.ui
|
||||
yafi/ui/thermals.ui
|
||||
yafi/ui/leds.ui
|
||||
yafi/ui/battery.ui
|
||||
yafi/ui/battery_limiter.ui
|
||||
yafi/ui/hardware.ui
|
||||
|
||||
BIN
pyinstaller/LpcCrOSEC.bin
Normal file
8
pyinstaller/entrypoint.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import os
|
||||
if os.name == 'nt' and os.environ.get('GDK_SCALE') is None:
|
||||
import ctypes
|
||||
scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)
|
||||
os.environ["GDK_SCALE"] = f"{round(scale_factor, -2)//100}"
|
||||
|
||||
from yafi import main
|
||||
main()
|
||||
BIN
pyinstaller/splash.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
301
pyinstaller/splash.svg
Normal file
|
After Width: | Height: | Size: 48 KiB |
@@ -1,5 +0,0 @@
|
||||
import os
|
||||
os.environ["GDK_SCALE"] = "2"
|
||||
|
||||
from yafi import main
|
||||
main()
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- 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 → Normal file
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 398 KiB |
81
pyinstaller/yafi.spec
Executable file
@@ -0,0 +1,81 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
from PyInstaller.utils.hooks import collect_data_files
|
||||
import os
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--onefile", action="store_true")
|
||||
options = parser.parse_args()
|
||||
|
||||
datas = [('LpcCrOSEC.bin', '.')] if os.name == 'nt' and os.path.exists('LpcCrOSEC.bin') else []
|
||||
datas += collect_data_files('yafi')
|
||||
|
||||
a = Analysis(
|
||||
['entrypoint.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)
|
||||
|
||||
if options.onefile:
|
||||
splash = Splash(
|
||||
'splash.png',
|
||||
binaries=a.binaries,
|
||||
datas=a.datas,
|
||||
text_pos=(4, 480),
|
||||
# Text doesn't scale on Linux, but does on Windows
|
||||
text_size=12 if os.name == 'nt' else 6,
|
||||
minify_script=True,
|
||||
always_on_top=True,
|
||||
)
|
||||
|
||||
exe_args = (
|
||||
[
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
splash,
|
||||
splash.binaries,
|
||||
]
|
||||
if options.onefile
|
||||
else [a.scripts]
|
||||
)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
*exe_args,
|
||||
exclude_binaries=not options.onefile,
|
||||
name='YAFI',
|
||||
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'],
|
||||
)
|
||||
|
||||
if not options.onefile:
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='YAFI',
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "yafi"
|
||||
version = "0.3"
|
||||
version = "1.0"
|
||||
authors = [
|
||||
{ name="Steve-Tech" }
|
||||
]
|
||||
@@ -8,11 +8,10 @@ description = "Yet Another Framework Interface"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"cros_ec_python >= 0.0.4",
|
||||
"cros_ec_python >= 0.4.0",
|
||||
"PyGObject"
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 2 - Pre-Alpha",
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
|
||||
14
python3-cros_ec_python.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "python3-cros_ec_python",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"cros_ec_python\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6c/7a/10d978a02bbe37530490cfd14e0994c433dc29c81b3afcdbde453d512528/cros_ec_python-0.3.0-py3-none-any.whl",
|
||||
"sha256": "aeb14ebdbd60ec6d6a4b11df1482a295466da4a908a468d168efd4cc141e7e3d"
|
||||
}
|
||||
]
|
||||
}
|
||||
271
yafi/battery.py
@@ -18,218 +18,89 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Adw
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk, Adw, GLib
|
||||
|
||||
import cros_ec_python.commands as ec_commands
|
||||
import cros_ec_python.exceptions as ec_exceptions
|
||||
|
||||
@Gtk.Template(resource_path='/au/stevetech/yafi/ui/battery.ui')
|
||||
|
||||
@Gtk.Template(resource_path="/au/stevetech/yafi/ui/battery.ui")
|
||||
class BatteryPage(Gtk.Box):
|
||||
__gtype_name__ = 'BatteryPage'
|
||||
__gtype_name__ = "BatteryPage"
|
||||
|
||||
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()
|
||||
batt_status = Gtk.Template.Child()
|
||||
|
||||
bat_ext_group = Gtk.Template.Child()
|
||||
bat_ext_enable = Gtk.Template.Child()
|
||||
bat_ext_stage = Gtk.Template.Child()
|
||||
bat_ext_trigger_time = Gtk.Template.Child()
|
||||
bat_ext_reset_time = Gtk.Template.Child()
|
||||
bat_ext_trigger = Gtk.Template.Child()
|
||||
bat_ext_reset = Gtk.Template.Child()
|
||||
batt_charge = Gtk.Template.Child()
|
||||
batt_health = Gtk.Template.Child()
|
||||
batt_cycles_label = Gtk.Template.Child()
|
||||
batt_volts_label = Gtk.Template.Child()
|
||||
batt_watts_label = Gtk.Template.Child()
|
||||
batt_cap_rem_label = Gtk.Template.Child()
|
||||
batt_cap_full_label = Gtk.Template.Child()
|
||||
|
||||
batt_manu = Gtk.Template.Child()
|
||||
batt_model = Gtk.Template.Child()
|
||||
batt_serial = Gtk.Template.Child()
|
||||
batt_type = Gtk.Template.Child()
|
||||
batt_orig_cap = Gtk.Template.Child()
|
||||
batt_orig_volts = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def setup(self, app):
|
||||
# Charge limiter
|
||||
try:
|
||||
ec_limit = ec_commands.framework_laptop.get_charge_limit(app.cros_ec)
|
||||
ec_limit_enabled = ec_limit != (0, 0)
|
||||
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)
|
||||
|
||||
def handle_chg_limit_change(min, max):
|
||||
ec_commands.framework_laptop.set_charge_limit(
|
||||
app.cros_ec, int(min), int(max)
|
||||
)
|
||||
|
||||
def handle_chg_limit_enable(switch):
|
||||
active = switch.get_active()
|
||||
if active:
|
||||
handle_chg_limit_change(
|
||||
self.chg_limit_scale.get_value(), self.bat_limit_scale.get_value()
|
||||
)
|
||||
else:
|
||||
ec_commands.framework_laptop.disable_charge_limit(app.cros_ec)
|
||||
|
||||
self.chg_limit.set_sensitive(active)
|
||||
self.bat_limit.set_sensitive(active)
|
||||
self.chg_limit_override.set_sensitive(active)
|
||||
|
||||
self.chg_limit_enable.connect(
|
||||
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
||||
)
|
||||
self.chg_limit_scale.connect(
|
||||
"value-changed",
|
||||
lambda scale: handle_chg_limit_change(
|
||||
scale.get_value(), self.bat_limit_scale.get_value()
|
||||
),
|
||||
)
|
||||
self.bat_limit_scale.connect(
|
||||
"value-changed",
|
||||
lambda scale: handle_chg_limit_change(
|
||||
self.chg_limit_scale.get_value(), scale.get_value()
|
||||
),
|
||||
)
|
||||
|
||||
self.chg_limit_override_btn.connect(
|
||||
"clicked",
|
||||
lambda _: ec_commands.framework_laptop.override_charge_limit(
|
||||
app.cros_ec
|
||||
),
|
||||
)
|
||||
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)
|
||||
self.chg_limit_enable.set_sensitive(False)
|
||||
else:
|
||||
raise e
|
||||
|
||||
# Battery Extender
|
||||
try:
|
||||
ec_extender = ec_commands.framework_laptop.get_battery_extender(
|
||||
app.cros_ec
|
||||
)
|
||||
self.bat_ext_enable.set_active(not ec_extender["disable"])
|
||||
self.bat_ext_stage.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_trigger_time.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_reset_time.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_trigger.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_reset.set_sensitive(not ec_extender["disable"])
|
||||
|
||||
self.bat_ext_stage.set_subtitle(str(ec_extender["current_stage"]))
|
||||
self.bat_ext_trigger_time.set_subtitle(
|
||||
format_timedelta(ec_extender["trigger_timedelta"])
|
||||
)
|
||||
self.bat_ext_reset_time.set_subtitle(
|
||||
format_timedelta(ec_extender["reset_timedelta"])
|
||||
)
|
||||
self.bat_ext_trigger.set_value(ec_extender["trigger_days"])
|
||||
self.bat_ext_reset.set_value(ec_extender["reset_minutes"])
|
||||
|
||||
def handle_extender_enable(switch):
|
||||
active = switch.get_active()
|
||||
ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not active,
|
||||
int(self.bat_ext_trigger.get_value()),
|
||||
int(self.bat_ext_reset.get_value()),
|
||||
)
|
||||
self.bat_ext_stage.set_sensitive(active)
|
||||
self.bat_ext_trigger_time.set_sensitive(active)
|
||||
self.bat_ext_reset_time.set_sensitive(active)
|
||||
self.bat_ext_trigger.set_sensitive(active)
|
||||
self.bat_ext_reset.set_sensitive(active)
|
||||
|
||||
self.bat_ext_enable.connect(
|
||||
"notify::active", lambda switch, _: handle_extender_enable(switch)
|
||||
)
|
||||
self.bat_ext_trigger.connect(
|
||||
"notify::value",
|
||||
lambda scale, _: ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not self.bat_ext_enable.get_active(),
|
||||
int(scale.get_value()),
|
||||
int(self.bat_ext_reset.get_value()),
|
||||
),
|
||||
)
|
||||
self.bat_ext_reset.connect(
|
||||
"notify::value",
|
||||
lambda scale, _: ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not self.bat_ext_enable.get_active(),
|
||||
int(self.bat_ext_trigger.get_value()),
|
||||
int(scale.get_value()),
|
||||
),
|
||||
)
|
||||
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
|
||||
)
|
||||
self.bat_ext_group.set_visible(False)
|
||||
else:
|
||||
raise e
|
||||
|
||||
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
||||
if not battery:
|
||||
self.batt_status.set_subtitle("No data")
|
||||
return
|
||||
self.batt_manu.set_subtitle(battery["manufacturer"])
|
||||
self.batt_model.set_subtitle(battery["model"])
|
||||
self.batt_serial.set_subtitle(battery["serial"])
|
||||
self.batt_type.set_subtitle(battery["type"])
|
||||
self.batt_orig_cap.set_subtitle(f"{self._get_watts(battery, 'design_capacity'):.2f}Wh")
|
||||
self.batt_orig_volts.set_subtitle(f"{battery['design_voltage']/1000}V")
|
||||
self._update_battery(app, battery)
|
||||
# Schedule _update_battery to run every second
|
||||
GLib.timeout_add_seconds(
|
||||
1,
|
||||
self._update_battery,
|
||||
app
|
||||
GLib.timeout_add_seconds(1, self._update_battery, app)
|
||||
|
||||
def _get_watts(self, battery, key, volt_key="design_voltage"):
|
||||
return (battery[key] * battery[volt_key]) / 1000_000
|
||||
|
||||
def _update_battery(self, app, battery=None):
|
||||
if battery is None:
|
||||
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
||||
|
||||
status_messages = []
|
||||
if battery["invalid_data"]:
|
||||
status_messages.append("Invalid Data")
|
||||
if not battery["batt_present"]:
|
||||
status_messages.append("No Battery")
|
||||
if battery["ac_present"]:
|
||||
status_messages.append("Plugged in")
|
||||
if battery["level_critical"]:
|
||||
status_messages.append("Critical")
|
||||
if battery["discharging"]:
|
||||
status_messages.append("Discharging")
|
||||
if battery["charging"]:
|
||||
status_messages.append("Charging")
|
||||
self.batt_status.set_subtitle(", ".join(status_messages))
|
||||
|
||||
self.batt_charge.set_fraction(
|
||||
battery["capacity"] / battery["last_full_charge_capacity"]
|
||||
)
|
||||
self.batt_health.set_fraction(
|
||||
battery["last_full_charge_capacity"] / battery["design_capacity"]
|
||||
)
|
||||
self.batt_cycles_label.set_label(str(battery["cycle_count"]))
|
||||
self.batt_volts_label.set_label(f"{battery['volt']/1000:.2f}V")
|
||||
self.batt_watts_label.set_label(
|
||||
f"{self._get_watts(battery, 'rate', 'volt') * (-1 if battery['charging'] else 1):.2f}W"
|
||||
)
|
||||
self.batt_cap_rem_label.set_label(
|
||||
f"{self._get_watts(battery, 'capacity'):.2f}Wh"
|
||||
)
|
||||
self.batt_cap_full_label.set_label(
|
||||
f"{self._get_watts(battery, 'last_full_charge_capacity'):.2f}Wh"
|
||||
)
|
||||
|
||||
def _update_battery(self, app):
|
||||
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
|
||||
)
|
||||
|
||||
self.bat_ext_stage.set_subtitle(str(ec_extender["current_stage"]))
|
||||
self.bat_ext_trigger_time.set_subtitle(
|
||||
format_timedelta(ec_extender["trigger_timedelta"])
|
||||
)
|
||||
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
|
||||
)
|
||||
else:
|
||||
raise e
|
||||
|
||||
return app.current_page == 2 and success
|
||||
|
||||
def format_timedelta(timedelta):
|
||||
days = f"{timedelta.days} days, " if timedelta.days else ""
|
||||
hours, remainder = divmod(timedelta.seconds, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
return days + f"{hours}:{minutes:02}:{seconds:02}"
|
||||
return app.current_page == 2
|
||||
|
||||
223
yafi/battery_limiter.py
Normal file
@@ -0,0 +1,223 @@
|
||||
# battery_limiter.py
|
||||
#
|
||||
# Copyright 2025 Stephen Horvath
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Gtk, Adw, GLib
|
||||
|
||||
import cros_ec_python.commands as ec_commands
|
||||
import cros_ec_python.exceptions as ec_exceptions
|
||||
|
||||
@Gtk.Template(resource_path='/au/stevetech/yafi/ui/battery-limiter.ui')
|
||||
class BatteryLimiterPage(Gtk.Box):
|
||||
__gtype_name__ = 'BatteryLimiterPage'
|
||||
|
||||
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()
|
||||
|
||||
bat_ext_group = Gtk.Template.Child()
|
||||
bat_ext_enable = Gtk.Template.Child()
|
||||
bat_ext_stage = Gtk.Template.Child()
|
||||
bat_ext_trigger_time = Gtk.Template.Child()
|
||||
bat_ext_reset_time = Gtk.Template.Child()
|
||||
bat_ext_trigger = Gtk.Template.Child()
|
||||
bat_ext_reset = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def setup(self, app):
|
||||
# Charge limiter
|
||||
try:
|
||||
ec_limit = ec_commands.framework_laptop.get_charge_limit(app.cros_ec)
|
||||
ec_limit_enabled = ec_limit != (0, 0)
|
||||
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)
|
||||
|
||||
def handle_chg_limit_change(min, max):
|
||||
ec_commands.framework_laptop.set_charge_limit(
|
||||
app.cros_ec, int(min), int(max)
|
||||
)
|
||||
|
||||
def handle_chg_limit_enable(switch):
|
||||
active = switch.get_active()
|
||||
if active:
|
||||
handle_chg_limit_change(
|
||||
self.chg_limit_scale.get_value(), self.bat_limit_scale.get_value()
|
||||
)
|
||||
else:
|
||||
ec_commands.framework_laptop.disable_charge_limit(app.cros_ec)
|
||||
|
||||
self.chg_limit.set_sensitive(active)
|
||||
self.bat_limit.set_sensitive(active)
|
||||
|
||||
self.chg_limit_enable.connect(
|
||||
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
||||
)
|
||||
self.chg_limit_scale.connect(
|
||||
"value-changed",
|
||||
lambda scale: handle_chg_limit_change(
|
||||
scale.get_value(), self.bat_limit_scale.get_value()
|
||||
),
|
||||
)
|
||||
self.bat_limit_scale.connect(
|
||||
"value-changed",
|
||||
lambda scale: handle_chg_limit_change(
|
||||
self.chg_limit_scale.get_value(), scale.get_value()
|
||||
),
|
||||
)
|
||||
|
||||
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)
|
||||
self.chg_limit_enable.set_sensitive(False)
|
||||
else:
|
||||
raise e
|
||||
|
||||
# Battery Extender
|
||||
try:
|
||||
ec_extender = ec_commands.framework_laptop.get_battery_extender(
|
||||
app.cros_ec
|
||||
)
|
||||
self.bat_ext_enable.set_active(not ec_extender["disable"])
|
||||
self.bat_ext_stage.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_trigger_time.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_reset_time.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_trigger.set_sensitive(not ec_extender["disable"])
|
||||
self.bat_ext_reset.set_sensitive(not ec_extender["disable"])
|
||||
|
||||
self.bat_ext_stage.set_subtitle(str(ec_extender["current_stage"]))
|
||||
self.bat_ext_trigger_time.set_subtitle(
|
||||
format_timedelta(ec_extender["trigger_timedelta"])
|
||||
)
|
||||
self.bat_ext_reset_time.set_subtitle(
|
||||
format_timedelta(ec_extender["reset_timedelta"])
|
||||
)
|
||||
self.bat_ext_trigger.set_value(ec_extender["trigger_days"])
|
||||
self.bat_ext_reset.set_value(ec_extender["reset_minutes"])
|
||||
|
||||
def handle_extender_enable(switch):
|
||||
active = switch.get_active()
|
||||
ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not active,
|
||||
int(self.bat_ext_trigger.get_value()),
|
||||
int(self.bat_ext_reset.get_value()),
|
||||
)
|
||||
self.bat_ext_stage.set_sensitive(active)
|
||||
self.bat_ext_trigger_time.set_sensitive(active)
|
||||
self.bat_ext_reset_time.set_sensitive(active)
|
||||
self.bat_ext_trigger.set_sensitive(active)
|
||||
self.bat_ext_reset.set_sensitive(active)
|
||||
|
||||
self.bat_ext_enable.connect(
|
||||
"notify::active", lambda switch, _: handle_extender_enable(switch)
|
||||
)
|
||||
self.bat_ext_trigger.connect(
|
||||
"notify::value",
|
||||
lambda scale, _: ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not self.bat_ext_enable.get_active(),
|
||||
int(scale.get_value()),
|
||||
int(self.bat_ext_reset.get_value()),
|
||||
),
|
||||
)
|
||||
self.bat_ext_reset.connect(
|
||||
"notify::value",
|
||||
lambda scale, _: ec_commands.framework_laptop.set_battery_extender(
|
||||
app.cros_ec,
|
||||
not self.bat_ext_enable.get_active(),
|
||||
int(self.bat_ext_trigger.get_value()),
|
||||
int(scale.get_value()),
|
||||
),
|
||||
)
|
||||
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
|
||||
)
|
||||
self.bat_ext_group.set_visible(False)
|
||||
else:
|
||||
raise e
|
||||
|
||||
# Schedule _update_battery to run every second
|
||||
GLib.timeout_add_seconds(
|
||||
1,
|
||||
self._update_battery,
|
||||
app
|
||||
)
|
||||
|
||||
def _update_battery(self, app):
|
||||
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
|
||||
)
|
||||
|
||||
self.bat_ext_stage.set_subtitle(str(ec_extender["current_stage"]))
|
||||
self.bat_ext_trigger_time.set_subtitle(
|
||||
format_timedelta(ec_extender["trigger_timedelta"])
|
||||
)
|
||||
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
|
||||
)
|
||||
else:
|
||||
raise e
|
||||
|
||||
return app.current_page == 3 and success
|
||||
|
||||
def format_timedelta(timedelta):
|
||||
days = f"{timedelta.days} days, " if timedelta.days else ""
|
||||
hours, remainder = divmod(timedelta.seconds, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
return days + f"{hours}:{minutes:02}:{seconds:02}"
|
||||
@@ -18,9 +18,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Adw
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk, Adw, GLib
|
||||
|
||||
import cros_ec_python.commands as ec_commands
|
||||
import cros_ec_python.exceptions as ec_exceptions
|
||||
@@ -29,17 +27,24 @@ import cros_ec_python.exceptions as ec_exceptions
|
||||
class HardwarePage(Gtk.Box):
|
||||
__gtype_name__ = 'HardwarePage'
|
||||
|
||||
hw_als = Gtk.Template.Child()
|
||||
hw_als_label = Gtk.Template.Child()
|
||||
|
||||
hw_chassis = Gtk.Template.Child()
|
||||
hw_chassis_label = Gtk.Template.Child()
|
||||
|
||||
hw_fp_pwr = Gtk.Template.Child()
|
||||
hw_fp_pwr_en = Gtk.Template.Child()
|
||||
hw_fp_pwr_dis = Gtk.Template.Child()
|
||||
|
||||
hw_priv_cam = Gtk.Template.Child()
|
||||
hw_priv_cam_sw = Gtk.Template.Child()
|
||||
hw_priv_mic = Gtk.Template.Child()
|
||||
hw_priv_mic_sw = Gtk.Template.Child()
|
||||
|
||||
hw_fp_pwr = Gtk.Template.Child()
|
||||
hw_fp_pwr_en = Gtk.Template.Child()
|
||||
hw_fp_pwr_dis = Gtk.Template.Child()
|
||||
hw_lid_open = Gtk.Template.Child()
|
||||
hw_lid_open_sw = Gtk.Template.Child()
|
||||
hw_pwr_btn = Gtk.Template.Child()
|
||||
hw_pwr_btn_sw = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -68,7 +73,13 @@ class HardwarePage(Gtk.Box):
|
||||
GLib.timeout_add_seconds(1, self._update_hardware, app)
|
||||
|
||||
def _update_hardware(self, app):
|
||||
success = False
|
||||
# Memmap (ALS and Lid Open)
|
||||
als = ec_commands.memmap.get_als(app.cros_ec)
|
||||
self.hw_als_label.set_label(f"{als[0]} lux" if als[0] != 65535 else "MAX")
|
||||
switches = ec_commands.memmap.get_switches(app.cros_ec)
|
||||
self.hw_lid_open_sw.set_active(switches["lid_open"])
|
||||
self.hw_pwr_btn_sw.set_active(switches["power_button_pressed"])
|
||||
|
||||
# Chassis
|
||||
if not ec_commands.framework_laptop.EC_CMD_CHASSIS_INTRUSION in app.no_support:
|
||||
try:
|
||||
@@ -84,8 +95,6 @@ class HardwarePage(Gtk.Box):
|
||||
self.hw_chassis.set_subtitle(
|
||||
"Currently " + ("Open" if ec_chassis_open else "Closed")
|
||||
)
|
||||
|
||||
success = True
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||
app.no_support.append(
|
||||
@@ -106,8 +115,6 @@ class HardwarePage(Gtk.Box):
|
||||
)
|
||||
self.hw_priv_cam_sw.set_active(ec_privacy["camera"])
|
||||
self.hw_priv_mic_sw.set_active(ec_privacy["microphone"])
|
||||
|
||||
success = True
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||
app.no_support.append(
|
||||
@@ -118,4 +125,4 @@ class HardwarePage(Gtk.Box):
|
||||
else:
|
||||
raise e
|
||||
|
||||
return app.current_page == 3 and success
|
||||
return app.current_page == 4
|
||||
|
||||
111
yafi/leds.py
@@ -18,8 +18,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Adw
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gtk, Adw, GLib
|
||||
|
||||
import cros_ec_python.commands as ec_commands
|
||||
import cros_ec_python.exceptions as ec_exceptions
|
||||
@@ -28,6 +27,8 @@ import cros_ec_python.exceptions as ec_exceptions
|
||||
class LedsPage(Gtk.Box):
|
||||
__gtype_name__ = 'LedsPage'
|
||||
|
||||
first_run = True
|
||||
|
||||
led_pwr = Gtk.Template.Child()
|
||||
led_pwr_scale = Gtk.Template.Child()
|
||||
|
||||
@@ -36,27 +37,30 @@ class LedsPage(Gtk.Box):
|
||||
|
||||
led_advanced = Gtk.Template.Child()
|
||||
|
||||
led_pwr_colour = Gtk.Template.Child()
|
||||
|
||||
led_chg_colour = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def setup(self, app):
|
||||
# Power LED
|
||||
try:
|
||||
|
||||
def handle_led_pwr(scale):
|
||||
value = int(abs(scale.get_value() - 2))
|
||||
ec_commands.framework_laptop.set_fp_led_level(app.cros_ec, value)
|
||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][value])
|
||||
|
||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
||||
app.cros_ec
|
||||
).value
|
||||
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
||||
try:
|
||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
||||
app.cros_ec
|
||||
).value
|
||||
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
||||
except ValueError:
|
||||
# LED isn't a normal value
|
||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level_int(
|
||||
app.cros_ec
|
||||
)
|
||||
self.led_pwr.set_subtitle(f"Custom ({current_fp_level}%)")
|
||||
|
||||
self.led_pwr_scale.connect("value-changed", handle_led_pwr)
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||
@@ -85,28 +89,38 @@ class LedsPage(Gtk.Box):
|
||||
self.led_kbd.set_visible(False)
|
||||
|
||||
# Advanced options
|
||||
if ec_commands.general.get_cmd_versions(
|
||||
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
||||
if (
|
||||
ec_commands.general.get_cmd_versions(
|
||||
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
||||
)
|
||||
and self.first_run
|
||||
):
|
||||
|
||||
# Advanced: Power LED
|
||||
led_pwr_colour_strings = self.led_pwr_colour.get_model()
|
||||
|
||||
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(
|
||||
led_names = {
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED: "Battery LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED: "Power LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_ADAPTER_LED: "Adapter LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_LEFT_LED: "Left LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_RIGHT_LED: "Right LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_RECOVERY_HW_REINIT_LED: "Recovery LED",
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_SYSRQ_DEBUG_LED: "SysRq LED",
|
||||
}
|
||||
leds = {}
|
||||
for i in range(ec_commands.leds.EcLedId.EC_LED_ID_COUNT.value):
|
||||
try:
|
||||
led_id = ec_commands.leds.EcLedId(i)
|
||||
leds[led_id] = ec_commands.leds.led_control_get_max_values(
|
||||
app.cros_ec, led_id
|
||||
)
|
||||
for i, colour in enumerate(all_colours):
|
||||
if supported_colours[i]:
|
||||
strings.append(colour)
|
||||
|
||||
add_colours(
|
||||
led_pwr_colour_strings, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
||||
)
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_PARAM:
|
||||
continue
|
||||
else:
|
||||
raise e
|
||||
|
||||
# Power LED does not support Blue, even though Intel models think they do
|
||||
leds[ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED][2] = 0
|
||||
|
||||
def handle_led_colour(combobox, led_id):
|
||||
colour = combobox.get_selected() - 2
|
||||
@@ -130,27 +144,20 @@ class LedsPage(Gtk.Box):
|
||||
100,
|
||||
ec_commands.leds.EcLedColors(colour_idx),
|
||||
)
|
||||
for led_id, supported_colours in leds.items():
|
||||
if any(supported_colours):
|
||||
combo = Adw.ComboRow(title=led_names[led_id])
|
||||
model = Gtk.StringList.new(["Auto", "Off"])
|
||||
for i, colour in enumerate(all_colours):
|
||||
if supported_colours[i]:
|
||||
model.append(colour)
|
||||
combo.set_model(model)
|
||||
combo.connect(
|
||||
"notify::selected",
|
||||
lambda combobox, _, led_id=led_id: handle_led_colour(
|
||||
combobox, led_id
|
||||
),
|
||||
)
|
||||
self.led_advanced.add_row(combo)
|
||||
|
||||
self.led_pwr_colour.connect(
|
||||
"notify::selected",
|
||||
lambda combo, _: handle_led_colour(
|
||||
combo, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
||||
),
|
||||
)
|
||||
|
||||
# Advanced: Charging LED
|
||||
led_chg_colour_strings = self.led_chg_colour.get_model()
|
||||
|
||||
add_colours(
|
||||
led_chg_colour_strings,
|
||||
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED,
|
||||
)
|
||||
|
||||
self.led_chg_colour.connect(
|
||||
"notify::selected",
|
||||
lambda combo, _: handle_led_colour(
|
||||
combo, ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED
|
||||
),
|
||||
)
|
||||
else:
|
||||
self.led_advanced.set_visible(False)
|
||||
self.first_run = False
|
||||
|
||||
138
yafi/main.py
@@ -18,19 +18,21 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import threading
|
||||
import gi
|
||||
from gi.repository import Gio
|
||||
|
||||
gi.require_version('Gtk', '4.0')
|
||||
gi.require_version('Adw', '1')
|
||||
|
||||
from gi.repository import Gtk, Gio, Adw
|
||||
from gi.repository import Gtk, Gio, Adw, GLib
|
||||
from .window import YafiWindow
|
||||
from .thermals import ThermalsPage
|
||||
from .leds import LedsPage
|
||||
from .battery import BatteryPage
|
||||
from .battery_limiter import BatteryLimiterPage
|
||||
from .hardware import HardwarePage
|
||||
|
||||
from cros_ec_python import get_cros_ec
|
||||
@@ -65,12 +67,20 @@ class YafiApplication(Adw.Application):
|
||||
if not self.win:
|
||||
self.win = YafiWindow(application=self)
|
||||
|
||||
# Update the splash screen
|
||||
splash = getattr(sys, 'frozen', False) and '_PYI_SPLASH_IPC' in os.environ
|
||||
if splash:
|
||||
import pyi_splash
|
||||
pyi_splash.update_text("Detecting EC")
|
||||
|
||||
try:
|
||||
self.cros_ec = get_cros_ec()
|
||||
pass
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
self.error = e
|
||||
|
||||
message = (
|
||||
str(e)
|
||||
+ "\n\n"
|
||||
@@ -78,16 +88,24 @@ class YafiApplication(Adw.Application):
|
||||
+ "If you are using a Framework Laptop, there are additional troubleshooting steps in the README."
|
||||
)
|
||||
self.show_error("EC Initalisation Error", message)
|
||||
|
||||
if splash:
|
||||
pyi_splash.close()
|
||||
|
||||
self.win.present()
|
||||
return
|
||||
|
||||
if splash:
|
||||
pyi_splash.update_text("Building Interface")
|
||||
|
||||
self.change_page(self.win.content, ThermalsPage())
|
||||
|
||||
pages = (
|
||||
("Thermals", ThermalsPage()),
|
||||
("LEDs", LedsPage()),
|
||||
("Battery", BatteryPage()),
|
||||
("Hardware", HardwarePage()),
|
||||
("Battery Limiter", BatteryLimiterPage()),
|
||||
("Sensors", HardwarePage()),
|
||||
("About", None),
|
||||
)
|
||||
|
||||
@@ -103,10 +121,14 @@ class YafiApplication(Adw.Application):
|
||||
self.current_page = page
|
||||
self.change_page(self.win.content, pages[page][1])
|
||||
else:
|
||||
self.win.navbar.select_row(self.win.navbar.get_row_at_index(self.current_page))
|
||||
self.on_about_action()
|
||||
|
||||
self.win.navbar.connect("row-activated", lambda box, row: switch_page(row.get_index()))
|
||||
|
||||
if splash:
|
||||
pyi_splash.close()
|
||||
|
||||
self.win.present()
|
||||
|
||||
def on_about_action(self, *args):
|
||||
@@ -114,25 +136,123 @@ class YafiApplication(Adw.Application):
|
||||
about = Adw.AboutDialog(
|
||||
application_icon="au.stevetech.yafi",
|
||||
application_name="Yet Another Framework Interface",
|
||||
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n"
|
||||
+ "It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.",
|
||||
copyright="© 2025 Stephen Horvath",
|
||||
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n\n"
|
||||
+ "It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.\n\n"
|
||||
+ "YAFI is not affiliated with Framework Computer Inc. in any way.",
|
||||
copyright="© 2026 Stephen Horvath",
|
||||
developer_name="Stephen Horvath",
|
||||
developers=["Stephen Horvath"],
|
||||
developers=["Stephen Horvath https://github.com/Steve-Tech"],
|
||||
artists=["Mirabelle SALLES https://github.com/oiimrosabel"],
|
||||
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
||||
license_type=Gtk.License.GPL_2_0,
|
||||
version="0.3",
|
||||
version="1.0",
|
||||
website="https://github.com/Steve-Tech/YAFI",
|
||||
)
|
||||
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
||||
about.present(self.props.active_window)
|
||||
|
||||
if hasattr(self, 'debug_info'):
|
||||
about.set_debug_info(self.debug_info)
|
||||
else:
|
||||
threading.Thread(target=lambda: GLib.idle_add(about.set_debug_info, self.generate_debug_info())).start()
|
||||
|
||||
def show_error(self, heading, message):
|
||||
dialog = Adw.AlertDialog(heading=heading, body=message)
|
||||
dialog.add_response("exit", "Exit")
|
||||
dialog.connect("response", lambda d, r: self.win.destroy())
|
||||
dialog.add_response("about", "About")
|
||||
dialog.set_default_response("exit")
|
||||
dialog.connect("response", lambda d, r: self.on_about_action() if r == "about" else self.win.destroy())
|
||||
dialog.present(self.win)
|
||||
|
||||
def generate_debug_info(self):
|
||||
if hasattr(self, 'debug_info'):
|
||||
return self.debug_info
|
||||
|
||||
info = "YAFI Debug Information\n\n"
|
||||
|
||||
if hasattr(self, 'error'):
|
||||
if isinstance(self.error, Exception):
|
||||
info += f"{type(self.error).__name__}: {self.error}\n\n"
|
||||
info += ''.join(traceback.format_exception(type(self.error), self.error, self.error.__traceback__))
|
||||
info += "\n\n"
|
||||
else:
|
||||
info += f"Error: {self.error}\n\n"
|
||||
|
||||
info += f"Python Version: {sys.version}\n"
|
||||
info += f"GTK Version: {Gtk.get_major_version()}.{Gtk.get_minor_version()}.{Gtk.get_micro_version()}\n"
|
||||
info += f"Adwaita Version: {Adw.get_major_version()}.{Adw.get_minor_version()}.{Adw.get_micro_version()}\n"
|
||||
|
||||
try:
|
||||
import platform
|
||||
info += f"Platform: {platform.platform()}\n"
|
||||
info += f"Processor: {platform.processor() or platform.machine()}\n"
|
||||
except Exception as e:
|
||||
info += f"Platform Error: {type(e).__name__}: {e}\n"
|
||||
|
||||
try:
|
||||
import importlib.metadata
|
||||
info += f"Installed Packages: {[(dist.metadata['Name'], dist.version) for dist in importlib.metadata.distributions()]}\n"
|
||||
except Exception as e:
|
||||
info += f"Importlib Error: {type(e).__name__}: {e}\n"
|
||||
|
||||
try:
|
||||
if sys.platform == "linux":
|
||||
with open('/sys/devices/virtual/dmi/id/sys_vendor', 'r') as f:
|
||||
info += f"Manufacturer: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/product_name', 'r') as f:
|
||||
info += f"Model: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/product_sku', 'r') as f:
|
||||
info += f"SKU: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/board_name', 'r') as f:
|
||||
info += f"Board: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/bios_vendor', 'r') as f:
|
||||
info += f"BIOS Vendor: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/bios_version', 'r') as f:
|
||||
info += f"BIOS Version: {f.read().strip()}\n"
|
||||
with open('/sys/devices/virtual/dmi/id/bios_date', 'r') as f:
|
||||
info += f"BIOS Date: {f.read().strip()}\n"
|
||||
elif sys.platform == "win32":
|
||||
import subprocess
|
||||
ps_cmd = (
|
||||
"powershell -Command "
|
||||
"\"$cs = Get-CimInstance -ClassName Win32_ComputerSystem; "
|
||||
"$board = Get-CimInstance -ClassName Win32_BaseBoard; "
|
||||
"$bios = Get-CimInstance -ClassName Win32_BIOS; "
|
||||
"Write-Output $cs.Manufacturer; "
|
||||
"Write-Output $cs.Model; "
|
||||
"Write-Output $cs.SystemSKUNumber; "
|
||||
"Write-Output $board.Product; "
|
||||
"Write-Output $bios.Manufacturer; "
|
||||
"Write-Output $bios.Name; "
|
||||
"Write-Output $bios.ReleaseDate\""
|
||||
)
|
||||
output = subprocess.check_output(ps_cmd, shell=True).decode().splitlines()
|
||||
info += f"Manufacturer: {output[0]}\n"
|
||||
info += f"Model: {output[1]}\n"
|
||||
info += f"SKU: {output[2]}\n"
|
||||
info += f"Board: {output[3]}\n"
|
||||
info += f"BIOS Vendor: {output[4]}\n"
|
||||
info += f"BIOS Version: {output[5]}\n"
|
||||
# Blank line in the output for some reason
|
||||
info += f"BIOS Date: {output[7]}\n"
|
||||
except Exception as e:
|
||||
info += f"System Info Error: {type(e).__name__}: {e}\n"
|
||||
|
||||
if self.cros_ec:
|
||||
info += f"EC Interface: {type(self.cros_ec).__name__}\n"
|
||||
try:
|
||||
import cros_ec_python.commands as ec_commands
|
||||
info += f"EC Version: {ec_commands.general.get_version(self.cros_ec)["version_string_ro"]}\n"
|
||||
info += f"EC Chip: {ec_commands.general.get_chip_info(self.cros_ec)}\n"
|
||||
info += f"EC Build Info: {ec_commands.general.get_build_info(self.cros_ec)}\n"
|
||||
info += f"EC Protocol Version: {ec_commands.general.proto_version(self.cros_ec)}\n"
|
||||
info += f"EC Protocol Info: {ec_commands.general.get_protocol_info(self.cros_ec)}\n"
|
||||
except Exception as e:
|
||||
info += f"EC Info Error: {type(e).__name__}: {e}\n"
|
||||
|
||||
self.debug_info = info
|
||||
return info
|
||||
|
||||
|
||||
def main():
|
||||
"""The application's entry point."""
|
||||
|
||||
@@ -33,6 +33,7 @@ yafi_sources = [
|
||||
'thermals.py',
|
||||
'leds.py',
|
||||
'battery.py',
|
||||
'battery_limiter.py',
|
||||
'hardware.py',
|
||||
]
|
||||
|
||||
|
||||
131
yafi/thermals.py
@@ -18,9 +18,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Adw
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk, Adw, GLib
|
||||
|
||||
import cros_ec_python.commands as ec_commands
|
||||
import cros_ec_python.exceptions as ec_exceptions
|
||||
@@ -29,11 +27,17 @@ import cros_ec_python.exceptions as ec_exceptions
|
||||
class ThermalsPage(Gtk.Box):
|
||||
__gtype_name__ = 'ThermalsPage'
|
||||
|
||||
first_run = True
|
||||
|
||||
fan_rpm = Gtk.Template.Child()
|
||||
fan_mode = Gtk.Template.Child()
|
||||
fan_set_rpm = Gtk.Template.Child()
|
||||
fan_set_percent = Gtk.Template.Child()
|
||||
fan_percent_scale = Gtk.Template.Child()
|
||||
fan_set_points = Gtk.Template.Child()
|
||||
set_points = []
|
||||
ec_set_points_supported = False
|
||||
ec_set_points = []
|
||||
|
||||
temperatures = Gtk.Template.Child()
|
||||
temp_items = []
|
||||
@@ -42,10 +46,40 @@ class ThermalsPage(Gtk.Box):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def setup(self, app):
|
||||
# Temperature sensors
|
||||
while temp_child := self.temperatures.get_last_child():
|
||||
self.temperatures.remove(temp_child)
|
||||
self.temp_items.clear()
|
||||
|
||||
try:
|
||||
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||
# Generate some labels if the command is not supported
|
||||
ec_temp_sensors = {}
|
||||
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
||||
for i, temp in enumerate(temps):
|
||||
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
||||
else:
|
||||
raise e
|
||||
|
||||
for key, value in ec_temp_sensors.items():
|
||||
off_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C" if value[0] is not None else "Error")
|
||||
off_row.add_css_class("property")
|
||||
self.temperatures.append(off_row)
|
||||
self.temp_items.append(off_row)
|
||||
|
||||
self._update_thermals(app)
|
||||
|
||||
# Don't let the user change the fans if they can't get back to auto
|
||||
if ec_commands.general.get_cmd_versions(
|
||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
|
||||
):
|
||||
self.ec_set_points_supported = ec_commands.general.check_cmd_version(
|
||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_GET_THRESHOLD, 1
|
||||
) and ec_commands.general.check_cmd_version(
|
||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_SET_THRESHOLD, 1
|
||||
)
|
||||
|
||||
def handle_fan_mode(mode):
|
||||
match mode:
|
||||
@@ -53,13 +87,18 @@ class ThermalsPage(Gtk.Box):
|
||||
self.fan_set_rpm.set_visible(False)
|
||||
self.fan_set_percent.set_visible(False)
|
||||
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
|
||||
self.fan_set_points.set_visible(self.ec_set_points_supported)
|
||||
case 1: # Percent
|
||||
self.fan_set_points.set_visible(False)
|
||||
self.fan_set_rpm.set_visible(False)
|
||||
self.fan_set_percent.set_visible(True)
|
||||
case 2: # RPM
|
||||
self.fan_set_points.set_visible(False)
|
||||
self.fan_set_rpm.set_visible(True)
|
||||
self.fan_set_percent.set_visible(False)
|
||||
|
||||
handle_fan_mode(self.fan_mode.get_selected())
|
||||
|
||||
self.fan_mode.connect(
|
||||
"notify::selected",
|
||||
lambda combo, _: handle_fan_mode(combo.get_selected()),
|
||||
@@ -83,41 +122,77 @@ class ThermalsPage(Gtk.Box):
|
||||
):
|
||||
|
||||
def handle_fan_rpm(entry):
|
||||
rpm = int(entry.get_text())
|
||||
rpm = int(entry.get_value())
|
||||
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
|
||||
|
||||
self.fan_set_rpm.connect(
|
||||
"notify::text", lambda entry, _: handle_fan_rpm(entry)
|
||||
"notify::value", lambda entry, _: handle_fan_rpm(entry)
|
||||
)
|
||||
else:
|
||||
self.fan_set_rpm.set_sensitive(False)
|
||||
else:
|
||||
self.fan_mode.set_sensitive(False)
|
||||
|
||||
# Temperature sensors
|
||||
while temp_child := self.temperatures.get_last_child():
|
||||
self.temperatures.remove(temp_child)
|
||||
self.temp_items.clear()
|
||||
# Set points
|
||||
if self.ec_set_points_supported and self.first_run:
|
||||
def handle_set_point(entry, key):
|
||||
index = entry.ec_index
|
||||
temp = int(entry.get_value())
|
||||
# Don't allow an off temp higher than max temp and vice versa
|
||||
match key:
|
||||
case "temp_fan_off":
|
||||
if temp > self.ec_set_points[index]["temp_fan_max"]:
|
||||
entry.set_value(self.ec_set_points[index]["temp_fan_off"])
|
||||
return
|
||||
case "temp_fan_max":
|
||||
if temp < self.ec_set_points[index]["temp_fan_off"]:
|
||||
entry.set_value(self.ec_set_points[index]["temp_fan_max"])
|
||||
return
|
||||
self.ec_set_points[entry.ec_index][key] = temp
|
||||
ec_commands.thermal.thermal_set_thresholds(
|
||||
app.cros_ec, index,
|
||||
self.ec_set_points[index]
|
||||
)
|
||||
|
||||
try:
|
||||
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
||||
except ec_exceptions.ECError as e:
|
||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||
# Generate some labels if the command is not supported
|
||||
ec_temp_sensors = {}
|
||||
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
||||
for i, temp in enumerate(temps):
|
||||
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
||||
else:
|
||||
raise e
|
||||
for i, sensor in enumerate(ec_temp_sensors):
|
||||
ec_set_point = ec_commands.thermal.thermal_get_thresholds(app.cros_ec, i)
|
||||
self.ec_set_points.append(ec_set_point)
|
||||
off_row = Adw.SpinRow(
|
||||
title=f"Fan On - {sensor}",
|
||||
subtitle=f"Turn fan on when above temp (°C)",
|
||||
)
|
||||
off_row.ec_index = i
|
||||
# 0K to 65535K for 16bit unsigned range
|
||||
# Actually the EC takes 32bits, but let's keep it like this for sanity
|
||||
off_row.set_adjustment(Gtk.Adjustment(
|
||||
lower=-273,
|
||||
upper=65_262,
|
||||
page_increment=10,
|
||||
step_increment=1,
|
||||
value=ec_set_point["temp_fan_off"],
|
||||
))
|
||||
off_row.connect(
|
||||
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_off")
|
||||
)
|
||||
max_row = Adw.SpinRow(
|
||||
title=f"Fan Max - {sensor}",
|
||||
subtitle=f"Max fan speed when above temp (°C)",
|
||||
)
|
||||
max_row.ec_index = i
|
||||
max_row.set_adjustment(Gtk.Adjustment(
|
||||
lower=-273,
|
||||
upper=65_262,
|
||||
page_increment=10,
|
||||
step_increment=1,
|
||||
value=ec_set_point["temp_fan_max"],
|
||||
))
|
||||
max_row.connect(
|
||||
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_max")
|
||||
)
|
||||
self.fan_set_points.add_row(off_row)
|
||||
self.fan_set_points.add_row(max_row)
|
||||
|
||||
for key, value in ec_temp_sensors.items():
|
||||
new_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C")
|
||||
new_row.add_css_class("property")
|
||||
self.temperatures.append(new_row)
|
||||
self.temp_items.append(new_row)
|
||||
|
||||
self._update_thermals(app)
|
||||
self.first_run = False
|
||||
|
||||
# Schedule _update_thermals to run every second
|
||||
GLib.timeout_add_seconds(1, self._update_thermals, app)
|
||||
@@ -130,7 +205,7 @@ class ThermalsPage(Gtk.Box):
|
||||
ec_temp_sensors = ec_commands.memmap.get_temps(app.cros_ec)
|
||||
# The temp sensors disappear sometimes, so we need to handle that
|
||||
for i in range(min(len(self.temp_items), len(ec_temp_sensors))):
|
||||
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C")
|
||||
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C" if ec_temp_sensors[i] is not None else "Error")
|
||||
|
||||
# Check if this has already failed and skip if it has
|
||||
if not ec_commands.pwm.EC_CMD_PWM_GET_FAN_TARGET_RPM in app.no_support:
|
||||
|
||||
165
yafi/ui/battery-limiter.ui
Normal file
@@ -0,0 +1,165 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.96.3 -->
|
||||
<interface>
|
||||
<!-- interface-name battery-limiter.ui -->
|
||||
<!-- interface-description The Battery page for YAFI -->
|
||||
<!-- interface-authors Steve-Tech -->
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="BatteryLimiterPage" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-start">10</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Battery Limiters</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="chg_limit_enable">
|
||||
<property name="title">Enable Charge Limiter</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="chg_limit">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Limit the maximum charge</property>
|
||||
<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">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="page-increment">10.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">100.0</property>
|
||||
<property name="value">100.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="round-digits">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_limit">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Limit the minimum charge</property>
|
||||
<property name="title">Discharge Limit</property>
|
||||
<property name="visible">False</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">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="page-increment">10.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">100.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="round-digits">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
||||
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="title">Battery Extender</property>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="bat_ext_enable">
|
||||
<property name="title">Enable</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_stage">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Current Stage (0 to 2)</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_trigger_time">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Time Until Trigger</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_reset_time">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Time Until Reset</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="bat_ext_trigger">
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="lower">1.0</property>
|
||||
<property name="page-increment">5.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">99.0</property>
|
||||
<property name="value">5.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Number of days on charge before reducing charge limit</property>
|
||||
<property name="title">Trigger Days</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="bat_ext_reset">
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="lower">1.0</property>
|
||||
<property name="page-increment">5.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">9999.0</property>
|
||||
<property name="value">30.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Number of minutes off charge before resetting charge limit</property>
|
||||
<property name="title">Reset Minutes</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,181 +1,156 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.94.1 -->
|
||||
<!-- Created with Cambalache 0.96.1 -->
|
||||
<interface>
|
||||
<!-- interface-description The Battery page for YAFI -->
|
||||
<!-- interface-authors Steve-Tech -->
|
||||
<requires lib="gtk" version="4.12"/>
|
||||
<requires lib="libadwaita" version="1.6"/>
|
||||
<!-- interface-name battery.ui -->
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="BatteryPage" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-start">10</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Battery Limiters</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="chg_limit_enable">
|
||||
<property name="title">Enable Charge Limiter</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="chg_limit">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Limit the maximum charge</property>
|
||||
<property name="title">Charge Limit</property>
|
||||
<object class="GtkPaned">
|
||||
<property name="end-child">
|
||||
<object class="GtkListBox">
|
||||
<property name="width-request">100</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="AdwActionRow" id="batt_manu">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Manufacturer</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_model">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Model</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_serial">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Serial</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_type">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Type</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_orig_cap">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Design Capacity</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_orig_volts">
|
||||
<property name="css-classes">property</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Design Voltage</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="start-child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="margin-end">10</property>
|
||||
<property name="margin-start">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="chg_limit_label"/>
|
||||
<object class="AdwActionRow" id="batt_status">
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Battery Statistics</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="chg_limit_scale">
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="page-increment">10.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">100.0</property>
|
||||
<property name="value">100.0</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title">Charge</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="batt_charge">
|
||||
<property name="show-text">True</property>
|
||||
<property name="width-request">300</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="round-digits">0</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_limit">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Limit the minimum charge</property>
|
||||
<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">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="page-increment">10.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">100.0</property>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title">Health</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="batt_health">
|
||||
<property name="show-text">True</property>
|
||||
<property name="width-request">300</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="round-digits">0</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="chg_limit_override">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Disables the limiter for one charge cycle</property>
|
||||
<property name="title">Override Charge Limiter</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="chg_limit_override_btn">
|
||||
<property name="label">Override</property>
|
||||
<object class="AdwActionRow" id="batt_cycles">
|
||||
<property name="title">Charge Cycles</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="batt_cycles_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_volts">
|
||||
<property name="title">Current Voltage</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="batt_volts_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_watts">
|
||||
<property name="title">Current Wattage</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="batt_watts_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_cap_rem">
|
||||
<property name="title">Remaining Charge</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="batt_cap_rem_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="batt_cap_full">
|
||||
<property name="title">Last Full Charge</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="batt_cap_full_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
||||
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="title">Battery Extender</property>
|
||||
<child>
|
||||
<object class="AdwSwitchRow" id="bat_ext_enable">
|
||||
<property name="title">Enable</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_stage">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Current Stage (0 to 2)</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_trigger_time">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Time Until Trigger</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="bat_ext_reset_time">
|
||||
<property name="selectable">False</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="title">Time Until Reset</property>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="bat_ext_trigger">
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="lower">1.0</property>
|
||||
<property name="page-increment">5.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">99.0</property>
|
||||
<property name="value">5.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Number of days on charge before reducing charge limit</property>
|
||||
<property name="title">Trigger Days</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwSpinRow" id="bat_ext_reset">
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="lower">1.0</property>
|
||||
<property name="page-increment">5.0</property>
|
||||
<property name="step-increment">1.0</property>
|
||||
<property name="upper">9999.0</property>
|
||||
<property name="value">30.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="subtitle">Number of minutes off charge before resetting charge limit</property>
|
||||
<property name="title">Reset Minutes</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.94.1 -->
|
||||
<!-- Created with Cambalache 0.96.1 -->
|
||||
<interface>
|
||||
<!-- interface-description The Hardware page for YAFI -->
|
||||
<!-- interface-name hardware.ui -->
|
||||
<!-- interface-description The Sensors page for YAFI -->
|
||||
<!-- interface-copyright Steve-Tech -->
|
||||
<requires lib="gtk" version="4.12"/>
|
||||
<requires lib="libadwaita" version="1.3"/>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="HardwarePage" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
@@ -14,7 +15,15 @@
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Hardware Status</property>
|
||||
<property name="title">Sensors</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="hw_als">
|
||||
<property name="title">Ambient Light Sensor</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="hw_als_label"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -25,6 +34,30 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="hw_fp_pwr">
|
||||
<property name="title">Fingerprint</property>
|
||||
<property name="visible">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="hw_fp_pwr_en">
|
||||
<property name="label">Enable</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="hw_fp_pwr_dis">
|
||||
<property name="label">Disable</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="hw_priv_cam">
|
||||
<property name="subtitle">Use Privacy Switch</property>
|
||||
@@ -64,23 +97,35 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="hw_fp_pwr">
|
||||
<property name="title">Fingerprint</property>
|
||||
<property name="visible">False</property>
|
||||
<object class="AdwActionRow" id="hw_lid_open">
|
||||
<property name="title">Lid Open</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="hw_fp_pwr_en">
|
||||
<property name="label">Enable</property>
|
||||
<object class="GtkSwitch" id="hw_lid_open_sw">
|
||||
<property name="active">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="hw_pwr_btn">
|
||||
<property name="title">Power Button Pressed</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">end</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="hw_fp_pwr_dis">
|
||||
<property name="label">Disable</property>
|
||||
<object class="GtkSwitch" id="hw_pwr_btn_sw">
|
||||
<property name="active">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.94.1 -->
|
||||
<!-- Created with Cambalache 0.96.1 -->
|
||||
<interface>
|
||||
<!-- interface-name leds.ui -->
|
||||
<!-- interface-description The LEDs page for YAFI -->
|
||||
<!-- interface-authors Steve-Tech -->
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.6"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="LedsPage" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
@@ -68,52 +69,6 @@
|
||||
<property name="selectable">False</property>
|
||||
<property name="subtitle">These options break normal functionality</property>
|
||||
<property name="title">Advanced Options</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description">When using these options, the power LED may not turn off with the computer.</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="title">Power Button LED</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="led_pwr_colour">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Auto</item>
|
||||
<item>Off</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<property name="title">Colour</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description">When using these options, the charging indicator will no longer indicate charging.</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-end">5</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<property name="title">Charging Indicators</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="led_chg_colour">
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Auto</item>
|
||||
<item>Off</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
<property name="title">Colour</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.94.1 -->
|
||||
<!-- Created with Cambalache 0.96.3 -->
|
||||
<interface>
|
||||
<!-- interface-name thermals.ui -->
|
||||
<!-- interface-description The Thermals page for YAFI -->
|
||||
<!-- interface-authors Steve-Tech -->
|
||||
<requires lib="gtk" version="4.12"/>
|
||||
<requires lib="libadwaita" version="1.6"/>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="ThermalsPage" parent="GtkBox">
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
@@ -91,6 +92,12 @@
|
||||
<property name="visible">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwExpanderRow" id="fan_set_points">
|
||||
<property name="selectable">False</property>
|
||||
<property name="title">Fan Set Points</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
|
||||
320
yafi/ui/yafi.cmb
@@ -1,315 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||
<cambalache-project version="0.94.0" target_tk="gtk-4.0">
|
||||
<ui>
|
||||
(1,1,"yafi.ui","yafi.ui","YAFI is another GUI for the Framework Laptop Embedded Controller.",None,"Steve-Tech",None,None,None,None),
|
||||
(2,17,None,"thermals.ui","The Thermals page for YAFI",None,"Steve-Tech",None,None,None,None),
|
||||
(3,4,None,"leds.ui","The LEDs page for YAFI",None,"Steve-Tech",None,None,None,None),
|
||||
(4,1,None,"battery.ui","The Battery page for YAFI",None,"Steve-Tech",None,None,None,None),
|
||||
(5,1,None,"hardware.ui","The Hardware page for YAFI","Steve-Tech",None,None,None,None,None)
|
||||
</ui>
|
||||
<object>
|
||||
(1,1,"AdwApplicationWindow","YafiWindow",None,None,None,None,0,None,None),
|
||||
(1,2,"AdwNavigationSplitView",None,1,None,None,None,0,None,None),
|
||||
(1,6,"AdwNavigationPage",None,2,None,None,None,0,None,None),
|
||||
(1,7,"AdwNavigationPage",None,2,None,None,None,1,None,None),
|
||||
(1,10,"AdwHeaderBar",None,11,None,"top",None,0,None,None),
|
||||
(1,11,"AdwToolbarView",None,7,None,None,None,0,None,None),
|
||||
(1,13,"AdwToolbarView",None,6,None,None,None,0,None,None),
|
||||
(1,14,"AdwHeaderBar",None,13,None,"top",None,0,None,None),
|
||||
(1,16,"GtkScrolledWindow",None,13,None,None,None,1,None,None),
|
||||
(1,17,"GtkListBox","navbar",16,None,None,None,0,None,None),
|
||||
(1,52,"GtkBox","content",53,None,None,None,0,None,None),
|
||||
(1,53,"GtkScrolledWindow",None,11,None,None,None,1,None,None),
|
||||
(2,2,"GtkPaned",None,17,None,None,None,0,None,None),
|
||||
(2,3,"GtkListBox","temperatures",2,None,None,None,1,None,None),
|
||||
(2,4,"AdwActionRow",None,3,None,None,None,0,None,None),
|
||||
(2,5,"GtkBox",None,2,None,None,None,0,None,None),
|
||||
(2,6,"GtkListBox",None,5,None,None,None,0,None,None),
|
||||
(2,7,"AdwActionRow",None,6,None,None,None,0,None,None),
|
||||
(2,8,"AdwActionRow","fan_rpm",6,None,None,None,1,None,None),
|
||||
(2,9,"AdwComboRow","fan_mode",6,None,None,None,2,None,None),
|
||||
(2,10,"GtkStringList",None,9,None,None,None,0,None,None),
|
||||
(2,11,"AdwActionRow","fan_set_percent",6,None,None,None,3,None,None),
|
||||
(2,12,"GtkBox",None,11,None,None,None,0,None,None),
|
||||
(2,13,"GtkScale","fan_percent_scale",12,None,None,None,0,None,None),
|
||||
(2,14,"GtkAdjustment",None,13,None,None,None,0,None,None),
|
||||
(2,15,"AdwSpinRow","fan_set_rpm",6,None,None,None,4,None,None),
|
||||
(2,16,"GtkAdjustment",None,15,None,None,None,0,None,None),
|
||||
(2,17,"GtkBox","ThermalsPage",None,None,None,None,1,None,None),
|
||||
(3,4,"GtkBox","LedsPage",None,None,None,None,1,None,None),
|
||||
(3,5,"GtkListBox",None,4,None,None,None,0,None,None),
|
||||
(3,6,"AdwActionRow",None,5,None,None,None,0,None,None),
|
||||
(3,10,"AdwActionRow","led_pwr",5,None,None,None,1,None,None),
|
||||
(3,11,"GtkBox",None,10,None,None,None,0,None,None),
|
||||
(3,12,"GtkScale","led_pwr_scale",11,None,None,None,0,None,None),
|
||||
(3,13,"GtkAdjustment",None,12,None,None,None,0,None,None),
|
||||
(3,14,"AdwActionRow","led_kbd",5,None,None,None,2,None,None),
|
||||
(3,15,"GtkBox",None,14,None,None,None,0,None,None),
|
||||
(3,16,"GtkScale","led_kbd_scale",15,None,None,None,0,None,None),
|
||||
(3,17,"GtkAdjustment",None,16,None,None,None,0,None,None),
|
||||
(3,18,"AdwExpanderRow","led_advanced",5,None,None,None,3,None,None),
|
||||
(3,23,"AdwComboRow","led_pwr_colour",31,None,None,None,0,None,None),
|
||||
(3,24,"GtkStringList",None,23,None,None,None,0,None,None),
|
||||
(3,25,"AdwComboRow","led_chg_colour",32,None,None,None,0,None,None),
|
||||
(3,26,"GtkStringList",None,25,None,None,None,0,None,None),
|
||||
(3,31,"AdwPreferencesGroup",None,18,None,None,None,0,None,None),
|
||||
(3,32,"AdwPreferencesGroup",None,18,None,None,None,1,None,None),
|
||||
(4,1,"GtkBox","BatteryPage",None,None,None,None,0,None,None),
|
||||
(4,2,"GtkListBox",None,1,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,5,"GtkBox",None,4,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),
|
||||
(4,28,"GtkAdjustment",None,27,None,None,None,0,None,None),
|
||||
(4,29,"AdwSpinRow","bat_ext_reset",13,None,None,None,6,None,None),
|
||||
(4,30,"GtkAdjustment",None,29,None,None,None,0,None,None),
|
||||
(4,31,"AdwActionRow","bat_ext_stage",13,None,None,None,2,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,34,"GtkBox",None,33,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),
|
||||
(4,39,"GtkButton","chg_limit_override_btn",38,None,None,None,0,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,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),
|
||||
(5,4,"AdwActionRow","hw_chassis",2,None,None,None,1,None,None),
|
||||
(5,5,"GtkLabel","hw_chassis_label",4,None,None,None,0,None,None),
|
||||
(5,6,"AdwActionRow","hw_priv_cam",2,None,None,None,2,None,None),
|
||||
(5,9,"AdwActionRow","hw_priv_mic",2,None,None,None,3,None,None),
|
||||
(5,11,"GtkSwitch","hw_priv_mic_sw",13,None,None,None,0,None,None),
|
||||
(5,13,"GtkBox",None,9,None,None,None,0,None,None),
|
||||
(5,14,"GtkBox",None,6,None,None,None,0,None,None),
|
||||
(5,15,"GtkSwitch","hw_priv_cam_sw",14,None,None,None,0,None,None),
|
||||
(5,16,"AdwActionRow","hw_fp_pwr",2,None,None,None,4,None,None),
|
||||
(5,17,"GtkBox",None,16,None,None,None,0,None,None),
|
||||
(5,18,"GtkButton","hw_fp_pwr_en",17,None,None,None,0,None,None),
|
||||
(5,19,"GtkButton","hw_fp_pwr_dis",17,None,None,None,1,None,None)
|
||||
</object>
|
||||
<object_property>
|
||||
(1,1,"GtkWindow","default-height","500",None,None,None,None,None,None,None,None,None),
|
||||
(1,1,"GtkWindow","default-width","800",None,None,None,None,None,None,None,None,None),
|
||||
(1,2,"AdwNavigationSplitView","content",None,None,None,None,None,7,None,None,None,None),
|
||||
(1,2,"AdwNavigationSplitView","sidebar",None,None,None,None,None,6,None,None,None,None),
|
||||
(1,6,"AdwNavigationPage","title","Settings",None,None,None,None,None,None,None,None,None),
|
||||
(1,7,"AdwNavigationPage","title","Yet Another Framework Interface",None,None,None,None,None,None,None,None,None),
|
||||
(1,52,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||
(1,52,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||
(2,2,"GtkPaned","end-child",None,0,None,None,None,3,None,None,None,None),
|
||||
(2,2,"GtkPaned","start-child",None,0,None,None,None,5,None,None,None,None),
|
||||
(2,4,"AdwPreferencesRow","title","Temperatures",0,None,None,None,None,None,None,None,None),
|
||||
(2,4,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(2,5,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
|
||||
(2,6,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
|
||||
(2,6,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
|
||||
(2,7,"AdwPreferencesRow","title","Fan Control",0,None,None,None,None,None,None,None,None),
|
||||
(2,7,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(2,8,"AdwPreferencesRow","title","Current Speed",0,None,None,None,None,None,None,None,None),
|
||||
(2,9,"AdwComboRow","model",None,0,None,None,None,10,None,None,None,None),
|
||||
(2,9,"AdwPreferencesRow","title","Speed Set Mode",0,None,None,None,None,None,None,None,None),
|
||||
(2,11,"AdwPreferencesRow","title","Fan Speed",0,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkWidget","visible","False",0,None,None,None,None,None,None,None,None),
|
||||
(2,13,"GtkRange","adjustment",None,0,None,None,None,14,None,None,None,None),
|
||||
(2,13,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
|
||||
(2,13,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
|
||||
(2,14,"GtkAdjustment","page-increment","10.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,14,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,14,"GtkAdjustment","upper","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,14,"GtkAdjustment","value","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,15,"AdwPreferencesRow","title","Fan RPM Target",0,None,None,None,None,None,None,None,None),
|
||||
(2,15,"AdwSpinRow","adjustment",None,0,None,None,None,16,None,None,None,None),
|
||||
(2,15,"GtkWidget","visible","False",0,None,None,None,None,None,None,None,None),
|
||||
(2,16,"GtkAdjustment","page-increment","1000.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,16,"GtkAdjustment","step-increment","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,16,"GtkAdjustment","upper","65535.0",0,None,None,None,None,None,None,None,None),
|
||||
(2,17,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
|
||||
(3,5,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
|
||||
(3,5,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
|
||||
(3,6,"AdwPreferencesRow","title","LED Control",0,None,None,None,None,None,None,None,None),
|
||||
(3,6,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(3,10,"AdwPreferencesRow","title","Power Button",0,None,None,None,None,None,None,None,None),
|
||||
(3,12,"GtkRange","adjustment",None,0,None,None,None,13,None,None,None,None),
|
||||
(3,12,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
|
||||
(3,12,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkAdjustment","page-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkAdjustment","upper","2.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkAdjustment","value","2.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,14,"AdwPreferencesRow","title","Keyboard Backlight",0,None,None,None,None,None,None,None,None),
|
||||
(3,16,"GtkRange","adjustment",None,0,None,None,None,17,None,None,None,None),
|
||||
(3,16,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
|
||||
(3,16,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkAdjustment","page-increment","10.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkAdjustment","upper","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkAdjustment","value","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(3,18,"AdwExpanderRow","subtitle","These options break normal functionality",None,None,None,None,None,None,None,None,None),
|
||||
(3,18,"AdwPreferencesRow","title","Advanced Options",None,None,None,None,None,None,None,None,None),
|
||||
(3,18,"GtkListBoxRow","selectable","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,23,"AdwComboRow","model",None,0,None,None,None,24,None,None,None,None),
|
||||
(3,23,"AdwPreferencesRow","title","Colour",0,None,None,None,None,None,None,None,None),
|
||||
(3,25,"AdwComboRow","model",None,0,None,None,None,26,None,None,None,None),
|
||||
(3,25,"AdwPreferencesRow","title","Colour",0,None,None,None,None,None,None,None,None),
|
||||
(3,31,"AdwPreferencesGroup","description","When using these options, the power LED may not turn off with the computer.",None,None,None,None,None,None,None,None,None),
|
||||
(3,31,"AdwPreferencesGroup","title","Power Button LED",None,None,None,None,None,None,None,None,None),
|
||||
(3,31,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,31,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,31,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,31,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"AdwPreferencesGroup","description","When using these options, the charging indicator will no longer indicate charging.",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"AdwPreferencesGroup","title","Charging Indicators",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,32,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(4,1,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
|
||||
(4,2,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
|
||||
(4,2,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
|
||||
(4,3,"AdwPreferencesRow","title","Battery Limiters",0,None,None,None,None,None,None,None,None),
|
||||
(4,3,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(4,4,"AdwActionRow","subtitle","Limit the maximum charge",None,None,None,None,None,None,None,None,None),
|
||||
(4,4,"AdwPreferencesRow","title","Charge Limit",0,None,None,None,None,None,None,None,None),
|
||||
(4,4,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,6,"GtkRange","adjustment",None,0,None,None,None,7,None,None,None,None),
|
||||
(4,6,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
|
||||
(4,6,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkAdjustment","page-increment","10.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkAdjustment","upper","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkAdjustment","value","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"AdwPreferencesGroup","description","Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"AdwPreferencesGroup","title","Battery Extender",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"GtkWidget","margin-bottom","5",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"GtkWidget","margin-end","5",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"GtkWidget","margin-start","5",0,None,None,None,None,None,None,None,None),
|
||||
(4,13,"GtkWidget","margin-top","5",0,None,None,None,None,None,None,None,None),
|
||||
(4,27,"AdwActionRow","subtitle","Number of days on charge before reducing charge limit",None,None,None,None,None,None,None,None,None),
|
||||
(4,27,"AdwPreferencesRow","title","Trigger Days",0,None,None,None,None,None,None,None,None),
|
||||
(4,27,"AdwSpinRow","adjustment",None,0,None,None,None,28,None,None,None,None),
|
||||
(4,27,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,28,"GtkAdjustment","lower","1.0",None,None,None,None,None,None,None,None,None),
|
||||
(4,28,"GtkAdjustment","page-increment","5.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,28,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,28,"GtkAdjustment","upper","99.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,28,"GtkAdjustment","value","5.0",None,None,None,None,None,None,None,None,None),
|
||||
(4,29,"AdwActionRow","subtitle","Number of minutes off charge before resetting charge limit",0,None,None,None,None,None,None,None,None),
|
||||
(4,29,"AdwPreferencesRow","title","Reset Minutes",0,None,None,None,None,None,None,None,None),
|
||||
(4,29,"AdwSpinRow","adjustment",None,0,None,None,None,30,None,None,None,None),
|
||||
(4,29,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,30,"GtkAdjustment","lower","1.0",None,None,None,None,None,None,None,None,None),
|
||||
(4,30,"GtkAdjustment","page-increment","5.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,30,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,30,"GtkAdjustment","upper","9999.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,30,"GtkAdjustment","value","30.0",None,None,None,None,None,None,None,None,None),
|
||||
(4,31,"AdwPreferencesRow","title","Current Stage (0 to 2)",0,None,None,None,None,None,None,None,None),
|
||||
(4,31,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(4,31,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,32,"AdwPreferencesRow","title","Enable",None,None,None,None,None,None,None,None,None),
|
||||
(4,33,"AdwActionRow","subtitle","Limit the minimum charge",0,None,None,None,None,None,None,None,None),
|
||||
(4,33,"AdwPreferencesRow","title","Discharge Limit",0,None,None,None,None,None,None,None,None),
|
||||
(4,33,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,35,"GtkRange","adjustment",None,0,None,None,None,36,None,None,None,None),
|
||||
(4,35,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
|
||||
(4,35,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
|
||||
(4,36,"GtkAdjustment","page-increment","10.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,36,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,36,"GtkAdjustment","upper","100.0",0,None,None,None,None,None,None,None,None),
|
||||
(4,37,"AdwActionRow","subtitle","Disables the limiter for one charge cycle",0,None,None,None,None,None,None,None,None),
|
||||
(4,37,"AdwPreferencesRow","title","Override Charge Limiter",0,None,None,None,None,None,None,None,None),
|
||||
(4,37,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,38,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||
(4,38,"GtkWidget","halign","end",None,None,None,None,None,None,None,None,None),
|
||||
(4,38,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||
(4,39,"GtkButton","label","Override",None,None,None,None,None,None,None,None,None),
|
||||
(4,40,"AdwPreferencesRow","title","Enable Charge Limiter",None,None,None,None,None,None,None,None,None),
|
||||
(4,41,"AdwPreferencesRow","title","Time Until Trigger",0,None,None,None,None,None,None,None,None),
|
||||
(4,41,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(4,41,"GtkWidget","sensitive","False",0,None,None,None,None,None,None,None,None),
|
||||
(4,42,"AdwPreferencesRow","title","Time Until Reset",0,None,None,None,None,None,None,None,None),
|
||||
(4,42,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(4,42,"GtkWidget","sensitive","False",0,None,None,None,None,None,None,None,None),
|
||||
(5,1,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
|
||||
(5,2,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
|
||||
(5,2,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
|
||||
(5,3,"AdwPreferencesRow","title","Hardware Status",0,None,None,None,None,None,None,None,None),
|
||||
(5,3,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
|
||||
(5,4,"AdwPreferencesRow","title","Chassis Open Count",0,None,None,None,None,None,None,None,None),
|
||||
(5,6,"AdwActionRow","subtitle","Use Privacy Switch",None,None,None,None,None,None,None,None,None),
|
||||
(5,6,"AdwPreferencesRow","title","Camera Enabled",0,None,None,None,None,None,None,None,None),
|
||||
(5,9,"AdwActionRow","subtitle","Use Privacy Switch",None,None,None,None,None,None,None,None,None),
|
||||
(5,9,"AdwPreferencesRow","title","Microphone Enabled",0,None,None,None,None,None,None,None,None),
|
||||
(5,11,"GtkSwitch","active","True",0,None,None,None,None,None,None,None,None),
|
||||
(5,11,"GtkWidget","sensitive","False",0,None,None,None,None,None,None,None,None),
|
||||
(5,13,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||
(5,13,"GtkWidget","halign","end",None,None,None,None,None,None,None,None,None),
|
||||
(5,13,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||
(5,14,"GtkBox","homogeneous","True",0,None,None,None,None,None,None,None,None),
|
||||
(5,14,"GtkWidget","halign","end",0,None,None,None,None,None,None,None,None),
|
||||
(5,14,"GtkWidget","valign","center",0,None,None,None,None,None,None,None,None),
|
||||
(5,15,"GtkSwitch","active","True",0,None,None,None,None,None,None,None,None),
|
||||
(5,15,"GtkWidget","sensitive","False",0,None,None,None,None,None,None,None,None),
|
||||
(5,16,"AdwPreferencesRow","title","Fingerprint",0,None,None,None,None,None,None,None,None),
|
||||
(5,16,"GtkWidget","visible","False",None,None,None,None,None,None,None,None,None),
|
||||
(5,17,"GtkBox","homogeneous","True",0,None,None,None,None,None,None,None,None),
|
||||
(5,17,"GtkBox","spacing","5",None,None,None,None,None,None,None,None,None),
|
||||
(5,17,"GtkWidget","halign","end",0,None,None,None,None,None,None,None,None),
|
||||
(5,17,"GtkWidget","valign","center",0,None,None,None,None,None,None,None,None),
|
||||
(5,18,"GtkButton","label","Enable",None,None,None,None,None,None,None,None,None),
|
||||
(5,19,"GtkButton","label","Disable",None,None,None,None,None,None,None,None,None)
|
||||
</object_property>
|
||||
<object_data>
|
||||
(1,17,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(1,17,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(2,8,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(2,8,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(2,10,"GtkStringList",1,1,None,None,None,None,None,None),
|
||||
(2,10,"GtkStringList",2,2,"Auto",1,None,0,None,None),
|
||||
(2,10,"GtkStringList",2,3,"Percent",1,None,0,None,None),
|
||||
(2,10,"GtkStringList",2,4,"RPM",1,None,0,None,None),
|
||||
(2,6,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(2,6,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(3,5,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(3,5,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(3,24,"GtkStringList",1,1,None,None,None,None,None,None),
|
||||
(3,24,"GtkStringList",2,2,"Auto",1,None,0,None,None),
|
||||
(3,24,"GtkStringList",2,3,"Off",1,None,0,None,None),
|
||||
(3,26,"GtkStringList",1,1,None,None,None,None,None,None),
|
||||
(3,26,"GtkStringList",2,2,"Auto",1,None,0,None,None),
|
||||
(3,26,"GtkStringList",2,3,"Off",1,None,0,None,None),
|
||||
(3,18,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(4,2,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(4,2,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(4,31,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(4,31,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(5,2,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(5,2,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(4,41,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(4,41,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(4,42,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(4,42,"GtkWidget",2,2,None,1,None,None,None,None)
|
||||
</object_data>
|
||||
<object_data_arg>
|
||||
(1,17,"GtkWidget",2,2,"name","navigation-sidebar"),
|
||||
(2,8,"GtkWidget",2,2,"name","property"),
|
||||
(2,6,"GtkWidget",2,2,"name","boxed-list"),
|
||||
(3,5,"GtkWidget",2,2,"name","boxed-list"),
|
||||
(3,18,"GtkWidget",2,2,"name","destructive-action"),
|
||||
(4,2,"GtkWidget",2,2,"name","boxed-list"),
|
||||
(4,31,"GtkWidget",2,2,"name","property"),
|
||||
(5,2,"GtkWidget",2,2,"name","boxed-list"),
|
||||
(4,41,"GtkWidget",2,2,"name","property"),
|
||||
(4,42,"GtkWidget",2,2,"name","property")
|
||||
</object_data_arg>
|
||||
<!-- Created with Cambalache 0.96.3 -->
|
||||
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
|
||||
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
|
||||
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="89f5b68da04abad587d8b949d18357cd956313680e663b10e5d42697f9bfbf6e"/>
|
||||
<ui template-class="LedsPage" filename="leds.ui" sha256="abc3ee759974a5c92feb48cc258dbe7271d0402facf71fd5e779f2bb1a277e16"/>
|
||||
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="3a50b0dea08b9acbaa389d7d7a38bd94970fdc79207ef10638f722f52d9425cd"/>
|
||||
<ui template-class="HardwarePage" filename="hardware.ui" sha256="37ea282198d9f60435f80e4adf8256cd2249e590dcad4b63af634d828673f1bf"/>
|
||||
<ui template-class="BatteryPage" filename="battery.ui" sha256="d495280cb543a26cdee1c2939e5af980d8d3878c326e360eeab4f05195cdbdc9"/>
|
||||
</cambalache-project>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.94.1 -->
|
||||
<!-- Created with Cambalache 0.96.1 -->
|
||||
<interface>
|
||||
<!-- interface-name yafi.ui -->
|
||||
<!-- interface-description YAFI is another GUI for the Framework Laptop Embedded Controller. -->
|
||||
<!-- interface-authors Steve-Tech -->
|
||||
<requires lib="gtk" version="4.12"/>
|
||||
<requires lib="libadwaita" version="1.4"/>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<template class="YafiWindow" parent="AdwApplicationWindow">
|
||||
<property name="default-height">500</property>
|
||||
<property name="default-width">800</property>
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from gi.repository import Adw
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gtk, Adw
|
||||
|
||||
@Gtk.Template(resource_path='/au/stevetech/yafi/ui/yafi.ui')
|
||||
class YafiWindow(Adw.ApplicationWindow):
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<file preprocess="xml-stripblanks">ui/thermals.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/leds.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/battery.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/battery-limiter.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/hardware.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/au/stevetech/yafi/icons/scalable/actions">
|
||||
|
||||