Acpi su laptop
Introduzione
Questo how-to mira a spiegare come si può facilmente configurare il demone acpid. Per farlo serve:
- acpid
- text editor
- conoscenze minime di bash scripting
Individuare gli eventi
La prima cosa da fare e individuare gli eventi che ci interessano quindi aprite una console e date:
su tail -f /var/log/acpid | grep received
In questo modo è possibile avere i dati dei vari eventi. Si possono quindi ricavare gli eventi dovuti alla disconessione della batteria e dell'alimentatore (magari non contemporaneamente per non spegenere di brutto il pc). Nel mio caso ho ottenuto i seguenti risultati:
ac_adapter AC 00000080 00000000 alimentatore scollegato ac_adapter AC 00000080 00000001 alimentatore collegato battery BAT0 00000081 00000001 batteria in sede battery BAT0 00000080 00000000 batteria scollegata battery BAT0 00000080 00000001 batteria collegata button/lid LID 00000080 00000001 coperchio aperto button/lid LID 00000080 00000001 coperchio chiuso button/power PWRF 00000080 bottone spegnimento button/sleep SLPB 00000080 bottone sospensione
File di configurazione
Per interagire con l'acpi dobbiamo configurare il demone acpid. In partocolare a noi interessano:
/etc/acpi/events/default /etc/acpi/acpi_handler.sh
Il primo dovrebbe apparire così:
# This is the ACPID default configuration, it takes all # events and passes them to /etc/acpi/default.sh for further # processing. # event keeps a regular expression matching the event. To get # power events only, just use something like "event=button power.*" # to catch it. # action keeps the command to be executed after an event occurs # In case of the power event above, your entry may look this way: #event=button/power.* #action=/sbin/init 0 # Optionally you can specify the placeholder %e. It will pass # through the whole kernel event message to the program you've # specified. event=.* action=/etc/acpi/acpi_handler.sh %e
Come si può facilmente capire questo Script fa per ogni evento avvia lo script acpi_handler.sh passandogli il nome dell'evento. Questo lo lasceremo così com'è mentre iniziamo a costruire il nuovo acpi_handler.sh.
#!/bin/bash
#
# /etc/acpi/action.sh (2004.01.17)
# called by acpid for all events
# Christopher Knoerle <cknoerle@gmx.net>
# edited by l1q1d <l1q1d@yahoo.it>
# /etc/acpi/acpi_handler.sh
# Questo script è stato testato su un acer travelmate 210 tev
# Programmi e variabili che si useranno in seguito
LOGGER="/usr/bin/logger -t ACPID" # logs to syslog - an echo logs to /var/log/acpid
XGAMMA="/usr/X11R6/bin/xgamma"
XSET="/usr/X11R6/bin/xset"
HDPARM="/sbin/hdparm"
# È necessario mettere l'indirizzo giusto della batteria, dell'alimentatore e del coperchio
BAT_STATE="/proc/acpi/battery/BAT0/state"
BAT_INFO="/proc/acpi/battery/BAT0/info"
AC_STATE="/proc/acpi/ac_adapter/AC/state"
LID_STATE="/proc/acpi/button/lid/LID/state"
# Se lo script non sa come gestire questo evento
# scrive nel /var/log/acpid
# può essere utile per trovare 'grep #### /var/log/acpid'
# in alternativa si può sostituire echo con $LOGGER in modo da vederlo in /var/log/messages
no_action ()
{
echo "#### NO ACTION FOR EVENT: " $*
exit 1
}
# Pressione del bottone Sleep
btn_sleep ()
{
$LOGGER "Start Sleeping"
# Questo è un piccolo script creato da me che manda in sistema in sospensione
/sbin/suspend.sh
}
# AC Adapter plugged in
acad_in ()
{
$LOGGER "AC Adapter plugged IN"
if ps -A | grep -q X
then
$XGAMMA -d 0:0 -gamma 1.0 # set gamma in X to 100%
$XSET -d 0:0 dpms 0 0 600 # shutdown display after 600s
fi
$HDPARM -S 240 /dev/hda > /dev/null 2>&1 # spindown after 20min
$HDPARM -B 255 /dev/hda > /dev/null 2>&1 # disable drive's APM
}
# AC Adapter plugged out
acad_out ()
{
$LOGGER "AC Adapter plugged OUT"
if ps -A | grep -q X
then
$XGAMMA -d 0:0 -gamma 0.7 # set gamma in X to 70%
$XSET -d 0:0 dpms 0 0 120 # shutdown display after 120s
fi
$HDPARM -S 4 /dev/hda > /dev/null 2>&1 # spindown after 20s
$HDPARM -B 1 /dev/hda > /dev/null 2>&1 # enable drives's APM
}
# state of battery changed
# shutdown if battery capacity is low
battery ()
{
if grep -q discharging $BAT_STATE
then
BAT_REMAIN=`awk '/remaining/ { print $3 }' $BAT_STATE`
if (($BAT_REMAIN < `awk '/warning/ { print $4 }' $BAT_INFO`))
then
$LOGGER "battery capacity is critically low"
# Nel mio caso faccio sospendere il pc ma si può tranquillamente farlo spegnere
btn_sleep
# btn_pwr # Nel caso in cui lo si voglia far spegnere
fi
fi
}
# powerbutton pressed
btn_pwr ()
{
$LOGGER "Powerbutton pressed"
$LOGGER "shutdown initiated"
/sbin/init 0
}
# lid closed/opened
# Se avete da inserire qualche opzione per quando il coperchio si chiude (tipo metterlo in standby)
btn_lid ()
{
if grep -q open $LID_STATE
then
$LOGGER "Lid opened"
else
$LOGGER "Lid closed"
fi
}
# Con i dati ottunuti attraverso il
# tail -f /var/log/acpid | grep received
# si costruisce un case che farà eseguire i vari comandi
case "$*" in
ac_adapter\ AC\ 00000080\ 00000000)
acad_out
;;
ac_adapter\ AC\ 00000080\ 00000001)
acad_in
;;
battery\ BAT0\ 00000081\ 00000001)
battery
;;
battery\ BAT0\ 00000080\ 00000000)
$LOGGER "Battery Plugged Out"
;;
battery\ BAT0\ 00000080\ 00000001)
$LOGGER "Battery Plugged In"
;;
button?lid\ LID\ 00000080\ ????????)
# the last eight digits count the times the lid was shut
btn_lid
;;
button?power\ PWRF\ 00000080\ ????????)
# the last eight digits count the times the button was pressed
btn_pwr
;;
button?sleep\ SLPB\ 00000080\ ????????)
btn_sleep
;;
*)
no_action
;;
esac
Spero che i commenti nello script siano esaustivi, per lo script sulla sospensione del sistema dovete crearne uno apposito
Autore: L1q1d 21:07, 17 Ott 2006 (CEST)