local P = {} local m, topic, cid local active_subscriptions = {} local pending_subscriptions = {} local pending_subcsription local function p(msg) print("MQTT: "..msg) end -- Subscribe to all registered subscriptions -- TODO: subscriptions that are not successfull will remain in state = 1. Might not be a real problem if it happens, the server probably disallowed the subscription. local function create_subscriptions() print("create_subscriptions, pending count "..table.getn(pending_subscriptions)..", pending: "..tostring(pending_subscription)) if (pending_subscription) then return end pending_subcsription = table.remove(pending_subscriptions) -- The API claims that the callback has this signature: function(client, topic, message) -- but that doesn't seems right from the source code. The code doesn't -- remember the topics that is being subscribed to. m:subscribe(pending_subcsription, 0, function(client) print("success: "..pending_subcsription) table.insert(active_subscriptions, pending_subscription) pending_subscription = nil create_subscriptions() end) end local function mq_client_connected(con) p("connected") create_subscriptions() end local function disconnect() p("Lost wifi connection, disconnecting") m:close() m = nil -- append active_subscriptions to pending_subscriptions active_subscriptions = {} end function mq_on_timer() -- This crashes the module: -- local status = wifi.sta.status() -- p("checking status, status="..status) local status = wifi.sta.getip() if status and status ~= "0.0.0.0" then if not m then p("connecting") -- client id, keepalive, username, password m = mqtt.Client(cid, 120) -- m:on("connect", mq_connected) m:on("offline", function() m:close(); m = nil end) -- host, port, secure, auto_reconnect, function(client), ssl=8883 m:connect("trygvis.io", 1883, 0, 0, mq_client_connected) end else if m then disconnect() end end end function P.init(timer_id, client_id) cid = client_id topic = "/esp8266/"..client_id tmr.alarm(timer_id, 3 * 1000, 1, mq_on_timer) end function P.subscribe(path, cb) subscription = subscriptions[path] if subscription then print("subscription on "..path.." already registered, state="..tostring(subscription.state)) return end print("Registering subscription on "..path) pending_subscriptions[path] = true create_subscriptions() end function P.publish(path, payload) if not m then print("Not connected, dropping message to "..path) return false, 'not connected' end path = topic.."/"..path print("path="..path) m:publish(path, payload, 0, 0) return true, 'ok' end return P