As the title says... Chat on...
User avatar
By faramon
#64703 Hi,

I have mqtt on my NodeMcu with Esp8266 v0.9 and apropriate firmware.
Mqtt works great.
but I found problem with Mqtt when wifi or internet is down and when reconnect, mqtt is not able to reconnects to works like usual. It doesn't receive or publish payloads and I get message that it is offline.
How to resolve the problem with Mqtt and wifi reconnection?

Thanx,
Faramon
Last edited by faramon on Tue Apr 25, 2017 6:28 am, edited 2 times in total.
User avatar
By faramon
#64730 After 15 hours of work on this problem, I think I solve the problem.
My NodeMcu have 4 scripts in Lua that makes my aplication for wifi connection stable.

First is init.lua (for now I have test.lua):
Code: Select allprint("ESP8266 module start")
app = require("application")
config = require("config")
setup = require("setup")

setup.start()

second is config.lua:
Code: Select alllocal module = {}

module.SSID = {} 
module.SSID["mySSID"] = "myWifiPass"
module.BROKER = "m20.cloudmqtt.com" 
module.UN = 'myUsername'
module.PS = 'myPassword'
module.RECONNECT = 0
module.QOS = 0
module.PORT = 12986
module.KEEPALIVE = 120
module.ID = node.chipid()
module.SUBPOINT = "temp/status"
module.PUBPOINT = "temp/messages"
module.RETAIN = 0
module.GETTIME = "test/gettime"
module.PRINTTIME = "test/printtime"

return module 

then setup.lua:
Code: Select alllocal module = {}

local function wifi_wait_ip() 
  if wifi.sta.getip()== nil then
    print("IP unavailable, Waiting...")
  else
    tmr.stop(1)
    print("\n====================================")
    print("ESP8266 mode is: " .. wifi.getmode())
    print("MAC address is: " .. wifi.ap.getmac())
    print("IP is "..wifi.sta.getip())
    print("====================================")
    app.start()
  end
end

local function wifi_start(list_aps) 
    if list_aps then
        for key,value in pairs(list_aps) do
            if config.SSID and config.SSID[key] then
                wifi.setmode(wifi.STATION);
                wifi.sta.config(key,config.SSID[key])
                wifi.sta.connect()
                print("Connecting to " .. key .. " ...")
                --config.SSID = nil  -- can save memory
                tmr.alarm(1, 2500, 1, wifi_wait_ip)
            print("Connected!")
            end
        end
    else
        print("Error getting AP list")
    end
end

function module.start() 
  print("Configuring Wifi ...")
  wifi.setmode(wifi.STATION);
  wifi.sta.getap(wifi_start)
end

return module

and final is application.lua:
Code: Select alllocal module = {} 
m = nil

-- Toggling LED or Relay - signal OUT
local pin = 4  --> GPIO2
local value = gpio.LOW
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, value)

local function pingTime()
    m:publish(config.GETTIME, "gettime", config.QOS, config.RETAIN, function(conn)
    end)
end

local function toggleLed (pPin, pValue)
    gpio.write(pPin, pValue)
end

-- Sends my id to the broker for registration
local function register_myself() 
    print("Subscribing...")
    m:subscribe({[config.SUBPOINT]=config.QOS, [config.PRINTTIME]=config.QOS, nil})
end

local function mqtt_start() 
   -- Connect to broker
    m:connect(config.BROKER, config.PORT, config.QOS, config.RECONNECT, function(con)
      print("Connected!")
        register_myself()
        pingTime()
    end,
    function(client, reason)
        print("failed reason: " .. reason)
    end)
      
    -- on receive message
    m:on("message", function(conn, topic, data)
        print(topic .. ":" )
        if data ~= nil then
          print(data)
          -- do something, we have received a message
          if data == "1" then
            print("On")
            toggleLed(pin, gpio.HIGH)
          end

          if data == "0" then
            print("Off")
            toggleLed(pin, gpio.LOW)
          end
        end
    end)

   -- This is part when wifi disconnects and I tested it for 5 minutes connecting wifi back and this works
    m:on("offline", function(client)
      print ("Offline " .. config.ID)
      --print(node.heap())
      tmr.start(1)
      print("Configuring Wifi ...")
      wifi.setmode(wifi.STATION);
      wifi.sta.getap(wifi_start)
    end)
   
    print("Connecting to broker...")
end

--------------------- Wifi part again ----------------------------------
local function wifi_wait_ip() 
  if wifi.sta.getip()== nil then
    print("IP unavailable, Waiting...")
  else
    tmr.stop(1)
    print("\n====================================")
    print("ESP8266 mode is: " .. wifi.getmode())
    print("MAC address is: " .. wifi.ap.getmac())
    print("IP is "..wifi.sta.getip())
    print("====================================")
    --app.start()
    return true
  end
end

local function wifi_start(list_aps) 
    if list_aps then
        for key,value in pairs(list_aps) do
            if config.SSID and config.SSID[key] then
                wifi.setmode(wifi.STATION);
                wifi.sta.config(key,config.SSID[key])
                wifi.sta.connect()
                print("Connecting to " .. key .. " ...")
                --config.SSID = nil  -- can save memory
                tmr.alarm(1, 5000, 1, wifi_wait_ip)
                print("Connected!")
            end
        end
    else
        print("Error getting AP list")
    end
end
-------------------------------------------

function module.start()
  print("Starting MQTT module...")
  -- initiate the mqtt client and set keepalive timer to 120sec
  m = mqtt.Client(config.ID, config.KEEPALIVE,  config.UN, config.PS)
  m:lwt("temp/messages", "Offline " .. config.ID, 0, 0)
  mqtt_start()
end

return module 

If you find bugs or inappropriate behavior, please let me know!

Thanx,
Faramon