Search code examples
luadbuslgi

Lua: translate a Python code that emits a message using a XML dbus definition into Lua


I asked this in a comment of a previous question but I think it is better to move it here as a new independent question.

I am trying to figure out how to translate this Python code to emit a dbus signal into Lua using lgi DBus:

class DBUSTestInterface(object):
    """
    Server_XML definition.
    Emit / Publish a signal that is a random integer every second 
    type='i' for integer. 
    """
    dbus = """
    <node>
        <interface name="com.test.device.aaa">
            <signal name="get">
                <arg type='s'/>
                <arg type='s'/>
                <arg type='s'/>
                <arg type='s'/>
                <arg type='s'/>
                <arg type='s'/>
                <arg type='s'/>
                <arg type='i'/>
            </signal>
        </interface>
    </node>
    """
    get = signal()

emit = DBUSTestInterface()
bus.publish("com.test.device.get", emit)

I suspect (not sure at all) that it has to be made sending a message to the introspectable interface, something similar to this:

local object = "/org/freedesktop/DBus"
local interface = "org.freedesktop.DBus.Introspectable"
local method = "Introspect"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(aoo)", {{location},session})) -- How do I set the same message as above?

But I am not sure, and I have no idea of how to set the message body with the XML that is working in Python.

If you can provide some example or point out where I can find it I would appreciate it!

Thanks!


Solution

  • Heh, Google just lead me here while looking at https://github.com/pavouk/lgi/issues/220.

    Somehow I feel like your code example cannot work as-is / is not some self-contained python code. Hence, I will go with the comment in the text:

    Emit / Publish a signal that is a random integer every second

    Lua code doing this (well, except for "random integer", unless you consider 42 to be random):

    local lgi = require("lgi")
    local Gio, GLib, GObject = lgi.Gio, lgi.GLib, lgi.GObject
    
    local conn
    
    GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, function()
        if conn then
            conn:emit_signal(nil, "/your/example/has/no/path",
                "com.test.device.aaa", "get",
                GLib.Variant("(sssssssi)", { "what", "are", "all",
                "these", "strings", "for", "?", 42 }))
        end
        return true
    end)
    
    local function on_bus_acquire(con)
        conn = con
    
        local function arg(name, signature)
            return Gio.DBusArgInfo{ name = name, signature = signature }
        end
        local interface_info = Gio.DBusInterfaceInfo {
            name = "com.test.device.aaa",
            signals = {
                Gio.DBusSignalInfo{
                    name = "get",
                    args = {
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "s"),
                        arg("no_name?!?", "i")
                    }
                }
            }
        }
        conn:register_object("/your/example/has/no/path", interface_info, nil)
    end
    
    Gio.bus_own_name(Gio.BusType.SESSION, "com.test.device.get", Gio.BusNameOwnerFlags.NONE,
        GObject.Closure(on_bus_acquire), nil, nil)
    
    GLib.MainLoop.new():run()