2017-07-21 2 views
2

J'essaye d'écrire un script python qui détectera quand un périphérique mtp (dans ce cas un téléphone Android) a été monté sur un raspberry pi 3 (lancer raspbian jessie) . Je veux transférer automatiquement des fichiers sur le téléphone quand il est branché.Écouter les signaux dbus pour monter le périphérique mtp sur debian linux

J'ai commencé avec le script donné que la deuxième réponse à this question

J'ai changé quelques petites choses à faire pour courir sur mon pi framboise . Le script actuel est ci-dessous. Je peux voir les signaux UnitNew et UnitRemoved lorsque je branche/débranche mon téléphone. Quand il arrive à la fonction path_to_device, je reçois cette erreur:

DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.systemd1.Manager was not provided by any .service files 

Je lis dans une question similaire que c'est un problème d'autorisations, alors j'ai essayé d'exécuter le script comme sudo ./usb_SYSTEM.py mais je reçois encore la même erreur.

J'ai également essayé d'utiliser un SessionBus au lieu d'un SystemBus. Les signaux sont différents, le nom de bus est alors org.gtk.vfs.MountTracker. Je reçois toujours la même erreur, cette fois il est dit org.gtk.vfs.MountTracker n'est pas un service disponible. Lorsque j'essaie d'exécuter la version SessionBus avec sudo, je ne vois pas les signaux du tout. Est-ce que j'utilise la bonne entrée pour la fonction get_object()? Et le bon type de bus? Il n'y a pas de bus de destination puisque le signal est diffusé, je ne sais pas si cela fait partie du problème. J'ai une compréhension très limitée de Linux et des signaux/bus.

Script:

#!/usr/bin/env python 
# -*- encoding: utf-8 -*- 

import dbus 
import dbus.service 
if getattr(dbus, 'version', (0,0,0)) >= (0,41,0): 
    import dbus.glib 

from dbus.mainloop.glib import DBusGMainLoop 
from gi.repository import GLib 
import sys 
import os 


class DeviceManager: 
    def __init__(self): 
     self.bus = dbus.SystemBus() 
     self.bus.add_signal_receiver(self.device_added, 
         'UnitNew', 
         'org.freedesktop.systemd1.Manager', 
         None, 
         '/org/freedesktop/systemd1', 
         path_keyword='path') 

     self.bus.add_signal_receiver(self.device_removed, 
         'UnitRemoved', 
         'org.freedesktop.systemd1.Manager', 
         None, 
         '/org/freedesktop/systemd1', 
         path_keyword='path') 

     self.bus.add_signal_receiver(self.print_event, None, None, None, None, 
            sender_keyword='sender', message_keyword='message') 

    def path_to_device(self, path): 
     return self.bus.get_object('org.freedesktop.systemd1.Manager', path) 

    def device_added(self, *args, **kwds): 
     path = kwds['path'] 
     print 'Added', path 
     properties = self.path_to_device(path).GetAllProperties() 
     print properties.get('info.category') 
     if properties.get('info.category') == u'volume': 
      label, dev = properties.get('volume.label'), properties.get('block.device') 
      print 'Mounting %s on /mnt/%s' %(dev, label) 
      ## os.system('mount %s /mnt/%s' %(dev, label)) 

    def device_removed(self, *args, **kwds): 
     path = kwds['path'] 
     print 'Removed', path 

    def print_event(*args, **sender): 
     print "got signal from:" 
     print sender 

if __name__ == '__main__': 
    DBusGMainLoop(set_as_default=True) 

    m = DeviceManager() 

    mainloop = GLib.MainLoop() 
    try: 
     mainloop.run() 
    except KeyboardInterrupt: 
     mainloop.quit() 
     print 'Exiting...' 
     sys.exit(0) 

Répondre

1

Je ne suis pas assez familier avec les systemd API D-Bus pour être en mesure de dire si l'approche générale est correcte, mais cela devrait aider le problème spécifique:

self.bus.get_object('org.freedesktop.systemd1.Manager', path) 

Le premier argument à bus.get_object() est le nom du service (généralement un nom connu dans la documentation des services). Je suis sûr que 'org.freedesktop.systemd1' est le nom du service que vous devriez utiliser. Celui que vous utilisez actuellement ('org.freedesktop.systemd1.Manager') est l'une des interfaces implémentées par l'un des objets exposés par ce service. Le fait que les interfaces et les noms de service se ressemblent souvent est à mon avis une erreur de conception dans D-Bus ... Si le débogueur D-Bus d-feet est disponible sur raspbian (ou si vous avez une autre boîte Linux à tester) , Je suggère de l'utiliser pour voir tous les services D-Bus et leurs objets et interfaces exposés: il est beaucoup plus facile de comprendre comment ils se rapportent les uns aux autres.