これは 利用可能なDBusサービスのリスト へのフォローアップ質問です。
次のpythonコードは、利用可能なすべてのDBusサービスをリストします。
import dbus
for service in dbus.SystemBus().list_names():
print(service)
Pythonのサービスの下のオブジェクトパスをリストするにはどうすればよいですか?回答にpythonが含まれていなくてもかまいませんが、それが推奨されます。
Ubuntu 14.04を使用しています
QT
セットアップは、qdbus
を使用して、最も便利な方法を提供します。
qdbus --system org.freedesktop.UPower
プリント
/
/org
/org/freedesktop
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/line_power_ADP0
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
python way ...公式について docs (understandard interfaces)について):
さまざまなD-Busアプリケーションで役立つ可能性のある標準インターフェースがいくつかあります。
org.freedesktop.DBus.Introspectable
このインターフェースには1つのメソッドがあります。
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
オブジェクトインスタンスは
Introspect
を実装する場合があり、これはオブジェクトの[〜#〜] xml [〜#〜]記述を返します。 、オブジェクトパスツリーでその下にあるオブジェクト、およびそのプロパティ。
だから、これはあなたが始めるための非常に単純な例です。 xml.etree.ElementTree
と dbus
を使用します:
#!/usr/bin/env python
import dbus
from xml.etree import ElementTree
def rec_intro(bus, service, object_path):
print(object_path)
obj = bus.get_object(service, object_path)
iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
xml_string = iface.Introspect()
for child in ElementTree.fromstring(xml_string):
if child.tag == 'node':
if object_path == '/':
object_path = ''
new_path = '/'.join((object_path, child.attrib['name']))
rec_intro(bus, service, new_path)
bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')
org.freedesktop.UPower
を再帰的にイントロスペクトします。 /org/freedesktop/UPower
およびすべてのオブジェクトパス(ノード名)を出力します。
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0
これは、d-feet
を使用した場合に得られるものとほぼ同じです(必要ない場合)。
これをプログラムでPythonで実行できるかどうかはわかりません。かもしれませんが、その方法を理解することは大きな頭痛の種になるでしょう。私は以前にそれをやろうとして、結局Dbusを嫌っていました。とにかく、あなたが物事を調査したいのなら、私は d-feet を使うことを勧めます。以下は blog から盗んだスクリーンショットです。
プログラム名、オブジェクトパスなどがわかったら、Pythonを使用してそれらにアクセスできます。
例
progname = 'org.freedesktop.NetworkManager'
objpath = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'
bus = dbus.SystemBus()
obj = bus.get_object(progname, objpath) # Here we get object
intf = dbus.Interface(obj, intfname) # Here we get interface
meth = inf.get_dbus_method(methname) # Here we get method
meth() # And finally calling the method
ご覧のとおり、単純なことを行うのはお尻の痛みです。しかし、これはDbusで取得できる最も簡単なワークフローです。
したがって、GUIツールを使用して、オブジェクトのパスやインターフェイスなどを見つけます。次に、上記のコードスニペットをテンプレートとして使用して、これらにアクセスします。また、IPythonのインタープリターを介してこれを実行し、各オブジェクトが持つメソッド、プロパティなどを確認することをお勧めします(タブを押す)。
サービスにorg.freedesktop.DBus.ObjectManager
を実装するオブジェクトがある場合、そのメソッドGetManagedObjects
は 「すべてのオブジェクト、インターフェース、およびプロパティを1回のメソッド呼び出しで返します。」 たとえば、UDisks2にはそのようなオブジェクト。
私の経験からバス名(サービス)のオブジェクトパスを取得するために知っていることは、オブジェクトパス '/'でイントロスペクトすること(つまり、上記の例を使用)です。
introspectfunc('org.freedesktop.UPower', '/')
これは返すべきです:
<node name="/">
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>
次に、パス '/ org'で内省します
introspectfunc('org.freedesktop.UPower', '/org')
これは返すべきです:
<node name="/org">
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>
等々:
introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.
これは、オブジェクトパス「/」がルートで、すべてのノードがサブフォルダーであるハードドライブのフォルダー構造をたどるようなものです。これは、特定のバス名(サービス)のオブジェクトパスを取得し、オブジェクトパスを含むコレクションを構築する最良の方法のようです
#don_crissti の回答に従って、私は実装しました。このソリューションは、インターフェースの名前とメソッド、およびシグナル情報を提供します
import dbus
from xml.etree import ElementTree
bus = dbus.SystemBus()
def busNames():
return [ name for name in bus.list_names() if not name.startswith(":") ]
def pathNames(service,object_path="/",paths=None,serviceDict=None):
if paths == None:
paths = {}
paths[object_path] = {}
obj = bus.get_object(service, object_path)
iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
xml_string = iface.Introspect()
root = ElementTree.fromstring(xml_string)
for child in root:
if child.tag == 'node':
if object_path == '/':
object_path = ''
new_path = '/'.join((object_path, child.attrib['name']))
pathNames(service, new_path,paths)
else:
if object_path == "":
object_path = "/"
functiondict = {}
paths[object_path][child.attrib["name"]] = functiondict
for func in child.getchildren():
if func.tag not in functiondict.keys():
functiondict[func.tag] =[]
functiondict[func.tag].append(func.attrib["name"])
if serviceDict == None:
serviceDict = {}
serviceDict[service] = paths
return serviceDict
import json
import random
service=random.sample(busNames(),1).pop()
print service
print json.dumps(pathNames(service),indent=3)