Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[HOWTO] Come spegnere il tuo laptop se la batteria e' finita
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

Goto page 1, 2  Next  
Reply to topic    Gentoo Forums Forum Index Forum italiano (Italian) Risorse italiane (documentazione e tools)
View previous topic :: View next topic  
Author Message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Wed May 26, 2004 8:04 pm    Post subject: [HOWTO] Come spegnere il tuo laptop se la batteria e' finita Reply with quote

[EDIT 12/12/05]
1. modificato il metodo di avvio dello script (cazzantonio)
2. gestione batteria hotplug (cazzantonio)
3. aumentata la verbosita' dello script (log + precisi) (io)
4. leggero abbellimento complessivo del codice (io)

Alla fine dopo molte ricerche ho deciso di arrangiarmi usando Perl.


Il problema e' quello di voler spegnere il mio laptop quando, in presenza di una prolungata assenza di alimentazione di rete, anche la batteria arriva verso la fine.

Avevo postato qui:

https://forums.gentoo.org/viewtopic.php?t=174846&highlight=acpi+batteria
https://forums.gentoo.org/viewtopic.php?t=158030&highlight=acpi+batteria
https://forums.gentoo.org/viewtopic.php?t=137711&highlight=acpi+batteria

senza ottenere grande risultati comunque ecco lo script in Perl:

Code:

#!/usr/bin/perl -w

#
#    checkbattery.pl
#
#    Checks your laptop battery state... if it's too low a nice
#    command like `/sbin/poweroff' will be executed.
#
#    Copyright (C) 2004 Matteo Guglielmi
#
#
#    License:
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#    General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software Foundation,
#    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

############################################################################
#                                                                          #
# DECLARATIONS                                                             #
#                                                                          #
############################################################################

# SOME OF THE FLAGS BELOW WILL BE SET LATER ON BY THIS SCRIPT

my $pname            = 'checkbattery.pl';
my $state_file       = '/proc/acpi/battery/BAT0/state';
my $shutdown         = '/sbin/poweroff';
my $logger           = "/usr/bin/logger -t $pname ";
my $capacity_warning = 400;
my $more             = 60;   # seconds
my $less             = 30;   # seconds
my $capacity_is      = '';
my $state_is         = '';

############################################################################
#                                                                          #
# SUBROUTINES                                                              #
#                                                                          #
############################################################################

############################################################################
#                                                                          #
# SUB: get_battery_presence                                                #
#                                                                          #
# DESCRIPTION: Gets battery presence state                                 #
#                                                                          #
# USAGE: &get_battery_presence(BatteryStateFile)                           #
#                                                                          #
# EXAMPLE: &get_battery_presence('/proc/acpi/battery/BAT0/state');         #
#                                                                          #
# EXTERNAL DATA USED: None                                                 #
#                                                                          #
############################################################################

sub get_battery_presence {
  my $read_state = 'not defined';

  if (open(STATEFILE, "<$_[0]")) {

    while (defined($row = <STATEFILE>)) {
      chomp($row);

      if ($row =~ m/^present:\s+([a-z]+)$/) {
        $read_state = $1;
        last;
      }
    }

    close(STATEFILE);
  }

  return $read_state;
}

############################################################################
#                                                                          #
# SUB: get_charging_state                                                  #
#                                                                          #
# DESCRIPTION: Gets battery charging state                                 #
#                                                                          #
# USAGE: &get_charging_state(BatteryStateFile)                             #
#                                                                          #
# EXAMPLE: &get_charging_state('/proc/acpi/battery/BAT0/state');           #
#                                                                          #
# EXTERNAL DATA USED: None                                                 #
#                                                                          #
############################################################################

sub get_charging_state {
  my $read_state = 'not defined';

  if (open(STATEFILE, "<$_[0]")) {

    while (defined($row = <STATEFILE>)) {
      chomp($row);

      if ($row =~ m/^charging\s+state:\s+([a-z]+)$/) {
        $read_state = $1;
        last;
      }
    }

    close(STATEFILE);
  }

  return $read_state;
}

############################################################################
#                                                                          #
# SUB: get_remaining_capacity                                              #
#                                                                          #
# DESCRIPTION: Gets battery remaining capacity                             #
#                                                                          #
# USAGE: &get_remaining_capacity(BatteryStateFile)                         #
#                                                                          #
# EXAMPLE: &get_remaining_capacity('/proc/acpi/battery/BAT0/state');       #
#                                                                          #
# EXTERNAL DATA USED: None                                                 #
#                                                                          #
############################################################################

sub get_remaining_capacity {
  my $read_capacity = 'not defined';

  if (open(STATEFILE, "<$_[0]")) {

    while (defined($row = <STATEFILE>)) {
      chomp($row);

      if ($row =~ m/^remaining\s+capacity:\s+(\d+)\s+mAh$/) {
        $read_capacity = $1;
        last;
      }
    }

    close(STATEFILE);
  }

  return $read_capacity;
}



