- Rust 52.4%
- Shell 28%
- Python 19.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .archive/.github/workflows | ||
| config | ||
| distros | ||
| docs | ||
| legacy-python | ||
| src | ||
| systemd | ||
| .gitignore | ||
| acer-profile.install | ||
| Cargo.lock | ||
| Cargo.toml | ||
| install.sh | ||
| LICENSE | ||
| PKGBUILD | ||
| README.md | ||
acer-profile
Řízení výkonnostních profilů pro Acer Swift SFG14-73 (Intel Core Ultra 9
185H, Meteor Lake-H) na Linuxu. Jeden statický Rust binár, který nahrazuje
power-profiles-daemon (PPD) na DBus system bus a zároveň vlastní RAPL, EPP,
governor a i915 GPU frekvence.
Proč to existuje
Na tomto stroji je power-profiles-daemon rozbitý: při přepnutí z
performance do jiného profilu vrací zápis EPP EBUSY, protože PPD píše EPP
dřív než governor, a intel_pstate v governor=performance vlastní EPP a
jakýkoli zápis vrací trvale EBUSY. Profil uvízne a Plasma slider přestane
fungovat.
acer-profile řeší problém přímo: vlastní DBus jméno net.hadess.PowerProfiles
(i alias org.freedesktop.UPower.PowerProfiles pro PowerDevil), aplikuje
správné pořadí zápisů (governor → EPP → RAPL → GPU) a při
governor=performance EPP přeskočí. Žádný prostředník, žádný EBUSY.
Legacy reference: Neúplná původní verze v Pythonu je zachována v
legacy-python/pouze jako referenční implementace (vyvíjena před přepisem do Rustu, nepoužívat v provozu). Rust verze je aktuální a plnohodnotná.
Požadavky
Build
| Požadavek | Verze | Poznámka |
|---|---|---|
Rust toolchain (rustc + cargo) |
stable (testováno 1.96.1) | install.sh doinstaluje přes pacman/apt/dnf nebo rustup fallback |
pkg-config |
libovolná | cargo občas vyžaduje při linkování |
Runtime
| Požadavek | Balíček (Arch/Debian/Fedora) | Poznámka |
|---|---|---|
| Linux kernel | ≥ 6.x | sysfs intel-rapl, cpufreq/policy*, i915 |
systemd |
— | DBus system bus + service unit |
dbus (busctl) |
systemd / dbus / systemd dbus-tools |
pro ověření + PowerDevil komunikaci |
stress-ng |
stress-ng |
subcommand measure a probe-pl2 (zátěž CPU) |
lm_sensors (sensors) |
lm_sensors / lm-sensors / lm_sensors |
čtení Package teploty (`sensors |
Kernel / hardware předpoklady
intel_pstatedriver aktivní (scaling_governor,energy_performance_preference).intel-raplpowercap (/sys/class/powercap/intel-rapl:0/).i915GPU driver (gt_max_freq_mhz,gt_boost_freq_mhzzapisovatelné). Na tomto stroji Intel Arc Graphics (Meteor Lake-P) používá kernel driveri915(nexe).cpufreqpolicies na/sys/devices/system/cpu/cpufreq/policy*(22 policy).
Hardware specifikace Acer Swift SFG14-73 / Intel Core Ultra 9 185H (Meteor Lake-H):
- PBP=45 W (PL1), cTDP=35–65 W, MTP=115 W.
- Probe-validovaný PL2 strop=64 W (5089 MHz@83 °C; 80 W→98 °C throttle).
- i915 GPU: RPn/RP1=800 MHz, RP0/boost=2350 MHz.
Na strojích bez těchto sysfs cest
acer-profilegracefully přeskočí chybějící páky (nezhavaruje). Funkce ale závisí na jejich existenci.
Co ovládá
| Pák | sysfs cesta | Poznámka |
|---|---|---|
| RAPL PL1 (long-term) | intel-rapl:0/constraint_0_power_limit_uw |
Sustained power limit |
| RAPL PL2 (short-term) | intel-rapl:0/constraint_1_power_limit_uw |
Turbo power limit |
| EPP | policy*/energy_performance_preference |
power / balance_power / performance |
| Governor | policy*/scaling_governor |
powersave / performance |
| GPU max freq | i915/.../gt_max_freq_mhz |
i915 writable |
| GPU boost freq | i915/.../gt_boost_freq_mhz |
i915 writable, max musí být ≥ boost |
Cesty se objevují za běhu (glob přes std::fs), chybějící páky se gracefully
přeskočí. Fan control není dostupný (EC neimplementuje WMI misc setting
0x000B) — ventilatory zůstávají na EC auto-řízení.
Profily
Hodnoty kalibrované měřením (viz docs/PROFILY-TESTOVANI.md):
| Profil | PL1 | PL2 | EPP | Governor | GPU max/boost |
|---|---|---|---|---|---|
eco |
20 W | 25 W | power |
powersave |
800 / 800 MHz |
normal |
35 W | 45 W | balance_power |
powersave |
1600 / 1600 MHz |
performance |
45 W | 64 W | performance |
performance |
2350 / 2350 MHz |
Alias názvy (pro pohodlí / DBus kompatibilitu):
| Alias | Kanonický |
|---|---|
power-saver |
eco |
balanced |
normal |
performance / perf |
performance |
Konfigurace: /etc/acer-profile/profiles.toml (TOML, viz config/profiles.toml).
Po úpravě: sudo systemctl restart acer-profile.
State file: /var/lib/acer-profile/current (jeden řádek = kanonický název).
Persistuje se napříč rebootem, daemon ho po startu aplikuje.
Instalace
sudo ./install.sh
Skript:
- Zkontroluje a doinstaluje chybějící závislosti (
rust/cargo,stress-ng,lm_sensors,dbus) přespacman/apt/dnf(fallbackrustup). cargo build --release.- Zastaví starý Python daemon (
systemctl stop acer-profile) a smaže staré Python soubory (acer_profile/v site-packages, wrappery/usr/bin/acer-profilea/usr/bin/acer-profiled). State + config se zachovají. - Nainstaluje binár do
/usr/bin/acer-profile. - Zazálohuje existující config (nepřepíše uživatelské hodnoty z probe).
systemctl mask power-profiles-daemon(zabrání kolizi o DBus jméno; balíček zůstává, nikdy nenaběhne).- Nainstaluje systemd unitu,
enable --now acer-profile.service. - Ověří:
acer-profile status+busctl introspect.
Použití
# Stav hardwarových pák (čtení, bez roota)
acer-profile status
# Seznam profilů s hodnotami
acer-profile list
# Nastavení profilu (vyžaduje root — zápis sysfs + state file)
sudo acer-profile set eco
sudo acer-profile set normal
sudo acer-profile set performance
# Sledování změn profilu (foreground, bez roota)
acer-profile watch
# Srovnání profilů: zátěž + vzorkování CPU freq/teploty (root)
sudo acer-profile measure
# Detekce stropu PL2 s teplotní ochranou (root)
sudo acer-profile probe-pl2
# DBus service mód (pro systemd, normálně nespouštět ručně)
acer-profile daemon
Plasma slider
Po instalaci a restartu plasma-powerdevil.service funguje Plasma battery
widget slider (Power Saver / Balanced / Performance) přes DBus do root daemonu
— bez sudo, bez EBUSY.
Pokud widget po instalaci ukazuje chybovou hlášku, restartuj PowerDevil:
systemctl --user restart plasma-powerdevil.service
Plasma používá dvě kontroly:
isServiceRegistered("org.freedesktop.UPower.PowerProfiles")na system bus → "PPD nainstalován".GetAllna cestě/org/freedesktop/UPower/PowerProfiles→ načteProfilesaActiveProfile.
Proto daemon registruje obě bus jména (net.hadess.PowerProfiles +
org.freedesktop.UPower.PowerProfiles) a slouží interface na obou cestách
(/net/hadess/PowerProfiles + /org/freedesktop/UPower/PowerProfiles).
Subcommandy detailně
status
Vypíše: aktivní profil, RAPL PL1/PL2 (aktuální + max), EPP, governor, CPU max frekvenci, GPU frekvence (cur/max/boost/RP0/RPn), teploty.
list
Vypíše všechny 3 profily s hodnotami a aliasy.
set <profil>
Aplikuje profil (governor → EPP → RAPL → GPU), persistuje do state file.
Akceptuje aliasy (power-saver, balanced, performance, eco, normal,
perf). Vyžaduje root.
measure
Pro každý profil (eco, normal, performance):
setprofil, 2 s settle.- Snapshot (idle): EPP/gov/PL1/PL2/GPU/teplota.
- 15 s
stress-ng --cpu $(nproc), vzorkováníscaling_cur_freq(max, průměr). - Snapshot po zátěži.
- 20 s cooldown.
Na konci návrat na normal. Výstup je tabulka pro porovnání frekvencí a teplot
mezi profily. Vyžaduje root.
probe-pl2
Bezpečná inkrementální detekce stropu PL2:
- Kroky: 64 → 80 → 100 → 115 W (nikdy nepřesáhne Intel MTP 115 W).
- 8 s
stress-ngna každý krok, teplotní ochrana 95 °C (při překročení zastaví). - 20 s cooldown mezi kroky.
- Detekuje VRM/EC tunel (když přijatý W ≠ požadovaný W).
- Na konci návrat na
normal+ doporučení proprofiles.toml.
Vyžaduje root.
watch
Sleduje state file, při změně vypíše timestamp + profil + status. Default
interval 1 s (-i). Bez roota (jen čtení).
daemon
DBus service mód — registruje net.hadess.PowerProfiles +
org.freedesktop.UPower.PowerProfiles na system bus, aplikuje startovní profil
z state file, polling (1 s) sleduje state file pro CLI změny a emituje
PropertiesChanged na obou cestách. Běží přes systemd (Type=simple).
Architektura
acer-profile (jeden binár)
├── main.rs clap dispatch: status/list/set/watch/measure/probe-pl2/daemon
├── levers.rs sysfs: RAPL, EPP/governor (pořadí+EBUSY retry+skip), i915 GPU, teploty
├── profiles.rs serde Profile + TOML load + aliasy + PPD name mapping
├── controller.rs apply pořadí + state file + set_profile
├── dbus.rs net.hadess.PowerProfiles + org.freedesktop.UPower.PowerProfiles (alias)
├── daemon.rs blocking DBus connection + boot persist + polling + PropertiesChanged
├── measure.rs measure subcommand (stress-ng + sampling)
└── probe.rs probe-pl2 subcommand (inkrementální + teplotní ochrana)
Závislosti (Cargo)
serde, toml, clap, log, env_logger, anyhow, zbus (blocking, async-io feature), async-io
Žádný async runtime (tokio). Vše std::* + zbus blocking API.
Klíčové implementční detaily
- Pořadí zápisu: governor → EPP → RAPL → GPU. Při
governor=performancese EPP přeskočí (intel_pstate ho vlastní, jinak EBUSY). - EBUSY retry: 3× se sleep 150 ms (pomáhá pro transientní race na
eco/normal; pro
governor=performanceje EBUSY trvalý, proto skip). - GPU EINVAL tolerance: i915 runtime PM race, errno 22 se toleruje (zápis se často přesto aplikuje).
- glob bez externí crate: vlastní
glob_paths()přesstd::fs::read_dirs*matchem. - DBus dual registration: obě jména + obě cesty, aby PowerDevil proxy
(
/org/freedesktop/UPower/PowerProfiles) ibusctl(/net/hadess/...) fungovaly. - PropertiesChanged: vygenerovaný
<prop>_changed(&self, sc)přesasync_io::block_onz polling loopu (zbus 4.x).
Získání zdrojového kódu / build
git clone https://github.com/David-Nahorniak/acer-profile-rs.git
cd acer-profile-rs
# Build
cargo build --release
# Lint
cargo clippy --release
# Binár
target/release/acer-profile
Předkompilované binárky (.tar.gz, .deb, .rpm) pro x86_64 (gnu i musl)
jsou k dispozici na GitHub Releases.
Musl varianta je plně statický binár (bez glibc závislosti) — portable napříč
distry. GNU varianta + .deb/.rpm jsou linkované proti glibc (nativní pro
běžné distribuce).
Rust toolchain: stable (testováno 1.96.1). Pokud není nainstalovaný,
install.sh ho doinstaluje (pacman/apt/dnf nebo rustup fallback).
DBus ověření
# Náš interface (net.hadess)
busctl introspect net.hadess.PowerProfiles /net/hadess/PowerProfiles
# Alias interface (PowerDevil používá tento)
busctl introspect org.freedesktop.UPower.PowerProfiles /org/freedesktop/UPower/PowerProfiles
# GetAll přes alias
busctl call org.freedesktop.UPower.PowerProfiles /org/freedesktop/UPower/PowerProfiles \
org.freedesktop.DBus.Properties GetAll s org.freedesktop.UPower.PowerProfiles
# PowerDevil proxy (má vracet 3 profily)
busctl --user call org.kde.Solid.PowerManagement \
/org/kde/Solid/PowerManagement/Actions/PowerProfile \
org.kde.Solid.PowerManagement.Actions.PowerProfile profileChoices
Reversibilita (návrat k PPD)
sudo systemctl disable --now acer-profile
sudo systemctl unmask power-profiles-daemon
sudo systemctl enable --now power-profiles-daemon
PPD byl jen masknut (ne odinstalován), takže návrat je reverzibilní.
Bezpečnost
- RAPL = power limit, ne napětí (žádný overvolt). Nepersistuje přes reboot.
probe-pl2: teplotní ochrana 95 °C, nikdy přes Intel MTP 115 W, inkrementální.- THERMTRIP ~110 °C = hardwarová záchrana (OS neovládá).
- DBus service běží jako root (zápis sysfs); memory-safe Rust, attack surface omezený na DBus + sysfs (žádné vstupy z internetu).
Soubory
acer-profile-rs/
├── Cargo.toml
├── Cargo.lock
├── README.md
├── install.sh # instalace + mask PPD
├── PKGBUILD # AUR bonus (acer-profile-git)
├── acer-profile.install # AUR pre/post hooks
├── config/profiles.toml # kalibrované hodnoty profilů
├── systemd/acer-profile.service # Type=simple, ExecStart=/usr/bin/acer-profile daemon
├── docs/PROFILY-TESTOVANI.md # testovací dokumentace
├── src/
│ ├── main.rs
│ ├── levers.rs
│ ├── profiles.rs
│ ├── controller.rs
│ ├── dbus.rs
│ ├── daemon.rs
│ ├── measure.rs
│ └── probe.rs
└── legacy-python/ # neúplná původní Python verze (jen reference)
├── acer_profile/
├── config/
├── docs/
├── systemd/
├── install.sh
├── phase1-*.sh / phase2-measure.sh / probe-pl2.sh
└── pyproject.toml
Licence
MIT.