2017-07-21 13 views
2

mtpデバイス(この場合はAndroid電話)がラズベリーパイ3(raspbian jessieを実行中)にマウントされていることを検出するpythonスクリプトを作成しようとしています。 。私はそれが接続されると自動的に携帯電話にファイルを転送したい。dbusシグナルを聞いてdebian linuxにmtpデバイスをマウントする

私は私が私のラズベリーパイ上で実行するためにそれを得るためにいくつかのことを変更し​​

に2つ目の答えとして与えられたスクリプトで始まっ。現在のスクリプトは以下の通りです。私は、私の電話機の抜き差しをするとUnitNewとUnitRemovedの信号を見ることができます。それはpath_to_device関数になると、私はこのエラーを取得する:

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

は、私は、これはアクセス許可の問題であることを同様の質問に読み、私はsudoの./usb_SYSTEM.pyとしてスクリプトを実行しようとしたが、私はまだ取得します同じエラー。

また、私はSystemBusの代わりにSessionBusを使ってみました。信号は異なります。バス名はorg.gtk.vfs.MountTrackerです。私はまだ同じエラーが表示されますが、今度はorg.gtk.vfs.MountTrackerは利用可能なサービスではありません。私がsudoでSessionBusのバージョンを動かそうとすると、私は全くシグナルを見ません。

私はget_object()関数の正しい入力を使用していますか?そして、正しいバスタイプですか?信号がブロードキャストされているので、宛先バスはありません。問題の一部であるかどうかはわかりません。私は、Linuxとシグナル/バスの理解が非常に限られています。

スクリプト:

#!/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) 

答えて

1

私は一般的なアプローチが正しいかどうかを伝えることができることがsystemdにD-BUS APIで十分慣れていないんだが、これは特定の問題を支援する必要があります

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

bus.get_object()の最初の引数はサービス名です(通常、サービスのドキュメントに記載されているよく知られている名前)。私はかなり 'org.freedesktop.systemd1'があなたが使用すべきであるサービス名であると確信しています。現在使用しているもの( 'org.freedesktop.systemd1.Manager')は、そのサービスによって公開されているオブジェクトの1つによって実装されたインタフェースの1つです。

インターフェイスとサービス名がよく似ているという事実は、私の考えではD-Busのデザインミスです... d-feet Dバスのデバッガがraspbianで利用可能な場合(またはテストする別のLinuxボックスがある場合)私はそれを使ってすべてのD-Busサービスと公開されているオブジェクトとインタフェースを見ることをお勧めします。

関連する問題