############################################################################
#                                                                          #
#                           BEGIN MAIN SCRIPT                              #
#                                                                          #
############################################################################

while (1) {
  $battery_presence = &get_battery_presence($state_file);

  if ($battery_presence eq 'yes') {
    $state_is = &get_charging_state($state_file);

    if ($state_is eq 'charging' || $state_is eq 'charged') {
      sleep($more);
    } elsif ($state_is eq 'discharging') {
      $capacity_is = &get_remaining_capacity($state_file);

      if ($capacity_is eq 'not defined') {
        system("$logger"."could not open ``$state_file'' or capacity state $capacity_is");
      } else {
        system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");

        if ($capacity_is <= $capacity_warning) {
          system("$logger"."battery discharging: capacity too much low");
          system("$shutdown");
          last;
        } else {
          sleep($less);
        }
      }
    } else {
      system("$logger"."could not open ``$state_file'' or battery state $state_is");
#      system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#      last;
      sleep($less);
    }
  } elseif ($battery_presence eq 'no') {
    system("$logger"."battery not present");
    sleep($more);
  } else {
    system("$logger"."could not open ``$state_file'' or battery presence $battery_presence");
    sleep($more);
  }
}

############################################################################
#                                                                          #
#                               END MAIN SCRIPT                            #
#                                                                          #
############################################################################


Per ``installarlo'' basta copiarlo dove si vuole tipo:

Code:

# cp ./checkbattery.pl /usr/local/bin
# chmod 744 /usr/local/bin/checkbattery.pl

e poi editare i seguenti file:

Code:

# nano -w /etc/conf.d/local.start

aggiungendo la linea:

Code:

/usr/local/bin/checkbattery.pl & echo $! > /tmp/checkbattery.pid



Code:

# nano -w /etc/conf.d/local.stop

aggiungendo la linea:

Code:

if [ -f /tmp/checkbattery.pid ]; then
  kill -15 `cat /tmp/checkbattery.pid`
  rm /tmp/checkbattery.pid
fi


ed in fine:

Code:

# /etc/init.d/local restart


Volendo e' possibile anche lanciarlo utilizzando il seguente script di init:
Code:
#vim checkbattery


Code:
#!/sbin/runscript

depend() {
        need localmount acpid logger
}

start() {
        ebegin "Starting checkbattery script"
        /scripts/sbin/checkbattery.pl & echo $! > /tmp/checkbattery.pid
        eend $? "Failed to start checkbattery script"
        [ `ps aux |grep checkbattery.pl|wc -l` -eq 1 ] && rm /tmp/checkbattery.pid       
}

stop() {
        ebegin "Stopping checkbattery script"
        if [ -f /tmp/checkbattery.pid ]; then
          kill -15 `cat /tmp/checkbattery.pid`
          rm /tmp/checkbattery.pid
        fi
}


ricordandosi poi di dare un bel:
Code:
# rc-update add checkbattery default

alla fine.

Come funziona:

prima di tutto acpi deve essere installato ovvero dovete avere in /proc/acpi/da/qualche/parte il file relativo allo stato della batteria; il mio state file e':
Code:

[stekkino:~] > cat /proc/acpi/battery/BAT0/state
present:                 yes
capacity state:          ok
charging state:          charging
present rate:            29 mA
remaining capacity:      4030 mAh
present voltage:         16848 mV


il quale poi e' uno dei settaggi di default dello script associato alla variabile $state_file.
Se il vostro file sta in una posizione diversa basta modificare il valore di tale variabile nello script.

Nota:
se fate un cat del vostro state file come root dovreste vedere qualcosa di molto simile al mio output.
Questo e' molto importante perche' lo script si basa sul riconoscimento delle due righe che iniziano con ``charging state:'' e ``remaining capacity:''

Lo script non fa altro che aprire lo state file e cercare la riga che comincia con ``charging state:'', a questo punto capisce se l'alimentazione dalla rete e' presente o meno: se e' presente (``charging'') allora il check successivo lo fa dopo un minuto, se non e' presente (``discharging'') allora prosegue ricavando sempre dallo stesso file l'informazine relativa ai MilliApereOra che rimangono (riga ``remaining capacity: ??? mAh'').
Se tale valore e' maggiore della soglia di default pari a 400 (variabile $capacity_warning) allora ripete tutto dall'inizio dopo 15 secondi altrimenti manda un messaggio sul log file /var/log/messages tramite il programma ``logger'' e quindi spegne il pc tramite il comando ``poweroff''.

I due tempi di attesa come il valore di soglia di carica bassa ed i due programmi usati per mandare un log sul file messages e spegnere il pc sono modificabili a piacimento.

Dimenticavo.... chiaramente Perl deve essere presente nel vostro sistema.

Come vedete la soluzione non ha nessuna pretesa di complessita'e miglioramenti sono ben accetti.

