zt190 take a look at device policy. It should allow your client to connect to the hub with given client-id, subscribe and publish to specific topics. Enable all options if unsure.
Here is the article we touch Azure device policy a bit: https://flespi.com/kb/flespi-to-azure
luamqtt - MQTT client written in pure lua
Hi guys, many thanks for the great module! I'm trying to utilize SSL/TLS in order to securely communicate with flespi broker. Is my understanding correct, that luamqtt is not supporting certificate based authentication?
So if token is regarded as not secure enough and luamqtt is used as MQTT client, the only way would to go would be via port 8883 or 443?
jp_one I'm trying to utilize SSL/TLS in order to securely communicate with flespi broker. Is my understanding correct, that luamqtt is not supporting certificate based authentication?
If you mean SSL/TLS secure transport for MQTT protocol - it's fully supported if your Lua runtime has a luasec (or compatible) module. And you can specify any custom SSL parameters like certificate file in the secure={...}
table parameter in mqtt client instance constructor (see secure
parameter description there).
If you are talking about new MQTT 5.0 packet type AUTH - it's also supported in the luamqtt with client:auth() method. But this is a broker-specific authentication method, thus you cannot use it with flespi broker.
jp_one So if token is regarded as not secure enough and luamqtt is used as MQTT client
Sorry, I can't understand this part. Can you please rephrase it?
jp_one the only way would to go would be via port 8883 or 443?
I would say that you always should use port 8883 and SSL/TLS secure connection.
But port 443 is for websocket transport, which is not supported by luamqtt.
I currently have the problem that both update functions (loop and sync) block the process until a message is received.
With the system I want to implement this library in I don't have the possibility to create a thread or have this run externally somehow. So the whole program will stop running until messages come in. I do however have the possibility to continually call a function. I thought I could use the run_sync methode as from the description, but that also waits for an incoming message.
So I would need something more in line of a function that checks if a message was reveiced, if not it just moves along. Is there a straightforward way of calling such a function?
OleBier Can you please check how it's working on a pull request https://github.com/xhaskx/luamqtt/pull/31 ?
Unfortunately the pull request didn't help with the problem.
Honestly I have no idea. I haven't worked with networking that much to have a deeper understanding of it.
I'm working with the Defold game engine which incorporates luasocket as default. It is possible to use other libraries, but anything that's not pure Lua needs to be adapted to the engine for it to work properly, so I would like to avoid that.
Previously I used the MQTT client library from Paho, with which you manually had to call the handler in intervalls, which was perfect for my use case as the game engine does provide a function that gets periodically called. Recently we've updated our server and along with it switched to a newer version of Mosquitto, but I constantly get disconnected from it. So I was looking into using a newer MQTT library that also features MQTT version 5 and this one looked very promising.
I hoped that there possibly would be some kind of function I could call instead of using the two give one. But poking at the library myself a bit I guess I will needs to make certain adjustments to use it.
OleBier Regarding your description I suppose you need function ioloop_mt:iteration()
- https://github.com/xHasKx/luamqtt/blob/master/mqtt/ioloop.lua#L109
You can access it with
local ioloop = require("mqtt.ioloop")
print(ioloop.get().iteration) -- function: 0x612d866782c0
This function intended to be run in some outer loop, but I think your engine's handler will be suitable for that too.
- Edited
Thank you for creating the library and all the help you have given me. I managed to get it working with adding the following code to the init.lua. Which is basically just a slightly changed run_ioloop(...)
local loop = ioloop_get()
function mqtt.init_ioloop(...)
for i = 1, select("#", ...) do
local cl = select(i, ...)
loop:add(cl)
if type(cl) ~= "function" then
cl:start_connecting()
end
end
end
function mqtt.iterate_ioloop()
loop:iteration()
end
Hello,
I’m using CoppeliaSim for robot simulation and LuaMQTT to connect the robot to a local Mosquitto MQTT broker. The issue is that the MQTT connection is blocking the simulation, preventing the robot from moving based on MQTT payloads received in topics.
I’m trying to use async code to handle the MQTT connection without blocking the simulation, but it’s not working as expected. When the MQTT connection is established, the simulation gets blocked.
I’ve used coroutines in CoppeliaSim and LuaMQTT’s callback functions, but the MQTT connection still seems to block the simulation.
Has anyone managed to make this work asynchronously in CoppeliaSim? Any help would be appreciated!
PS: Just to be clear, the broker works, and both publish and subscribe functions work. However, when the MQTT connection is established, the simulation crashes.
- The link to my Lua script:
https://www.blackbox.ai/share/eb9b70e1-466e-4b61-8713-c810981d41ae
Thank you in advance for your help!
BochraDahmen , the call for mqtt.run_ioloop(client)
is blocking your runtime. You need to run ioloop_mt:iteration()
method of the default ioloop instance there instead. Default ioloop can be obtained with require("mqtt.ioloop").get()
function
kial Thank you very much for your help! My code required a few adjustments related to the luamqtt library, such as using ioloop_mt:iteration()
, as well as modifications specific to CoppeliaSim, like ensuring the coroutine is resumed at least once per simulation step.
For anyone who might find it useful, here is the working code, it connects CoppeliaSim to a local MQTT broker in a non-blocking way :
function sysCall_init()
sim = require('sim')
-- Initialize MQTT
package.path = package.path .. ";C:/Program Files/CoppeliaRobotics/CoppeliaSimEdu/lua/mqtt/?.lua"
print("Package path updated:", package.path)
local mqtt = require("mqtt")
local ioloop = require("mqtt.ioloop").get() -- Get the default ioloop instance
if not mqtt then
error("Failed to load MQTT library. Check the path and ensure the library exists.")
end
-- Create MQTT client
client = mqtt.client{
uri = "127.0.0.1:1883",
id = "robot_client",
clean = true
}
if not client then
error("Failed to create MQTT client.")
end
print("Created MQTT client:", client)
-- Set up the MQTT client on events
client:on{
connect = function(connack)
if connack.rc ~= 0 then
print("Connection to broker failed:", connack:reason_string(), connack)
return
end
print("Connected to broker:", connack)
-- Subscribe to the topic after connection
assert(client:subscribe{
topic = "robot/commands",
qos = 2,
callback = function(suback)
print("Subscribed to topic:", suback)
end
})
end,
message = function(msg)
assert(client:acknowledge(msg))
print("Received message:", msg.topic, msg.payload)
end,
error = function(err)
print("MQTT client error:", err)
end,
close = function()
print("MQTT connection closed")
end
}
-- Attach client to the ioloop
local success, err = pcall(function()
ioloop:add(client)
end)
if not success then
print("Failed to add client to ioloop:", err)
return
end
print("Client added to ioloop")
-- Create the coroutine for the MQTT loop
mqttCoroutine = coroutine.create(function()
while true do
local success, err = pcall(function()
ioloop:iteration(0.1) -- Small timeout to prevent excessive CPU usage
end)
if not success then
print("Error in ioloop iteration:", err)
end
coroutine.yield() -- Yield control back to CoppeliaSim
end
end)
end
-- Resume the coroutine in the sensing function
function sysCall_sensing()
if coroutine.status(mqttCoroutine) ~= 'dead' then
local ok, errorMsg = coroutine.resume(mqttCoroutine)
if errorMsg then
error(debug.traceback(mqttCoroutine, errorMsg), 2)
end
end
end