我正在尝试编写一个python脚本,该脚本将检测mtp设备(在本例中为Android手机(何时安装到树莓派3(运行树莓派3((运行树莓杰西(。我想在插入手机时自动将文件传输到手机。
我从给出的脚本开始,作为这个问题的第二个答案
我更改了一些东西,让它在我的树莓派上运行。当前脚本如下。当我插入/拔出手机时,我可以看到"设备新"和"设备删除"信号。当它到达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 运行脚本,但我仍然收到同样的错误。
我也尝试使用SessionBus而不是SystemBus。信号不同,总线名称是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)
我对systemd D-Bus API不够熟悉,无法判断一般方法是否正确,但这应该有助于解决特定问题:
self.bus.get_object('org.freedesktop.systemd1.Manager', path)
要bus.get_object()
的第一个参数是服务名称(通常是在服务文档中找到的已知名称(。我很确定'org.freedesktop.systemd1'是你应该使用的服务名称。 您当前使用的接口('org.freedesktop.systemd1.Manager'(是由该服务公开的对象之一实现的接口之一。
在我看来,接口和服务名称通常看起来相似这一事实是 D-Bus 中的一个设计错误......如果d-feet D-Bus调试器在raspbian上可用(或者你有另一个linux盒子要测试(,我建议使用它来查看所有D-Bus服务及其公开的对象和接口:它更容易理解它们之间的关系。