Vorrei comunque risolvere ancora i miei dubbi evidenziati nei post indicati all'inizio di tale topic.

PS al commento "DECISIONE UN PO DRASTICA":
questa riga di codice e' un po' pericolosa perche' se per qualche ultra strano motivo con alimentazione di rete inserita si presenta
questo evento in modo stabile... il vostro/mio laptop appeno acceso si spegnera' di conseguenza ancora prima che abbiate il tempo di loggarvi e sistemare la faccenda.
In questo maleaugurato caso bisognerebbe:

    1 - o entrare con un runlevel che non attivi il servizio di check della batteria ovvero che non esegua il file /etc/init.d/local.start
    2 - o avviare il laptop con un CD autoavviante e disabilitare lo scrip di check
    3 - o modificare quella "DECISIONE UN PO DRASTICA" fin d'ora :wink:

Nel caso 3 si potrebbero cosi commentare le ultime due righe di codice come segue:
Code:

...
  } else {
  system("$logger".'battery state not defined');
# system("$shutdown");  # --- DECISIONE UN PO DRASTICA ORA DEL TUTTO INNOQUA --- #
# last;
  sleep(30);
  }
}

In questo caso vera' eseguito solo il "logger" per la notifica dell'evento ultrastrano oltre ad bel sleep di 30 secondi per non entrare in un loop mostruoso che ciuccerebbe tutta la vostra CPU (oltre a riempirvi il file di log!!!! e quindi l'HD alla velocita' del loop!!!!) nel caso in cui l'evento ultrastrano diventasse permanente.


Last edited by quantumwire on Mon Dec 12, 2005 12:09 pm; edited 15 times in total
Back to top
View user's profile Send private message
SilveRo
Tux's lil' helper
Tux's lil' helper


Joined: 13 Oct 2003
Posts: 147
Location: Milan (Italy)

PostPosted: Sun Jul 18, 2004 2:41 pm    Post subject: Re: [HOWTO] Come spegnere il tuo laptop se la batteria e' fi Reply with quote

Complimenti per il tuo script, mi e' stato molto utile. =)

Lo sto usando pure io, ma prima ho dovuto fare delle modifiche, perche':

1) la mia batteria quando e' carica come stato mi dice unknown.

2) la capacita' della mia batteria e' espressa in mWh.

Ecco le modifiche che ho fatto in get_remaining_capacity:

Code:

    if ($row =~ m/^remaining\s+capacity:\s+(\d+)\s+mWh$/) {


ed ecco il mio main:

Code:

while (1) {
  $state = &get_charging_state($state_file);

  if ($state eq 'discharging') {
    $capacity = &get_remaining_capacity($state_file);
    system("$logger"."battery discharging: capacity ``$capacity'' mWh");

    if ($capacity <= $capacity_warning) {
      system("$logger"."battery discharging: capacity too much low");
      system("$shutdown");
      last;
    } else {
      sleep(15);
    }
  } else {
      sleep(60);
  }
}


Se qualcuno vuole usare le mie modifiche, si ricordi di cambiare $capacity_warning, e impostarlo al (per esempio) 4% della capacita' in mWh.
Inoltre, come comando di shutdown ho preferito mettere "shutdown -h now".

=)
_________________
Think Gray
(things aren't all black or all white)
Back to top
View user's profile Send private message
federico
Advocate
Advocate


Joined: 18 Feb 2003
Posts: 3272
Location: Italy, Milano

PostPosted: Sun Jul 18, 2004 4:36 pm    Post subject: Reply with quote

Su Sideralis da mesi erano presenti programmi destinati a tale scopo... (eventualmente utilizzabili anche tramite interfaccia grafica!)

http://www.sideralis.net

Federico
_________________
Sideralis www.sideralis.org
Pic http://blackman.amicofigo.com/gallery
Arduino http://www.arduino.cc
Chi aveva potuto aveva spaccato
2000 pezzi buttati là
Molti saluti,qualche domanda
Semplice come musica punk
Back to top
View user's profile Send private message
fedeliallalinea
Administrator
Administrator


Joined: 08 Mar 2003
Posts: 31270
Location: here

PostPosted: Sun Jul 18, 2004 4:39 pm    Post subject: Reply with quote

Aggiunto nei post utilissimi
_________________
Questions are guaranteed in life; Answers aren't.
Back to top
View user's profile Send private message
Cagnulein
l33t
l33t


Joined: 18 Sep 2003
Posts: 861
Location: Modena, Italy

PostPosted: Sun Jul 18, 2004 6:06 pm    Post subject: Reply with quote

verramente ottimo lo stile di commento che hai addottato per le funzioni, penso che lo utilizzerò anche io magari usando un template :)
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Sun Jul 18, 2004 6:25 pm    Post subject: Reply with quote

federico wrote:
Su Sideralis da mesi erano presenti programmi destinati a tale scopo... (eventualmente utilizzabili anche tramite interfaccia grafica!)
Federico


Buono a sapersi... appena ho un po' di tempo spulcio il sito.

fedeliallalinea wrote:

Aggiunto nei post utilissimi


Grazie ragazzi... mi sento emozionato a palla... e' un piacere sapere che puo' servire.

Thanks.
_________________
HOWTO 1: Spegnere il laptop!
HOWTO 2: Comprimere i DVDs!


Last edited by quantumwire on Sun Jul 18, 2004 8:36 pm; edited 1 time in total
Back to top
View user's profile Send private message
SilveRo
Tux's lil' helper
Tux's lil' helper


Joined: 13 Oct 2003
Posts: 147
Location: Milan (Italy)

PostPosted: Sun Jul 18, 2004 7:31 pm    Post subject: Reply with quote

Mi sembrava strano che in due mesi nessuno avesse risposto al tuo thread, considerato anche quanto e' utile il tuo script.... Ero certo che ti sarebbe piaciuto leggere qualche conferma che sia servito a qualcuno =P.

Se non lo hai gia' fatto, dovresti postarlo anche nella sezione Documentation, Tips and Tricks, in inglese, perche' ci sono tanti utenti di Gentoo che l'italiano non lo capiscono =)
_________________
Think Gray
(things aren't all black or all white)
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Sun Jul 18, 2004 7:59 pm    Post subject: Reply with quote

Grazie.

Ho appena modificato leggermente il codice e aggiunto un paio di note relative a possibili malfunzionamenti che possono derivare dall'uso dello stesso.

Ciao e grazie ancora.
_________________
HOWTO 1: Spegnere il laptop!
HOWTO 2: Comprimere i DVDs!
Back to top
View user's profile Send private message
SilveRo
Tux's lil' helper
Tux's lil' helper


Joined: 13 Oct 2003
Posts: 147
Location: Milan (Italy)

PostPosted: Sun Jul 18, 2004 8:36 pm    Post subject: Reply with quote

quantumwire wrote:
Grazie.

Ho appena modificato leggermente il codice e aggiunto un paio di note relative a possibili malfunzionamenti che possono derivare dall'uso dello stesso.

Ciao e grazie ancora.


ghehehe, makke' dici, grazie a TE che hai fatto sto script =)
_________________
Think Gray
(things aren't all black or all white)
Back to top
View user's profile Send private message
akiross
Veteran
Veteran


Joined: 02 Mar 2003
Posts: 1170
Location: Mostly on google.

PostPosted: Sat Aug 21, 2004 2:30 pm    Post subject: Reply with quote

Salve!
Bello lo script, peccato che non mi sia proprio utile...
Ovviamente ai mac non ci pensa nessuno... :D

Ecco, ho fatto giusto 2 righe di BASH, che restituiscono lo stato della batteria (AC se alimentato, un numero se a batteria).

Code:

#!/bin/bash

### SETTINGS ###
# Files Used
PWR_FILE='/proc/pmu/info'
BAT_FILE='/proc/pmu/battery_0'

### GETTING INFO ##

USING_AC_PWR=`grep 'AC Power' $PWR_FILE | tr -s ' ' | cut -d ' ' -f4`

if [[ $USING_AC_PWR = '1' ]]; then
   echo "AC"
   exit
fi

MAX_CHARGE=`grep '^max_charge' $BAT_FILE | tr -s ' ' | cut -d ' ' -f3`
ACT_CHARGE=`grep '^charge' $BAT_FILE | tr -s ' ' | cut -d ' ' -f3`

#   echo "Max charge: $MAX_CHARGE"
#   echo "Act charge: $ACT_CHARGE"

PERCENT_CHARGE=$(($ACT_CHARGE * 100 / $MAX_CHARGE))

#   echo "Actual charge: $PERCENT_CHARGE%"

echo $PERCENT_CHARGE


Potete integrarlo facilmente a questo script se avete un mac, anche se comunque (non per svalutare il lavoro del nostro quantumwire) esistono plugin per gkrellm per monitorare la batteria ed eventualmente eseguire un comando quando raggiunge un certo stato.

Ciauz
_________________
Libera scienza in libero stato.
Horizon of Events
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Fri Aug 27, 2004 4:08 pm    Post subject: Reply with quote

akiross wrote:
...anche se comunque esistono plugin per gkrellm per monitorare la batteria ed eventualmente eseguire un comando quando raggiunge un certo stato.


Credo gkrellm funzioni solo in presenza di X.
_________________
HOWTO 1: Spegnere il laptop!
HOWTO 2: Comprimere i DVDs!
Back to top
View user's profile Send private message
Cazzantonio
Bodhisattva
Bodhisattva


Joined: 20 Mar 2004
Posts: 4514
Location: Somewere around the world

PostPosted: Thu Nov 17, 2005 11:01 am    Post subject: Reply with quote

Visto che me lo sono ricordato posto le mie modifiche a questo script.
Nel mio caso la batteria, quando è carica, riporta lo stato "charged", pertanto lo script me lo identificava come "battery state not defined" ed entrava nel loop dei reboot... :roll:
ho aggiunto un paio di righe alla funzione main per ovviare al problema... ecco il mio main:
Code:
while (1) {
  $state_is = &get_charging_state($state_file);

  if ($state_is eq 'charging') {
    sleep($more);
  } elsif ($state_is eq 'charged') {
    sleep($more);
  } elsif ($state_is eq 'discharging') {
    $capacity_is = &get_remaining_capacity($state_file);
    system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");

    if ($capacity_is <= $capacity_warning) {
      system("$logger"."battery discharging: capacity too much low");
      system("$shutdown");
      last;
    } else {
      sleep($less);
    }
  } else {
    system("$logger".'battery state not defined');
#    system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#    last;
    sleep(30);
  }
}


Inoltre invece di mettere il servizio in local.start ho trovato più comodo creare uno script di init apposito. In questo modo ho creato un'altro runlevel (copia del mio di default tranne questo script) in modo da avviare questo nel caso volessi avviare il notebook ignorando il check della batteria.
Ecco lo script di init:
Code:
 #!/sbin/runscript

depend() {
        need localmount acpid logger
}

start() {
        ebegin "Starting checkbattery script"
        /scripts/sbin/checkbattery.pl & echo $! > /tmp/checkbattery.pid
        eend $? "Failed to start checkbattery script"
        [ `ps aux |grep checkbattery.pl|wc -l` -eq 1 ] && rm /tmp/checkbattery.pid       
}

stop() {
        ebegin "Stopping checkbattery script"
        if [ -f /tmp/checkbattery.pid ]; then
          kill -15 `cat /tmp/checkbattery.pid`
          rm /tmp/checkbattery.pid
        fi
}


[EDIT] aggiunta allo start una riga per il controllo del pid
_________________
Any mans death diminishes me, because I am involved in Mankinde; and therefore never send to know for whom the bell tolls; It tolls for thee.
-John Donne


Last edited by Cazzantonio on Sun Dec 11, 2005 6:37 pm; edited 1 time in total
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Thu Nov 17, 2005 12:26 pm    Post subject: Reply with quote

Cazzantonio wrote:
Visto che me lo sono ricordato posto le mie modifiche a questo script.


Hey dude! Belle modifiche!

Le apportero' anch'io super-presto allo script!
Back to top
View user's profile Send private message
.:deadhead:.
Advocate
Advocate


Joined: 25 Nov 2003
Posts: 2963
Location: Milano, Italy

PostPosted: Sun Nov 20, 2005 1:03 am    Post subject: Reply with quote

Mi raccomanda quantumwire, poi aggiorna anche questo 3d :-D
_________________
Proudly member of the Gentoo Documentation Project: the Italian Conspiracy ! ;)
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Sun Nov 20, 2005 1:16 am    Post subject: Reply with quote

.:deadhead:. wrote:
Mi raccomanda quantumwire, poi aggiorna anche questo 3d :-D


Cioe' il mio post in testa?
Back to top
View user's profile Send private message
Cazzantonio
Bodhisattva
Bodhisattva


Joined: 20 Mar 2004
Posts: 4514
Location: Somewere around the world

PostPosted: Sun Dec 11, 2005 12:49 am    Post subject: Reply with quote

Siccome non mi intendo di perl faccio questa domanda...
E' possibile aggiungere due righe per fare in modo che dorma (che so... 60 secondi) nel caso la riga "present" dia "no"? (ovvero la batteria è disinserita)
Le minuscole modifiche fatte prima le ho fatte ad occhio pur non conoscendo il perl... questa mi risulta più ostica...

Pensavo di bypassare tutto questo mettendo un ciclo nel bash script che lancia checkbattery... tuttavia risulta più elegante ed efficiente se tale funzione fosse integrata nello script :wink:
_________________
Any mans death diminishes me, because I am involved in Mankinde; and therefore never send to know for whom the bell tolls; It tolls for thee.
-John Donne
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Sun Dec 11, 2005 1:39 pm    Post subject: Reply with quote

Cazzantonio wrote:
E' possibile aggiungere due righe per fare in modo che dorma (che so... 60 secondi) nel caso la riga "present" dia "no"? (ovvero la batteria è disinserita)


Ottima domanda... supponendo che la batteria non sia un device hotplug (credo sia rischioso provare a toglierla o inserirla durante il normale funzionamento del laptop) ho fatto le seguenti modifiche:

1. prima di tutto introduciamo queste ulteriori subroutines:
Code:
############################################################################
#                                                                          #
# SUB: ABORT(ExitNumber)                                                   #
#                                                                          #
# DESCRIPTION: Exits script ubnormally.                                    #
#                                                                          #
# USAGE: &abort(ExitNumber)                                                #
#                                                                          #
# EXAMPLE: &abort(5);                                                      #
#                                                                          #
# EXTERNAL DATA USED: None                                                 #
#                                                                          #
############################################################################

sub abort {
  exit($_[0]);
}

############################################################################
#                                                                          #
# SUB: get_battery_presence                                                #
#                                                                          #
# DESCRIPTION: Gets battery presence state                                 #
#                                                                          #
# USAGE: &get_battery_presence(BatteryStateFile)                           #
#                                                                          #
# EXAMPLE: &get_battery_presence('/proc/acpi/battery/BAT0/state');         #
#                                                                          #
# EXTERNAL DATA USED: None                                                 #
#                                                                          #
############################################################################

sub get_battery_presence {
  my $read_state = 'no';

  if (open(STATEFILE, "<$_[0]")) {

    while (defined($row = <STATEFILE>)) {
      chomp($row);

      if ($row =~ m/^present:\s+([a-z]+)$/) {
        $read_state = $1;
        last;
      }
    }

    close(STATEFILE);
  }

  return $read_state;
}

2. nella parte dichiarativa aggiungiamo la variabile battery_presence:
Code:
############################################################################
#                                                                          #
# DECLARATIONS                                                             #
#                                                                          #
############################################################################

# SOME OF THE FLAGS BELOW WILL BE SET LATER ON BY THIS SCRIPT

my $pname            = 'checkbattery.pl';
my $state_file       = '/proc/acpi/battery/BAT0/state';
my $shutdown         = '/sbin/poweroff';
my $logger           = "/usr/bin/logger -t $pname ";
my $capacity_warning = 400;
my $more             = 60;   # seconds
my $less             = 15;   # seconds
my $capacity_is      = '';
my $state_is         = '';
my $battery_presence = '';

3. ed in fine modifichiamo il main come segue:
Code:

$battery_presence = &get_battery_presence($state_file);

if ($battery_presence eq 'yes') {
  while (1) {
    $state_is = &get_charging_state($state_file);

    if ($state_is eq 'charging') {
      sleep($more);
    } elsif ($state_is eq 'charged') {
      sleep($more);
    } elsif ($state_is eq 'discharging') {
      $capacity_is = &get_remaining_capacity($state_file);
      system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");

      if ($capacity_is <= $capacity_warning) {
        system("$logger"."battery discharging: capacity too much low");
        system("$shutdown");
        last;
      } else {
        sleep($less);
      }
    } else {
      system("$logger".'battery state not defined');
#      system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#      last;
      sleep(30);
    }
  }
} else {
  system("$logger"."battery not present: ``$pname'' unloaded.);
  &abort(1);
}


Che cosa fa di diverso checkbattery.pl con questo codice modificato?

Se il file /proc/acpi/battery/BAT0/state e' assente (acpi non presente nel kernel!) oppure e' presente ma il laptop e' sprovvisto della batteria allora checkbattery.pl si autokillera' ritornando come valore d'errore al tuo script di init il valore 1 (per intenderci: echo $? produrra' 1).

Quello che dovresti fare ora e' quindi modificare il tuo script di init in modo tale da gestire questa eventualita' ovvero... oltre a printare sullo schermo "Failed..." gli dovresti anche fare rimuovere il file temporaneo contenente il pid nella directory /tmp.

A proposito ho pero' un po di dubbi in quanto il $? che tu stai usando dovrebbe essere quello complessivo del comando /scripts/sbin/checkbattery.pl & echo $! > /tmp/checkbattery.pid il quale, per definizione, dovrebbe sempre essere eseguito correttamente indipendentemente dal valore eventualmente ritornato dal checkbattery.pl!!! Il tuo $? dovrebbe essere relativo alla domanda: "Sei riuscito a scrivere il pid del checkbattery.pl nel file temporaneo?... tant'e' vero che il checkbattery.pl deve essere lanciato in parallelo per fare in modo che il tuo script di init termini... come fare allora????

Si potrebbe fare in modo che... tu mi mandi in parallelo ma il controllo del "se c'e' la batteria" lo fai leggendo un file temporaneo che io ti scrivo nella directory tmp prima di autokillarmi... ma forse esiste qualcosa di piu' elegante... qualche idea???

NOTA: come si puo vedere dal codice, il controllo della presenza/assenza della batteria viene eseguito una sola volta ovvero in fase di avvio dello stesso script. Tale scelta corrisponde all'assunzione di una politica per la batteria del laptop di tipo non hotplug.


Last edited by quantumwire on Sun Dec 11, 2005 4:38 pm; edited 2 times in total
Back to top
View user's profile Send private message
Cazzantonio
Bodhisattva
Bodhisattva


Joined: 20 Mar 2004
Posts: 4514
Location: Somewere around the world

PostPosted: Sun Dec 11, 2005 4:32 pm    Post subject: Reply with quote

Per le batterie hotplug (devo dire che non ho mai sentito parlare di una batteria non hotplug...) potrebbe andare bene questo main?
Code:
while (1) {
  $state_is = &get_charging_state($state_file);
  $battery_presence = &get_battery_presence($state_file);
 
  if ($battery_presence eq 'yes') {
    if ($state_is eq 'charging') {
    sleep($more);
    } elsif ($state_is eq 'charged') {
    sleep($more);
    } elsif ($state_is eq 'discharging') {
      $capacity_is = &get_remaining_capacity($state_file);
      system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");
       if ($capacity_is <= $capacity_warning) {
        system("$logger"."battery discharging: capacity too much low");
        system("$shutdown");
        last;
      } else {
        sleep($less);
      }
    } else {
      system("$logger".'battery state not defined');
#      system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#      last;
      sleep(30);
    }
  } else {
    system("$logger"."battery not present");
    sleep(60);
  }
}

Attendo conferma visto che ti ripeto che non conosco il perl e vado un po' ad occhio :wink:
In questo caso non dovrebbe essere nemmeno necessaria la funzione "abort" e si risolve anche il problema del pid! :wink: (visto che il programma non viene più abortito...

Per la soluzione non hotplug (anche se ti ripeto che mi pare così improbabile.... hai un portatile con la batteria non hotplug per caso?) si potrebbe fare un controllo accessorio (tipo "ps aux |grep checkbattery.pl") per vedere se è effettivamente attivo e cancellare il pid in caso contrario...
Ovvero cambiare lo start dello script di init in qualcosa di simile:
Code:
start() {
        ebegin "Starting checkbattery script"
        /scripts/sbin/checkbattery.pl & echo $! > /tmp/checkbattery.pid
        eend $? "Failed to start checkbattery script"
        [ `ps aux |grep checkbattery.pl|wc -l` -eq 1 ] && rm /tmp/checkbattery.pid
}

_________________
Any mans death diminishes me, because I am involved in Mankinde; and therefore never send to know for whom the bell tolls; It tolls for thee.
-John Donne


Last edited by Cazzantonio on Sun Dec 11, 2005 6:36 pm; edited 1 time in total
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Sun Dec 11, 2005 4:55 pm    Post subject: Reply with quote

Cazzantonio wrote:
Code:
while (1) {
  $state_is = &get_charging_state($state_file);
  $battery_presence = &get_battery_presence($state_file);
 
  if ($battery_presence eq 'yes') {
    if ($state_is eq 'charging') {
    sleep($more);
    } elsif ($state_is eq 'charged') {
    sleep($more);
    } elsif ($state_is eq 'discharging') {
      $capacity_is = &get_remaining_capacity($state_file);
      system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");
       if ($capacity_is <= $capacity_warning) {
        system("$logger"."battery discharging: capacity too much low");
        system("$shutdown");
        last;
      } else {
        sleep($less);
      }
    } else {
      system("$logger".'battery state not defined');
#      system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#      last;
      sleep(30);
    }
  } else {
    system("$logger"."battery not present");
    sleep(60);
  }
}


E' giusto... ma io lo modificherei cosi:
Code:
while (1) {
  $battery_presence = &get_battery_presence($state_file);

  if ($battery_presence eq 'yes') {
    $state_is = &get_charging_state($state_file);

    if ($state_is eq 'charging' || $state_is eq 'charged') {
      sleep($more);
    } elsif ($state_is eq 'discharging') {
      $capacity_is = &get_remaining_capacity($state_file);
      system("$logger"."battery discharging: capacity ``$capacity_is'' mAh");

      if ($capacity_is <= $capacity_warning) {
        system("$logger"."battery discharging: capacity too much low");
        system("$shutdown");
        last;
      } else {
        sleep($less);
      }
    } else {
      system("$logger".'battery state not defined');
#      system("$shutdown");  # --- DECISIONE UN PO DRASTICA --- #
#      last;
      sleep($less);
    }
  } else {
    system("$logger".'battery not present');
    sleep($more);
  }
}


Per quanto riguarda il tuo init script... perfetta l'aggiunta! Io la lascerei che male non fa!

/EDIT
Forse invece c'e' un problemino... e se capitasse che mi autokillo dopo che tu hai fatto il controllo del pid (checkbattery.pl un po' lento nell'aprire i files etc....)???

PS: Non ho mai provato a rimuovere la batteria del mio laptop mantre sta funzionando... a parte che dovrei quasi smontarlo per toglierla comunque se dici che la tua e' hotplug, lo script cosi' modificato dovrebbe anfare.

Fammi sapere se funziona... in tal caso modifichero' anche quello in testa riportando tutte le modifiche introdotte.
Back to top
View user's profile Send private message
Cazzantonio
Bodhisattva
Bodhisattva


Joined: 20 Mar 2004
Posts: 4514
Location: Somewere around the world

PostPosted: Sun Dec 11, 2005 6:33 pm    Post subject: Reply with quote

Si la tua versione è decisamente più carina :wink:

A me lo script funziona egregiamente... del resto la batteria la tolgo e la metto a seconda delle esigente (di solito se attacco la spina stacco la batteria, almeno che non voglia ricaricarla). Prima mi si riempivano i log di "battery state not defined" etc... ora posso eliminare il logging (commentando la riga) quando ho la spina attaccata ;-)

Il tuo dubbio sul controllo per il pid non so quanto possa essere fondato... in fondo non cambia niente che rimanga il file del pid in /tmp o meno mi pare... e poi penso che ps aux ti dica in tempo reale i programmi che girano... se checkbattery è partito nella linea precedente dello script dovrebbe bastare...

P.S. peccato che avevo postato la riga dello script di init senza mettere il pezzo più importante... :roll:
L'ho corretta e ora funziona :wink:
_________________
Any mans death diminishes me, because I am involved in Mankinde; and therefore never send to know for whom the bell tolls; It tolls for thee.
-John Donne
Back to top
View user's profile Send private message
Dr.Dran
l33t
l33t


Joined: 08 Oct 2004
Posts: 766
Location: Imola - Italy

PostPosted: Fri Dec 30, 2005 11:56 am    Post subject: Reply with quote

Scusa se mi intrometto, ma mi chiedevo se avevi provato anche il pacchetto laptop-mode-tools; mi interessa anche perchè mi deve arrivare un nuovo portatilino tutto fiammante ex-novo e mi piacerebbe partizionarlo con xfs e fare delle prove... magari lo si può integrare con questo utile script.

Comunque complimenti un bel lavoro :D
_________________
:: [Dr.Dran] Details ::
- Linux User # 286282
- IT FreeLance Consultant
- President of ImoLUG [Imola & Faenza Linux User Group]
Back to top
View user's profile Send private message
quantumwire
Guru
Guru


Joined: 15 Oct 2003
Posts: 403
Location: Lausanne

PostPosted: Tue Jan 03, 2006 1:55 pm    Post subject: Reply with quote

DranXXX wrote:
Scusa se mi intrometto, ma mi chiedevo se avevi provato anche il pacchetto laptop-mode-tools; mi interessa anche perchè mi deve arrivare un nuovo portatilino tutto fiammante ex-novo e mi piacerebbe partizionarlo con xfs e fare delle prove... magari lo si può integrare con questo utile script.

Comunque complimenti un bel lavoro :D


Quel pacchetto non l'ho mai utilizzato sul mio laptop... provero' a dargli un'occhiata e ti faccio sapere.
Back to top
View user's profile Send private message
codadilupo
Advocate
Advocate


Joined: 05 Aug 2003
Posts: 3135

PostPosted: Tue Jan 03, 2006 2:36 pm    Post subject: Reply with quote

DranXXX wrote:
Scusa se mi intrometto, ma mi chiedevo se avevi provato anche il pacchetto laptop-mode-tools; mi interessa anche perchè mi deve arrivare un nuovo portatilino tutto fiammante ex-novo e mi piacerebbe partizionarlo con xfs e fare delle prove... magari lo si può integrare con questo utile script.

Comunque complimenti un bel lavoro :D


ah, quindi é andata bene ;-)

