digitaltrails / ddcutil-service

A Dbus ddcutil server for control of DDC Monitors/VDUs
GNU General Public License v2.0
11 stars 1 forks source link

Returning a variant property array from Detect is undesirable. #1

Closed digitaltrails closed 10 months ago

digitaltrails commented 10 months ago

The Detect method is returning an array of properties. The properties vary in type, which means they must be typed Variant. On the client side the Variant properties must be explicitly unpacked to native types - this is an undesirable requirement for such a simple interface.

The alternative to returning arrays of properties have their own issues:

I investigated whether an struct of non-variant properties was valid, for example `({si}{ss}{sq})', but it seems not.

digitaltrails commented 10 months ago

After experimenting with a python interface I went with the second described solution. The Detect() method now returns structs. Python receives the structs as tuples, so they're pretty easy to work with. By adding a property the returns the names of the structure members, python can easily turned the unnamed tuples into named tuples:

bus = SessionMessageBus()

ddcutil_proxy = bus.get_proxy(
    "com.ddcutil.libddcutil.DdcutilServer",  # The bus name
    "/com/ddcutil/libddcutil/DdcutilObject",  # The object name
)

# Create a namedtuple that matches the attributes returned by the detect method
DetectedAttributes = namedtuple("DetectedAttributes", ddcutil_proxy.AttributesReturnedByDetect)

# Call detect to get back a list of unnamed tuples, one for each VDU
number_detected, list_of_displays, status, errmsg = ddcutil_proxy.Detect()
print(f"{number_detected=} {status=} {errmsg=}\n")
print(list_of_displays)

# Reform unnamed tuples into a list of namedtuples (optional, for convenience)
vdu_list = [DetectedAttributes(*vdu) for vdu in list_of_displays]
print(vdu_list)