dbusサービスですべてのオブジェクトパスを一覧表示するには?

dbusサービスですべてのオブジェクトパスを一覧表示するには?

フォローアップの質問です利用可能なDBusサービスのリスト

次のPythonコードは、利用可能なすべてのDBusサービスを一覧表示します。

import dbus
for service in dbus.SystemBus().list_names():
    print(service)

Pythonのサービスの下にオブジェクトパスをどのようにリストできますか?答えにPythonが含まれていなくても大丈夫ですが、好みです。

Ubuntu 14.04を使用しています

答え1

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方式について...公式によると文書(下に標準インターフェース):

さまざまな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.UPoweregから始めて再帰的にチェックし、/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(必ずしも必要ではありません):

ここに画像の説明を入力してください。

答え2

Pythonがプログラムでこれを行うことができるかどうかはわかりません。おそらくそうかもしれませんが、何が起こるのかを調べるのは途方もない痛みを伴うことです。私は前にこれを試しましたが、結局Dbusが嫌いになりました。とにかく私は使用することをお勧めしますDフィート物事を調べたいなら。以下は私のコンピュータから盗んだスクリーンショットです。ブログ

ここに画像の説明を入力してください。

プログラム名、オブジェクトパスなどがわかったら、Pythonを使用してそれにアクセスできます。

はい

progname = 'org.freedesktop.NetworkManager'
objpath  = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'

bus = dbus.SystemBus()

obj = bus.get_object(progname, objpath)
interface = dbus.Interface(obj, intfname)     # Get the interface to obj
method = interface.get_dbus_method(methname)  # The method on that interface

method()                                      # And finally calling the method

ご覧のとおり、簡単な作業を終えるのは痛いです。しかし、これはDbusで得ることができる最も簡単なワークフローです!

したがって、GUIツールを使用してオブジェクトパス、インターフェイスなどを見つけます。次に、上記のコードをテンプレートとして使用してこれらのアイテムにアクセスします。または、IPythonのインタプリタを介してこれを実行して、各オブジェクトにどのメソッド、プロパティなどがあるかを確認することをお勧めします(タブをクリックして)。

答え3

サービスにオブジェクト実装がある場合、org.freedesktop.DBus.ObjectManagerそのメソッドはGetManagedObjects次を返します。「単一メソッド呼び出し内のすべてのオブジェクト、インタフェース、および属性。」たとえば、UDiks2 にはこれらのオブジェクトがあります。

答え4

私の経験では、バス名(サービス)のオブジェクトパスを取得することは、セルフチェックのためにオブジェクトパス "/"を使用して実行できることを知っています。つまり(上記の例を使用)

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.

これは、オブジェクトパス "/"がルートであり、各ノードがサブフォルダであるハードドライブのフォルダ構造を参照するのと同じです。これは、特定のバス名(サービス)のオブジェクトパスを取得し、オブジェクトパスを含むコレクションを整理するための最良の方法のようです。

関連情報