Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index International Gentoo Users Forum italiano (Italian) Risorse italiane (documentazione e tools)
  • Search

[HOWTO] Come spegnere il tuo laptop se la batteria e' finita

Forum riservato alla documentazione in italiano.

Moderator: ago

Post Reply
  • Print view
Advanced search
32 posts
  • 1
  • 2
  • Next
Author
Message
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

[HOWTO] Come spegnere il tuo laptop se la batteria e' finita

  • Quote

Post by quantumwire » Wed May 26, 2004 8:04 pm

[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:

http://forums.gentoo.org/viewtopic.php? ... i+batteria
http://forums.gentoo.org/viewtopic.php? ... i+batteria
http://forums.gentoo.org/viewtopic.php? ... i+batteria

senza ottenere grande risultati comunque ecco lo script in Perl:

Code: Select all

#!/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: Select all

# cp ./checkbattery.pl /usr/local/bin
# chmod 744 /usr/local/bin/checkbattery.pl
e poi editare i seguenti file:

Code: Select all

# nano -w /etc/conf.d/local.start
aggiungendo la linea:

Code: Select all

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

Code: Select all

# nano -w /etc/conf.d/local.stop
aggiungendo la linea:

Code: Select all

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

Code: Select all

# /etc/init.d/local restart
Volendo e' possibile anche lanciarlo utilizzando il seguente script di init:

Code: Select all

#vim checkbattery

Code: Select all

#!/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: Select all

# 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: Select all

[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: Select all

...
  } 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.
Top
SilveRo
Tux's lil' helper
Tux's lil' helper
User avatar
Posts: 147
Joined: Mon Oct 13, 2003 9:22 pm
Location: Milan (Italy)
Contact:
Contact SilveRo
Website

Re: [HOWTO] Come spegnere il tuo laptop se la batteria e' fi

  • Quote

Post by SilveRo » Sun Jul 18, 2004 2:41 pm

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: Select all

    if ($row =~ m/^remaining\s+capacity:\s+(\d+)\s+mWh$/) {
ed ecco il mio main:

Code: Select all

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)
Top
federico
Advocate
Advocate
User avatar
Posts: 3272
Joined: Tue Feb 18, 2003 2:08 pm
Location: Italy, Milano
Contact:
Contact federico
Website

  • Quote

Post by federico » Sun Jul 18, 2004 4:36 pm

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
Top
fedeliallalinea
Administrator
Administrator
User avatar
Posts: 32019
Joined: Sat Mar 08, 2003 11:15 pm
Location: here
Contact:
Contact fedeliallalinea
Website

  • Quote

Post by fedeliallalinea » Sun Jul 18, 2004 4:39 pm

Aggiunto nei post utilissimi
Questions are guaranteed in life; Answers aren't.

"Those who would give up essential liberty to purchase a little temporary safety,
deserve neither liberty nor safety."
- Ben Franklin
https://www.news.admin.ch/it/nsb?id=103968
Top
Cagnulein
l33t
l33t
User avatar
Posts: 861
Joined: Thu Sep 18, 2003 3:39 pm
Location: Modena, Italy

  • Quote

Post by Cagnulein » Sun Jul 18, 2004 6:06 pm

verramente ottimo lo stile di commento che hai addottato per le funzioni, penso che lo utilizzerò anche io magari usando un template :)
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Sun Jul 18, 2004 6:25 pm

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.
Last edited by quantumwire on Sun Jul 18, 2004 8:36 pm, edited 1 time in total.
HOWTO 1: Spegnere il laptop!
HOWTO 2: Comprimere i DVDs!
Top
SilveRo
Tux's lil' helper
Tux's lil' helper
User avatar
Posts: 147
Joined: Mon Oct 13, 2003 9:22 pm
Location: Milan (Italy)
Contact:
Contact SilveRo
Website

  • Quote

Post by SilveRo » Sun Jul 18, 2004 7:31 pm

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)
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Sun Jul 18, 2004 7:59 pm

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!
Top
SilveRo
Tux's lil' helper
Tux's lil' helper
User avatar
Posts: 147
Joined: Mon Oct 13, 2003 9:22 pm
Location: Milan (Italy)
Contact:
Contact SilveRo
Website

  • Quote

Post by SilveRo » Sun Jul 18, 2004 8:36 pm

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)
Top
akiross
Veteran
Veteran
User avatar
Posts: 1170
Joined: Sun Mar 02, 2003 12:34 am
Location: Mostly on google.
Contact:
Contact akiross
Website

  • Quote

Post by akiross » Sat Aug 21, 2004 2:30 pm

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: Select all

#!/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
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Fri Aug 27, 2004 4:08 pm

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!
Top
Cazzantonio
Bodhisattva
Bodhisattva
User avatar
Posts: 4514
Joined: Sat Mar 20, 2004 8:57 pm
Location: Somewere around the world

  • Quote

Post by Cazzantonio » Thu Nov 17, 2005 11:01 am

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: Select all

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: Select all

 #!/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
Last edited by Cazzantonio on Sun Dec 11, 2005 6:37 pm, edited 1 time in total.
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
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Thu Nov 17, 2005 12:26 pm

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!
Top
.:deadhead:.
Advocate
Advocate
User avatar
Posts: 2963
Joined: Tue Nov 25, 2003 5:17 pm
Location: Milano, Italy

  • Quote

Post by .:deadhead:. » Sun Nov 20, 2005 1:03 am

Mi raccomanda quantumwire, poi aggiorna anche questo 3d :-D
Proudly member of the Gentoo Documentation Project: the Italian Conspiracy ! ;)
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Sun Nov 20, 2005 1:16 am

.:deadhead:. wrote:Mi raccomanda quantumwire, poi aggiorna anche questo 3d :-D
Cioe' il mio post in testa?
Top
Cazzantonio
Bodhisattva
Bodhisattva
User avatar
Posts: 4514
Joined: Sat Mar 20, 2004 8:57 pm
Location: Somewere around the world

  • Quote

Post by Cazzantonio » Sun Dec 11, 2005 12:49 am

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
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Sun Dec 11, 2005 1:39 pm

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: Select all

############################################################################
#                                                                          #
# 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: Select all

############################################################################
#                                                                          #
# 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: Select all

$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.
Top
Cazzantonio
Bodhisattva
Bodhisattva
User avatar
Posts: 4514
Joined: Sat Mar 20, 2004 8:57 pm
Location: Somewere around the world

  • Quote

Post by Cazzantonio » Sun Dec 11, 2005 4:32 pm

Per le batterie hotplug (devo dire che non ho mai sentito parlare di una batteria non hotplug...) potrebbe andare bene questo main?

Code: Select all

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: Select all

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
}
Last edited by Cazzantonio on Sun Dec 11, 2005 6:36 pm, edited 1 time in total.
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
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Sun Dec 11, 2005 4:55 pm

Cazzantonio wrote:

Code: Select all

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: Select all

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.
Top
Cazzantonio
Bodhisattva
Bodhisattva
User avatar
Posts: 4514
Joined: Sat Mar 20, 2004 8:57 pm
Location: Somewere around the world

  • Quote

Post by Cazzantonio » Sun Dec 11, 2005 6:33 pm

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
Top
Dr.Dran
l33t
l33t
User avatar
Posts: 766
Joined: Fri Oct 08, 2004 5:21 pm
Location: Imola - Italy
Contact:
Contact Dr.Dran
Website

  • Quote

Post by Dr.Dran » Fri Dec 30, 2005 11:56 am

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]
Top
quantumwire
Guru
Guru
User avatar
Posts: 403
Joined: Wed Oct 15, 2003 9:17 pm
Location: Lausanne

  • Quote

Post by quantumwire » Tue Jan 03, 2006 1:55 pm

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.
Top
codadilupo
Advocate
Advocate
Posts: 3135
Joined: Tue Aug 05, 2003 8:48 am

  • Quote

Post by codadilupo » Tue Jan 03, 2006 2:36 pm

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
Top
Dr.Dran
l33t
l33t
User avatar
Posts: 766
Joined: Fri Oct 08, 2004 5:21 pm
Location: Imola - Italy
Contact:
Contact Dr.Dran
Website

  • Quote

Post by Dr.Dran » Tue Jan 03, 2006 10:27 pm

@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/noteb ... aming2.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]
Top
neryo
Veteran
Veteran
User avatar
Posts: 1292
Joined: Sat Oct 09, 2004 2:54 pm
Location: Ferrara, Italy, Europe
Contact:
Contact neryo
Website

Re: [HOWTO] Come spegnere il tuo laptop se la batteria e' fi

  • Quote

Post by neryo » Wed Jan 04, 2006 10:25 am

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
Top
Post Reply
  • Print view

32 posts
  • 1
  • 2
  • Next

Return to “Risorse italiane (documentazione e tools)”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Authors
Gentoo is a trademark of the Gentoo Foundation, Inc. and of Förderverein Gentoo e.V.
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-4.0 license.
The Gentoo Name and Logo Usage Guidelines apply.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy