Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/03/2013, à 14:38

arthropode

Déclencher un script à partir d'un certain niveau de la batterie.

Bonjour,

J'aimerai savoir s'il y a un moyen 'simple' de déclencher un script ou une commande à partir d'un certain  niveau de charge.

Par exemple, que si la batterie ne contient plus que 10% de charge, appeler un script qui me sauvegarde ma session, si elle n'est plus qu'à 5%, mettre l'ordi en veille, etc.

Auriez-vous des idées ?

Merci.

Hors ligne

#2 Le 29/03/2013, à 15:30

ljere

Re : Déclencher un script à partir d'un certain niveau de la batterie.

xfce-power-manager doit pouvoir faire ça


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#3 Le 29/03/2013, à 15:46

tiramiseb

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Salut,

Les gestionnaires d'énergie des différents environnements font déjà ça.

Mais, oui, c'est possible.
Par contre je ne saurais plus te dire comment, ça fait longtemps que je ne l'ai pas fait (en fait... ça date d'avant que les environnements de bureau gèrent ça correctement...).

Hors ligne

#4 Le 29/03/2013, à 15:52

ljere

Re : Déclencher un script à partir d'un certain niveau de la batterie.

oui avant il y avait ce genre de commande qui aurait pu être utile

cat /proc/acpi/battery/*/state

mais visiblement le dossier battery n'existe plus sur ma session sinon il y a la possibilité d'installer acpi
puis lance

acpi -V | grep Battery

c'est déjà un bon départ pour ton script


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#5 Le 29/03/2013, à 19:08

arthropode

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Le problème des utilitaires des gestionnaires de bureaux, c'est que comme j'utilise Openbox, je ne peux pas les utiliser.

Sinon, pour faire un script qui utilise acpi et en extrait l'état de la batterie, puis effectue différentes actions, je suppose qu'il faut le mettre dans ma crontab pour qu'il soit lancé toutes les minutes. Mais ça ne risque pas d'être un peu demandeur en ressources ?

Hors ligne

#6 Le 03/04/2013, à 12:48

nesthib

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Lancer une commande sur l'état de la batterie toutes les minutes ne devrait pas trop poser de problème smile


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#7 Le 03/04/2013, à 12:56

tiramiseb

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Mais ça ne risque pas d'être un peu demandeur en ressources ?

Si ton script est léger, non pas vraiment.
Allez, ça va utiliser 1% de ton processeur pendant une seconde toutes les minutes, peut-être... Je doute qu'il y ait un impact visible.

Hors ligne

#8 Le 03/04/2013, à 17:17

ljere

Re : Déclencher un script à partir d'un certain niveau de la batterie.

je pense même que tu peux lancer ce script toute les 5 mn


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#9 Le 03/04/2013, à 17:36

Didier-T

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Bonjour arthropode,

tu peut utiliser conky, après tout on est pas forcé d'afficher quoi que ce soit, et sa permet de voir l’état de ta batterie toutes les x seconde et d’exécuter un script si une condition est atteinte.
en plus il me semble que c'est disponible sous toutes les distributions. cool

Hors ligne

#10 Le 03/04/2013, à 18:56

Josepe36

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Bonsoir

comme nous sommes dans la partie scripts et commande je pense que @arthropode a plus besoin d'un script voir exemple.

voici ce que je peux te proposer, je te l'ai fait version thread des fois que tu veuilles y rajouter d'autres actions à la suite, et de plus il est dérivé du second script que je vais poster qui permet d'analyser la charge d'un processus.

Ce script s'utilise avec un parametre, le délais entre chaque control, tu verras que c'est en fin de compte peu gourmand en ressources.
exenple:
nom_du_script.py -d 5
soit 5 secondes

le script ne faira qu'afficher des détail concernat la batterie, à toi d'apter pour éfféctuer un ou des action a partir d'un certain seuil.
Donc voici le script, bien entendu tu copie le contenu dans un fichier du style look_batt.py:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Josepe36 03 avril 2013

import os
import sys
import time
import threading

class BatterySurveil(threading.Thread):
    '''
       look at battery state
    '''
    def __init__(self, delay):
        threading.Thread.__init__(self)
        self.running = False
        self.delay = float(delay)

    def run(self):       
        use_file = ('info', 'state')
        bat_dir = '/proc/acpi/battery/'
        bat_rep = os.listdir(bat_dir)
        bat_files = {bat:{_file:elem for elem in os.listdir(bat_dir+bat)\
                            for _file in use_file if elem == _file \
                          }\
                            for bat in bat_rep
                    }
        self.running = True
        while self.running == True:
            #Get battery state, it may have more than one battery
            for batterie in bat_files:
                info_file = open(bat_dir+batterie+'/'+bat_files[batterie]['info'],'r')
                bat_capacity = info_file.readlines()[1].split(' ')[-2]
                info_file.close()
                state_file = open(bat_dir+batterie+'/'+bat_files[batterie]['state'],'r')
                bat_current_capacity = state_file.readlines()[-2].split(' ')[-2]
                state_file.close()
                current_percentage = float(bat_current_capacity) / float(bat_capacity) * 100
                #print result in terminal on the same line
                chaine = ("Batterie capacity :"+str(bat_capacity)+
                          "ma/h -- Actual capacity :"+bat_current_capacity+
                          "ma/h %.2f" % current_percentage +" %")
                sys.stdout.write("\r"+chaine)
                sys.stdout.flush()
            time.sleep(delay)

if __name__ == "__main__":
    #Get parameters
    if len(sys.argv) > 1:
        param = u"%s" % sys.argv[1]
        #If --help is call
        if param == "--help":
            print """
    This script look at battery state in real time.
    It must be call with a delay argument.
    Use :
    script.py -d<second>.
    or without parameter, default delay will be set to 1 second.
    """
            sys.exit()

    #In the case where -d argument exist
    if len(sys.argv) == 3:
        if sys.argv[1][0:2] == "-d":
            try:
                delay = float(sys.argv[2][0:])
                print "delay set to ",delay
                #Control if parameter delay is really numeric
                delay = float(delay)
            except:
                #if -d is not float do not crash
                print sys.argv
                print "Bad parameter here",sys.argv[2]," delay set to 1"
                delay = 1
                
        else:
            #if parameter different of -d do not crash
            print "Bad parameter ",sys.argv[2]," delay set to 1"
            delay = 1
            
    else:
        print "No delay parameter, delay set to 1 second"
        delay = 1

    #Start the thread to look at battery
    current_thread = BatterySurveil(delay)
    current_thread.start()

une fois ce script lançé tu peux surveiller sa consommation cpu et mémoire avec celui ci:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Josepe36 30 mars 2013

import os
import sys
import time
import signal
import gobject
import threading

class SysInfos(threading.Thread):
    '''Return informations about a process pid pass on argument:
        -cpu usage for the pid
        -memorie usage for the pid
        -the thread return a dic with cpu history and memorie history
    '''
    def __init__(self, process, interval):
        threading.Thread.__init__(self)
        self.running = False
        self.my_process = process
        self.interval = float(interval)
        self.total_mem = int(psutil.TOTAL_PHYMEM/1048576)
        self.cpu_list = []
        self.mem_list = []
        signal.signal(signal.SIGINT, self.signal_handler)

    def stop(self):
        self.stop_event.set()
        self.running = False
        #Just say good by
        print "End of thread ."
        #Return the dic for apply calculations
        return {"cpu_history": self.cpu_list,
                "memory_history": self.mem_list,
                "duration": self.duration,
                "start_time": self.start_time}


    def signal_handler(self, signal, frame):
        print '\nYou pressed Ctrl+C!'
        self.stop()

    def run(self):
        """Start the thread."""
        self.running = True
        print "thread is running now..."
        self.stop_event = threading.Event()
        self.duration = 0
        self.start_time = time.strftime('%H:%M:%S')
        print "start at : ", self.start_time
        print "process  : ", self.my_process
        while not self.stop_event.isSet() and self.running == True:
            #If process is stop out of the script we stop
            #status 5 is not running status
            if self.my_process.status == 5:
                print self.my_process.status
                self.stop()

            try:
                #Get cpu percentage, may have two arguments(see the doc)
                cpu_charge = self.my_process.get_cpu_percent(interval=self.interval)
                #Get memory percentage
                memorie_use = self.my_process.get_memory_percent()
                #print result in terminal on the same line
                chaine = ("cpu_charge "+str(cpu_charge)+
                          " % memory_use "+"%.2f" % memorie_use+"% "+
                          "%.2f" % float(self.total_mem/100*memorie_use)+" mo")
                sys.stdout.write("\r"+chaine)
                sys.stdout.flush()
                #Construct lists
                self.cpu_list.append(cpu_charge)
                self.mem_list.append(memorie_use)
                #Totalisation to have the duration, may be perfectionned i assume
                self.duration = self.duration + self.interval
            except:
                #If process is killed, thread is always running a small time
                #enough to generate some errors, because process does not exist
                #so exception nicely pass
                self.running = False

if __name__ == "__main__":
    #psutil module is perhaps absent
    try:
        import psutil
    except ImportError:
        print "You need to install python-psutil module."
        print "Try : apt-get install python-psutil"
        sys.exit()

    #Get parameters
    if len(sys.argv) > 1:
        param = u"%s" % sys.argv[1]
        #If --help is call
        if param == "--help":
            print """
    This script display informations about cpu and memory charge for a process.
    It must be call with a command or pid argument\n    and stop at the end of the process.
    Use :
    with command :     python process_listner.py <command> -d<seconds>
    with pid     :     python process_listner.py <pid> -d<seconds>
    parameter -d<second> is optional, set to 1 second by default.
    parameter -d<second> is the interval between two calculation of cpu charge.
    Press Ctrl+C to stop the script."""
            sys.exit()

    #In the case where -d argument exist
    if len(sys.argv) == 3:
        if sys.argv[2][0:2] == "-d":
            try:
                interval = float(sys.argv[2][2:])
                print "Interval set to ",interval
                #Control if parameter interval is really numeric
                interval = float(interval)
            except:
                #if -d is not float do not crash
                print "Bad parameter ",sys.argv[2]," Interval set to 1"
                interval = 1
                
        else:
            #if parameter different of -d do not crash
            print "Bad parameter ",sys.argv[2]," Interval set to 1"
            interval = 1
            
    else:
        #Set by default interval to 1
        print "Interval set to 1"
        interval = 1

    if len(sys.argv) == 2 or len(sys.argv) == 3:
        if not param.isnumeric():
        #If this script is called with a command
            #Open command with psutil Popen
            try:
                launch_command = psutil.Popen(sys.argv[1])
                script_process = psutil.Process(int(launch_command.pid))
            except:
                print "Nothing to do with command", sys.argv[1]," does not exist."
                sys.exit()
        else:
        #or if this script is called with pid
            #Get the process instance with psutil
            try:
                script_process = psutil.Process(int(sys.argv[1]))
            except:
                print "Nothing to do with process", sys.argv[1]," does not exist."
                sys.exit()

        name = script_process.name
        pid = script_process.pid
        #Start the thread to manage calculations
        current_thread = SysInfos(script_process, interval)
        current_thread.start()
        while not current_thread.isAlive():pass
        while current_thread.isAlive():pass

        #Stop the thread and get the dic
        results = current_thread.stop()
        moy_cpu_charge = float(sum(results["cpu_history"])/len(results["cpu_history"]))
        total_mem = int(psutil.TOTAL_PHYMEM/1048576)
        total_mem_use = float(sum(results["memory_history"])/len(results["memory_history"]))
        total_mem_use_percentage = float(total_mem/100*total_mem_use)
        #Just need to calculate and formate the results
        print "Stopping thread... "
        print "----------------------------------------------"
        print "Command                 :",name
        print "pid                     :",pid
        print "\ncpu charge              :", "%.2f" % moy_cpu_charge, '%'

        print "Total memory            :", total_mem, " mo"
        print "memorie use             :", "%.2f" % total_mem_use, '%', "%.2f" % total_mem_use_percentage, 'mo'
        print "\nInterval assigned at    :",interval, "seconds"
        print "Begin at                :", results["start_time"]
        print "Stopping at             :", time.strftime('%H:%M:%S')
        print "duration                :",results["duration"], " seconds"
        print "----------------------------------------------"
        sys.exit()
    else:
        #If no argument passed quit properly
        print "You need to pass an argument ."
        sys.exit()

pour info sur les scripts, tu peux taper :
le_nom_du_script.py --help

Dernière modification par Josepe36 (Le 03/04/2013, à 21:05)


Développeur distribution Hybryde
www.hybryde.org

Hors ligne

#11 Le 03/04/2013, à 19:04

Josepe36

Re : Déclencher un script à partir d'un certain niveau de la batterie.

voilà pour info le résultat du second script en surveillance du premier:

Command                 : python
pid                     : 8276

cpu charge              : 0.14 %
Total memory            : 2990  mo
memorie use             : 0.14 % 4.07 mo

Interval assigned at    : 1 seconds
Begin at                : 20:03:07
Stopping at             : 20:03:35
duration                : 28.0  seconds

autant dire que ça consomme pas grand chose smile

Dernière modification par Josepe36 (Le 03/04/2013, à 19:05)


Développeur distribution Hybryde
www.hybryde.org

Hors ligne

#12 Le 04/04/2013, à 18:22

arthropode

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Merci beaucoup pour toutes ces réponses.

@Didier_T
Je vais en effet voir avec conky. Comme je suis en pleine phase de configuration de mon ordi, j'étais justement là dedans. Merci pour l'idée.

@ Josepe
Merci beaucoup pour ces scripts. Je vais m'y plonger. Bon, et en effet, la charge mémoire est plutôt réduite. Mais vu les caractéristiques de mon ordinateur, je me méfie.

Merci encore.

Hors ligne

#13 Le 05/04/2013, à 07:19

Josepe36

Re : Déclencher un script à partir d'un certain niveau de la batterie.

Avec plaisir wink


Développeur distribution Hybryde
www.hybryde.org

Hors ligne