Plasmoide CPU Frequency Control: governor, limiti, EPP, boost e profili per task

Widget KDE Plasma 6 (org.enne2.cpufreq) per pilotare il profilo energetico della
CPU: governor, limiti min/max, energy_performance_preference, boost/turbo,
quattro profili pronti (Silenzioso, Risparmio, Bilanciato, Performance) e task
con profilo dedicato che ripristina lo stato precedente alla fine del comando.

Privilegi separati: il widget resta non privilegiato e l'unica operazione root
passa da un helper a interfaccia ristretta in /usr/local/libexec/enne2-cpufreq/
(comandi a elenco chiuso, argomenti validati su sysfs, rilettura di verifica),
invocato via pkexec con l'azione polkit dedicata org.enne2.cpufreq.set. La regola
in /etc/polkit-1/rules.d/ concede il consenso senza prompt a utenti locali in
sessione attiva nel gruppo wheel; senza la regola la policy chiede la password.

Dettagli verificati su frigate (Plasma 6.7.5, kernel 7.2, amd-pstate-epp):
- con boost disattivato cpuinfo_max_freq scende alla frequenza nominale, quindi
  il tetto hardware si legge da amd_pstate_max_freq e i profili applicano il
  boost prima dei limiti;
- scrittura dei limiti in ordine sicuro (mai min > max intermedio);
- baseline e contatore di riferimento per i task paralleli;
- syncControls protetto da uiReady e try/catch: un ReferenceError su un id della
  rappresentazione non deve interrompere l'aggiornamento dello stato;
- implicitWidth/Height costanti, altrimenti il containment riduce il widget a
  68x68.

Include install.sh/uninstall.sh (widget, backend, dry-run), README con modello di
sicurezza e diagnostica, screenshot docs/widget.png. Licenza MIT.
This commit is contained in:
enne2
2026-10-25 20:42:52 +01:00
commit d4902b0b72
15 changed files with 2674 additions and 0 deletions
Executable
+147
View File
@@ -0,0 +1,147 @@
#!/bin/sh
# SPDX-License-Identifier: MIT
# enne2-cpufreq — installazione.
#
# ./install.sh widget (utente) + backend privilegiato (sudo)
# ./install.sh --widget solo il plasmoide, come utente
# ./install.sh --backend solo helper + polkit, come root
# ./install.sh --no-polkit-rule
# backend senza la regola "nessun prompt":
# ogni modifica chiederà la password
# ./install.sh --dry-run mostra cosa verrebbe fatto
set -u
PKG_DIR=$(cd "$(dirname "$0")" && pwd)
ID=org.enne2.cpufreq
LIBDIR=/usr/local/libexec/enne2-cpufreq
POLICY_DST=/usr/share/polkit-1/actions/org.enne2.cpufreq.set.policy
RULE_DST=/etc/polkit-1/rules.d/50-org.enne2.cpufreq.rules
STATEDIR=/var/lib/enne2-cpufreq
MODE=all
WITH_RULE=1
DRY=0
for arg in "$@"; do
case "$arg" in
--widget) MODE=widget ;;
--backend) MODE=backend ;;
--all) MODE=all ;;
--no-polkit-rule) WITH_RULE=0 ;;
--dry-run|-n) DRY=1 ;;
-h|--help)
sed -n 's/^# \{0,1\}//p' "$0" | sed -n '1,20p'
exit 0
;;
*) printf 'opzione sconosciuta: %s\n' "$arg" >&2; exit 2 ;;
esac
done
say() { printf '%s\n' "$*"; }
run() {
if [ "$DRY" -eq 1 ]; then
printf ' [dry-run] %s\n' "$*"
else
"$@"
fi
}
have_widget() {
kpackagetool6 --type Plasma/Applet --show "$ID" >/dev/null 2>&1
}
install_widget() {
command -v kpackagetool6 >/dev/null 2>&1 || {
say "ERRORE: kpackagetool6 non trovato (pacchetto kpackagetool6/kf6-kpackage)."
return 1
}
if [ "$DRY" -eq 1 ]; then
say "[dry-run] kpackagetool6 --type Plasma/Applet --install|--upgrade $PKG_DIR"
elif have_widget; then
say "Aggiorno il plasmoide $ID…"
kpackagetool6 --type Plasma/Applet --upgrade "$PKG_DIR" || return 1
else
say "Installo il plasmoide $ID…"
kpackagetool6 --type Plasma/Applet --install "$PKG_DIR" || return 1
fi
WIDGET_DIR=$HOME/.local/share/plasma/plasmoids/$ID
if [ "$DRY" -eq 0 ] && [ -d "$WIDGET_DIR/contents/scripts" ]; then
chmod 0755 "$WIDGET_DIR"/contents/scripts/*.sh \
"$WIDGET_DIR"/contents/scripts/enne2-cpufreq-task 2>/dev/null
fi
# comodità da terminale: stesso launcher del widget
if [ "$DRY" -eq 0 ] && [ -d "$HOME/.local/bin" ]; then
ln -sfn "$WIDGET_DIR/contents/scripts/enne2-cpufreq-task" \
"$HOME/.local/bin/enne2-cpufreq-task"
say "Comando utente: ~/.local/bin/enne2-cpufreq-task (list|add|run|stop)"
fi
return 0
}
install_backend() {
if [ "$(id -u)" -ne 0 ]; then
say "ERRORE: la parte privilegiata richiede root (usare sudo)."
return 1
fi
say "Backend privilegiato in $LIBDIR"
run install -d -m 0755 -o root -g root "$LIBDIR"
run install -d -m 0755 -o root -g root "$STATEDIR"
run install -m 0755 -o root -g root "$PKG_DIR/bin/cpufreq-helper" "$LIBDIR/cpufreq-helper"
run install -m 0644 -o root -g root "$PKG_DIR/contents/scripts/profiles.sh" "$LIBDIR/profiles.sh"
say "Azione polkit: $POLICY_DST"
run install -d -m 0755 /usr/share/polkit-1/actions
run install -m 0644 -o root -g root \
"$PKG_DIR/polkit/org.enne2.cpufreq.set.policy" "$POLICY_DST"
if [ "$WITH_RULE" -eq 1 ]; then
say "Regola polkit senza prompt (gruppo wheel, sessione attiva): $RULE_DST"
run install -d -m 0755 /etc/polkit-1/rules.d
run install -m 0644 -o root -g root \
"$PKG_DIR/polkit/50-org.enne2.cpufreq.rules" "$RULE_DST"
else
say "Regola senza prompt NON installata: verrà chiesta la password a ogni modifica."
run rm -f "$RULE_DST"
fi
# polkitd sorveglia le directory delle regole, il reload è solo una sicurezza
if [ "$DRY" -eq 0 ]; then
systemctl try-reload-or-restart polkit >/dev/null 2>&1 || true
fi
say ""
say "Verifica:"
if [ "$DRY" -eq 0 ]; then
"$LIBDIR/cpufreq-helper" status | sed 's/^/ /'
fi
return 0
}
case "$MODE" in
widget)
install_widget
;;
backend)
install_backend
;;
all)
install_widget || exit 1
say ""
if [ "$(id -u)" -eq 0 ]; then
install_backend || exit 1
else
say "Parte privilegiata: sudo $0 --backend $([ "$WITH_RULE" -eq 0 ] && echo --no-polkit-rule)"
if [ "$DRY" -eq 1 ]; then
sudo -n true >/dev/null 2>&1 && sudo "$0" --backend $([ "$WITH_RULE" -eq 0 ] && echo --no-polkit-rule) || say "[dry-run] sudo richiesto"
else
sudo "$0" --backend $([ "$WITH_RULE" -eq 0 ] && echo --no-polkit-rule) || exit 1
fi
fi
;;
esac
say ""
say "Fatto. Aggiungi il widget dal desktop (Aggiungi widget → «CPU Frequency Control»)"
say "oppure via script: desktops()[0].addWidget(\"$ID\")"