#!/bin/sh # SPDX-License-Identifier: MIT # enne2-cpufreq — lettore di stato NON privilegiato per il plasmoide. # Legge solo attributi world-readable di sysfs, /proc e hwmon; non scrive nulla. # Uscita: righe key=value (formato usato dagli altri widget org.enne2.*). set -u SELF_DIR=$(dirname "$0") if [ -r "$SELF_DIR/profiles.sh" ]; then # shellcheck source=profiles.sh . "$SELF_DIR/profiles.sh" else printf 'helper=missing\nerror=profiles.sh mancante\n' exit 2 fi CPUFREQ=/sys/devices/system/cpu/cpufreq HELPER=/usr/local/libexec/enne2-cpufreq/cpufreq-helper POLICY_POLKIT=/usr/share/polkit-1/actions/org.enne2.cpufreq.set.policy RULE_POLKIT=/etc/polkit-1/rules.d/50-org.enne2.cpufreq.rules CONF_DIR=${XDG_CONFIG_HOME:-$HOME/.config}/enne2-cpufreq TASKS=$CONF_DIR/tasks.json RUN=${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/enne2-cpufreq readf() { [ -r "$1" ] || return 1 _val= IFS= read -r _val < "$1" 2>/dev/null || [ -n "$_val" ] || return 1 printf '%s\n' "$_val" } policies() { for _p in "$CPUFREQ"/policy[0-9]*; do [ -d "$_p" ] && printf '%s\n' "$_p" done } attr_values() { for _p in $(policies); do readf "$_p/$1" done | sort -u | tr '\n' ' ' | sed 's/ *$//' } p0=$(policies | head -n 1) if [ -z "$p0" ]; then printf 'helper=missing\nerror=nessuna policy cpufreq (driver non cpufreq?)\n' exit 2 fi driver=$(readf "$p0/scaling_driver" || echo unknown) hw_min=$(readf "$p0/cpuinfo_min_freq" || echo 0) hw_max=$(cf_hw_max_khz "$p0") # indipendente dallo stato del boost floor=$(readf "$p0/amd_pstate_lowest_nonlinear_freq" || echo "") [ -n "$floor" ] && [ "$floor" -gt "$hw_min" ] || floor=$hw_min min_khz=$(readf "$p0/scaling_min_freq" || echo 0) max_khz=$(readf "$p0/scaling_max_freq" || echo 0) governor=$(attr_values scaling_governor) governors=$(readf "$p0/scaling_available_governors" || echo "") epp=$(attr_values energy_performance_preference) epps=$(readf "$p0/energy_performance_available_preferences" || echo "") epp_supported=0 [ -n "$epps" ] && epp_supported=1 # boost: per-policy (kernel recenti) → globale → intel_pstate/no_turbo invertito boost=$(readf "$p0/boost" || readf "$CPUFREQ/boost" || echo "") boost_supported=0 [ -n "$boost" ] && boost_supported=1 if [ "$boost_supported" -eq 0 ] && [ -r /sys/devices/system/cpu/intel_pstate/no_turbo ]; then _nt=$(readf /sys/devices/system/cpu/intel_pstate/no_turbo) [ "$_nt" = "1" ] && boost=0 || boost=1 boost_supported=1 fi # frequenza istantanea: massima fra le policy (core più attivo) e media sum=0 cnt=0 curmax=0 for _p in $(policies); do _f=$(readf "$_p/scaling_cur_freq") || continue case "$_f" in ''|*[!0-9]*) continue ;; esac sum=$((sum + _f)) cnt=$((cnt + 1)) [ "$_f" -gt "$curmax" ] && curmax=$_f done [ "$cnt" -gt 0 ] || cnt=1 cur_avg=$((sum / cnt)) temp=$(readf /sys/class/hwmon/hwmon0/temp1_input 2>/dev/null || echo "") for _h in /sys/class/hwmon/hwmon*; do [ -r "$_h/name" ] || continue case "$(readf "$_h/name")" in k10temp|coretemp|zenpower) temp=$(readf "$_h/temp1_input" || echo "") break ;; esac done model=$(sed -n 's/^model name[[:space:]]*: //p' /proc/cpuinfo | head -n 1) load1=$(awk '{print $1}' /proc/loadavg) helper_state=missing [ -x "$HELPER" ] && helper_state=ok polkit_state=missing if [ -r "$POLICY_POLKIT" ] && [ -r "$RULE_POLKIT" ]; then polkit_state=ok elif [ -r "$POLICY_POLKIT" ]; then polkit_state=ask fi conflicts="" for _svc in tuned power-profiles-daemon tlp; do if systemctl is-active --quiet "$_svc" 2>/dev/null; then conflicts="$conflicts $_svc" fi done conflicts=${conflicts# } profile=$(cf_detect_profile "${governor:-}" "${epp:-}" "${boost:-0}" "$max_khz" "$floor" "$hw_max") printf 'driver=%s\n' "$driver" printf 'mode=%s\n' "$(readf /sys/devices/system/cpu/amd_pstate/status || echo n/a)" printf 'model=%s\n' "$model" printf 'policies=%s\n' "$cnt" printf 'governor=%s\n' "$governor" printf 'governors=%s\n' "$governors" printf 'epp=%s\n' "$epp" printf 'epps=%s\n' "$epps" printf 'epp_supported=%s\n' "$epp_supported" printf 'boost=%s\n' "$boost" printf 'boost_supported=%s\n' "$boost_supported" printf 'hw_min_khz=%s\n' "$hw_min" printf 'hw_max_khz=%s\n' "$hw_max" printf 'floor_khz=%s\n' "$floor" printf 'min_khz=%s\n' "$min_khz" printf 'max_khz=%s\n' "$max_khz" printf 'cur_khz=%s\n' "$curmax" printf 'cur_avg_khz=%s\n' "$cur_avg" printf 'temp_mdegc=%s\n' "$temp" printf 'load1=%s\n' "$load1" printf 'profile=%s\n' "$profile" printf 'profile_label=%s\n' "$(cf_profile_label "$profile")" printf 'helper=%s\n' "$helper_state" printf 'polkit=%s\n' "$polkit_state" printf 'conflicts=%s\n' "$conflicts" [ -r /var/lib/enne2-cpufreq/baseline ] && printf 'baseline=present\n' || printf 'baseline=absent\n' # ---- task configurati (un file JSON gestito da enne2-cpufreq-task) ---------- # Formato di ogni riga: task= # Il JSON (jq -c, una riga) evita ogni ambiguità su spazi, tabulazioni e pipe # dentro i comandi definiti dall'utente. if command -v jq >/dev/null 2>&1 && [ -r "$TASKS" ]; then _count=$(jq -r '.tasks | length' "$TASKS" 2>/dev/null || echo 0) printf 'task_count=%s\n' "${_count:-0}" _i=0 jq -c '.tasks[] | {name: .name, profile: .profile, command: .command, slug: .slug}' \ "$TASKS" 2>/dev/null | while IFS= read -r _line; do [ -n "$_line" ] || continue _slug=$(printf '%s' "$_line" | jq -r '.slug // ""' 2>/dev/null) _running=0 if [ -n "$_slug" ] && [ -r "$RUN/$_slug.pid" ]; then _pid=$(readf "$RUN/$_slug.pid") case "$_pid" in ''|*[!0-9]*) _running=0 ;; *) kill -0 "$_pid" 2>/dev/null && _running=1 ;; esac fi printf 'task=%s\t%s\t%s\n' "$_i" "$_running" "$_line" _i=$((_i + 1)) done else printf 'task_count=0\n' fi printf 'ts=%s\n' "$(date +%s)"