8
votes

Comment puis-je attraper un événement de suspension système en Python?

J'utilise Ubuntu 12.04. Y a-t-il un moyen d'attraper un événement suspendu à Python, c'est-à-dire si l'ordinateur portable va suspendre, faites-le ...? La même question pour attraper l'événement d'arrêt.


3 commentaires

Cela traite de l'événement de déconnexion accrocheur. Mais peut vous aider: Stackoverflow.com/Questtions/2490166/...


merci ... je vais regarder dans gnome.ui


J'aurais SystemD Ecrire un fichier sur / TMP pendant la suspension et un fichier différent pendant la reprise que mon programme interrogerait tous les 3 à 5 décisecondes. En outre, si mon programme a accédé à Internet, je aurais du gestionnaire de réseau créer un fichier pendant la suspension et la reprise que mon programme sonderait mon programme. dbus est "compliqué" .


3 Réponses :


5
votes

Je pense que la méthode la plus simple serait d'utiliser DBus Python interface et écoutez «Abouttosleep» et / ou «Dormeur» sur l'interface 'org.freedesktop.uppower'


2 commentaires

ne peut pas le trouver aussi, cela était manipulé par une halte, mais il est obsolète maintenant


J'ai placé un script shell dans /etc/init.d/ et définissez-le pour exécuter pendant l'arrêt. Le script fait le travail que je voulais faire à Python. J'aurais aimé tous les événements traités dans un seul programme Python, mais je me contenterai d'utiliser différents scripts.



3
votes

Vous pouvez étendre ce code, il écoute des événements d'ACPID, essayez d'imprimer la chaîne qu'il reçoit et de générer l'événement que vous souhaitez et de voir quelle ressemble à la chaîne.

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/var/run/acpid.socket")
print "Connected to acpid"
while 1:
    for event in s.recv(4096).split('\n'):
        event=event.split(' ')
        if len(event)<2: continue
        print event
        if event[0]=='ac_adapter':
            if event[3]=='00000001': #plugged
                plugged() #Power plugged event
            else: #unplugged
                unplugged() #Power unplugged event
        elif event[0]=='button/power':
            power_button() #Power button pressed
        elif event[0]=='button/lid':
            if event[2]=='open':
                lid_open() #Laptop lid opened
            elif event[2]=='close':
                lid_close() #Laptop lid closed


4 commentaires

Merci. C'est ce que je cherchais. BTW Où pouvez-vous obtenir une liste de ce que ces codes veulent dire? par exemple. 000000081?


HM Aucune idée honnêtement, j'ai obtenu ceux en générant les événements et voyez à quoi ressemblait la chaîne, vous pourriez essayer de voir dans la documentation d'ACPID, qui est le démon qui envoie ces chaînes.


cela est étrange. Il semble que je n'obtiens qu'un seul des signaux ouverts / fermés du couvercle après une suspension / reprise. ['processeur', 'cpu0', '00000081', '00000000'] ["bouton / couvercle", 'lid0', '00000080', '00000003'] ['processeur', 'cpu0 ',' 00000081 ',' 00000000 '] [' AC_ADAPTER ',' ADP0 ',' 00000080 ',' 00000000 '] [' BATTERY ',' BAT0 ',' 00000080 ',' 00000001 '] [' processeur ',' CPU0 ',' 00000081 ',' 00000000 ']


Peut-être que l'autre n'est pas généré comme événement ACPI, ou non sur votre ordinateur portable, ou si vous suspendez la fermeture du couvercle, lorsque vous ouvrez, il est toujours suspendu et que vous perdez l'événement.



5
votes

Si quelqu'un trébuche sur le même problème, voici le code:

#!/usr/bin/env python

import dbus      # for dbus communication (obviously)
import gobject   # main loop
from dbus.mainloop.glib import DBusGMainLoop # integration into the main loop

def handle_resume_callback():
    print "System just resumed from hibernate or suspend"

def handle_suspend_callback():
    print "System about to hibernate or suspend"

DBusGMainLoop(set_as_default=True) # integrate into main loob
bus = dbus.SystemBus()             # connect to dbus system wide
bus.add_signal_receiver(           # defince the signal to listen to
    handle_resume_callback,            # name of callback function
    'Resuming',                        # singal name
    'org.freedesktop.UPower',          # interface
    'org.freedesktop.UPower'           # bus name
)

bus.add_signal_receiver(           # defince the signal to listen to
    handle_suspend_callback,            # name of callback function
    'Sleeping',                        # singal name
    'org.freedesktop.UPower',          # interface
    'org.freedesktop.UPower'           # bus name
)

loop = gobject.MainLoop()          # define mainloop
loop.run()                         # run main loop


2 commentaires

Sauf que seuls les systèmes de bureau ont des DBU


En commençant par des versions plus récentes d'actualisation, le signal a déménagé à SystemD LOWIND, la nouvelle interface est "org.freedesktop.login1.manager", le nouveau nom de bus est "org.freedesktop.login1" et le nouveau signal est "PREPREEFORSLEEP" avec Un argument: vrai pour la suspension, faux pour la reprise. Plus d'infos Ici: serverfault.com/questions/573379/...