Coda
Back to top
View user's profile Send private message
Dr.Dran
l33t
l33t


Joined: 08 Oct 2004
Posts: 766
Location: Imola - Italy

PostPosted: Tue Jan 03, 2006 10:27 pm    Post subject: Reply with quote

@CodadiLupo
Si, oggi mi è arrivata l'e-mail per la conferma di tutto e mi chiedono addirittura una Foto e 2 righe per poi pubblicarle nella pagina per l'annucio della premiazione:
http://www.via.com.tw/en/products/notebook/winner_mascot_naming2.jsp

:D

@quantumwire
Grazie mille io per il momento non posso essere di aiuto fino a che non ho la materia prima :wink:
_________________
:: [Dr.Dran] Details ::
- Linux User # 286282
- IT FreeLance Consultant
- President of ImoLUG [Imola & Faenza Linux User Group]
Back to top
View user's profile Send private message
neryo
Veteran
Veteran


Joined: 09 Oct 2004
Posts: 1292
Location: Ferrara, Italy, Europe

PostPosted: Wed Jan 04, 2006 10:25 am    Post subject: Re: [HOWTO] Come spegnere il tuo laptop se la batteria e' fi Reply with quote

quantumwire wrote:

Il problema e' quello di voler spegnere il mio laptop quando, in presenza di una prolungata assenza di alimentazione di rete, anche la batteria arriva verso la fine.


fichissimo! complimenti.. :wink:
_________________
cache: a safe place for hiding or storing things..

D-link DWL-G650 AirPlus
Apache Php Mysql
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Forum italiano (Italian) Risorse italiane (documentazione e tools) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum