Linux - lepsze sterowanie zarządzaniem energii ACPI i fglrx.
21 listopada, 2008
Jakiś czas temu pisałem o fglrx i oszczędzaniu energii. Stwierdziłem, że znaczne ulepszenie istniejącego skryptu jest proste. Poniżej efekty w postaci dobrego zarządzania.
Jak pisałem, poprzednio były tylko dwa tryby: low power (przy pracy na zamkniętej pokrywie i na baterii), oraz default. Na dodatek wartości dobierane były na sztywno na podstwie tego, co aticonfig --lsp zwraca jako default i low.
Obecnie definiowane są 3 wartości:
- Praca przy zamkniętej pokrywie
- Praca na baterii i otwartej pokrywie
- Praca na zasilaczu i otwartej pokrywie
Wartości definiuje się wprost w pliku /etc/default/fglrx:
FGLRX_ACPI_SWITCH_POWERSTATES=true FGLRX_ACPI_LIDCLOSE_MODE=1 FGLRX_ACPI_BATTERY_MODE=2 FGLRX_ACPI_AC_MODE=3
Cyfry to oczywiście numery trybu zwracane przez aticonfig --lsp. W powyższym ustawieniu: jeśli zamykamy pokrywę (czyt. nie korzystamy z grafiki), to maksymalnie ją spowalniamy (jedyny powód, by tego nie robić to ogrzewanie mieszkania grafiką - pomijam), jeśli pracujemy na baterii, to pracujemy na średniej wydajności, a jeśli mamy prąd, to bierzemy ile fabryka dała. Oczywiście nie ma przeciwskazań, by ustawić np. wszędzie 1 (ja tak mam).
Największe modyfikacje to plik /etc/acpi/fglrx-powermode.sh. Obecnie wygląda on tak:
#!/bin/bash
. /etc/default/fglrx
if [ x$FGLRX_ACPI_SWITCH_POWERSTATES != xtrue ]; then
exit;
fi
getXuser() {
user=`finger| grep -m1 ":$displaynum " | awk '{print $1}'`
if [ x"$user" = x"" ]; then
user=`finger| grep -m1 ":$displaynum" | awk '{print $1}'`
fi
if [ x"$user" != x"" ]; then
userhome=`getent passwd $user | cut -d: -f6`
export XAUTHORITY=$userhome/.Xauthority
else
export XAUTHORITY=""
fi
}
grep -q closed /proc/acpi/button/lid/*/state
if [ $? = 0 ]; then
lid_closed=1
else
lid_closed=0
fi
grep -q off-line /proc/acpi/ac_adapter/*/state
if [ $? = 0 ]; then
on_dc=1
else
on_dc=0
fi
if [ ${lid_closed} -eq 1 ]; then
echo "fglrx: setting low power"
for x in /tmp/.X11-unix/*; do
displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
getXuser;
if [ x"$XAUTHORITY" != x"" ]; then
export DISPLAY=":$displaynum"
powermode=$FGLRX_ACPI_LIDCLOSE_MODE
if [ x"$powermode" != x"" ]; then
su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null
fi
fi
done
else
if [ ${on_dc} -eq 0 ]; then
echo "fglrx: setting AC powermode"
for x in /tmp/.X11-unix/*; do
displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
getXuser;
if [ x"$XAUTHORITY" != x"" ]; then
export DISPLAY=":$displaynum"
powermode=$FGLRX_ACPI_AC_MODE
if [ x"$powermode" != x"" ]; then
su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null
fi
fi
done
else
echo "fglrx: setting battery powermode"
for x in /tmp/.X11-unix/*; do
displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
getXuser;
if [ x"$XAUTHORITY" != x"" ]; then
export DISPLAY=":$displaynum"
powermode=$FGLRX_ACPI_BATTERY_MODE
if [ x"$powermode" != x"" ]; then
su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null
fi
fi
done
fi
fi
Skrypt nie był testowany na okoliczność błędów typu niezdefiniowana czy błędna wartość dla któregoś trybu, poza tym wygląda, że działa OK. Zachęcam do poprawek/uwag.
