lualgi

lua lgi subscribe to DBus signal


I am using LUA for the first time and I am trying to subscribe a callback to be executed when a DBus signal is received. I found some examples about how to send DBus signals using lgi but I haven't found anything about how to listen to a signal. Is there any example about that? in lgi documentation I didn't find it.

Thanks

[EDIT]

Just it case it is useful for someone, I have managed to subscribe to a signal using dbus_proxy (https://github.com/stefano-m/lua-dbus_proxy). This sample code subscribes to a signal and then emits one to see if the callback is called:

local lgi = require('lgi')
local GLib = lgi.GLib 
local p = require('dbus_proxy')
local Bus = p.Bus
local Proxy = p.Proxy   

local proxy = Proxy:new(
  {
    bus = Bus.SESSION,
    name = "org.freedesktop.DBus",
    path= "/org/freedesktop/DBus",
    interface = "org.freedesktop.DBus"
  }
)

local called = false
local received_proxy
local received_params
local function callback(proxy_obj, ...)
  print('Hi!')
  called = true
  received_proxy = proxy_obj
  received_params = {...}
end
local signal_name = "NameOwnerChanged"
local sender_name = nil -- any sender
proxy:connect_signal(callback, signal_name, sender_name)

local bus_name = "com.example.Test2"
local DBUS_NAME_FLAG_REPLACE_EXISTING = 2
proxy:RequestName(bus_name, DBUS_NAME_FLAG_REPLACE_EXISTING)

main_loop = GLib.MainLoop()
main_loop:run()

I will keep looking into it

Also, 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)

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

Thanks!


Solution

  • Here is a code sample, it subscribes for bluez PropertiesChanged signals for all object paths on system bus. You can change bus type, signal, interface name etc., as per your requirement and try it.

    local lgi = require 'lgi'
    local GLib, Gio = lgi.GLib, lgi.Gio
    local main_loop = GLib.MainLoop()
    
    --Get a system bus
    local bus = Gio.bus_get_sync(Gio.BusType.SYSTEM)
    
    --Create a user callback function that needs to operate when signal is received
    function onDBusSignalCallback(conn, sender, object_path, interface_name, signal_name, user_data)
            local str = string.format("SIGNAL - object_path:%s, interface_name:%s, signal_name:%s", object_path, interface_name, signal_name)
            print(str)
    end
    
    
    --Subscribe to any signal.
    local sub_id = bus:signal_subscribe('org.bluez', 'org.freedesktop.DBus.Properties',
                    'PropertiesChanged', nil, nil, Gio.DBusSignalFlags.NONE, onDBusSignalCallback)
    if sub_id then
            print("Subscription id", sub_id)
    end
    
    main_loop:run()