I have found situation where I have ruter from my internet provider and second router for my home network and this is MikroTik router.
MikroTik is connected to providers router with network cable to get internet.
Now, when wifi brake down, it start again and nodemcu get IP from MikroTik second router because it is connected to MikroTik wifi but MikroTik needs 2 minutes to get Online again and here is my BUG. IP is found and setup.lua script blocks because in this script is defined that MQTT is started again after wifi reconnects. But internet is not available in this moment and MQTT fails. Whole program is freezed.
I upload new setup script with code that search for internet like ping after wifi reconnects. When internet is available then MQTT is connected again. I tested it and it works in my scripts. My scripts have been updated with my new programs and functionalities and this is not scripts that I have been uploaded at first but I implemented this new code as is in my new script but I did not tested this script in this forum. If you find BUG or if you tested it and correct my code please post it on this forum.
Thanx, Faramon
setup.lua:
local module = {}
m = nil
-- TogglingLED
local pinUp = 2 --> GPIO4 -->D2
local state = gpio.LOW
gpio.mode(pinUp, gpio.OUTPUT)
gpio.write(pinUp, state)
local pinDown = 1 --> GPIO5 --> D1
gpio.mode(pinDown, gpio.OUTPUT)
gpio.write(pinDown, state)
local is_started = 0
local function resetPins()
gpio.write(pinUp, state)
gpio.write(pinDown, state)
end
local function pingTime()
m:publish(config.GETTIME, "gettime", config.QOS, config.RETAIN, function(conn) end)
end
local function publishUpDownStop(pPubPayload)
-- stop first if Up or Down
m:publish(config.STATUS, "S", config.QOS, config.RETAIN, function(conn) end)
-- then up or down
m:publish(config.STATUS, pPubPayload, config.QOS, config.RETAIN_TRUE, function(conn) end)
--m:publish(config.STATUS, "AVLB", config.QOS, config.RETAIN, function(conn) end)
end
local function push(pState)
if pState == "U" then
print("Up")
gpio.write(pinDown, gpio.LOW)
gpio.write(pinUp, gpio.HIGH)
end
if pState == "D" then
print("Down")
gpio.write(pinUp, gpio.LOW)
gpio.write(pinDown, gpio.HIGH)
end
if pState == "S" then
print("Stop")
gpio.write(pinDown, gpio.LOW)
gpio.write(pinUp, gpio.LOW)
end
publishUpDownStop(pState)
-- Timer for reset (stoping job Up or Down) after 10 sec
if pState == "U" or pState == "D" then
tmr.alarm(2,10000,0,function()
print("Stop")
gpio.write(pinDown, gpio.LOW)
gpio.write(pinUp, gpio.LOW)
publishUpDownStop("S")
end)
end
end
-- Sends my id to the broker for registration
local function register_myself()
print("Subscribing...")
m:subscribe({[config.SUBPOINT]=config.QOS, [config.PING]=config.QOS, [config.PRINTTIME]=config.QOS, nil})
print("Subscribed on " .. config.SUBPOINT)
end
local function mqtt_start()
is_started = 1
-- Connect to broker
m:connect(config.BROKER, config.PORT, config.QOS, config.RECONNECT,
function(con)
print("Connected!")
register_myself()
m:publish(config.STATUS, "AVLB", config.QOS, config.RETAIN, function(conn) end)
pingTime()
end,
function(client, reason)
print("failed reason: " .. reason)
resetPins()
end)
-- on receive message
m:on("message", function(conn, topic, data)
--print(topic .. ":" ..data)
if data ~= nil then
if is_started == 0 then
if topic == node.chipid() .."/SET" then
if data == "U" or data == "D" or data == "S" then
push(data)
--publishUpDownStop(data)
end
end
end
if topic == config.PING and data == "AVLB" then
--print("Sending response Available")
m:publish(config.STATUS, "AVLB", config.QOS, config.RETAIN, function(conn) end)
end
is_started = 0
end
end)
m:on("offline", function(client)
print ("Offline " .. config.ID)
resetPins()
--print(node.heap())
tmr.start(1)
print("Configuring Wifi ...")
wifi.setmode(wifi.STATION);
wifi.sta.getap(wifi_start)
--node.restart()
end)
print("Connecting to broker...")
end
module.timeout_restart = 0;
reset_pin = 5 --> GPIO14 -->D5
gpio.mode(reset_pin, gpio.INT, gpio.PULLUP)
local function isOnline()
http.get("http://httpbin.org/ip", nil, function(code, data, result)
print(code)
if (code < 0) then
print("HTTP request failed...")
else
--print(code, data)
print("ping success")
tmr.stop(6)
print("Starting application..")
return true
end
end)
end
local function wifi_wait_ip()
if wifi.sta.getip()== nil then
print("IP unavailable, Waiting..."..module.timeout_restart)
module.timeout_restart = module.timeout_restart + 1
if(module.timeout_restart >= 180) then
--file.remove('wifi_config.lc')
node.restart()
end
gpio_read = gpio.read(reset_pin)
is_pressed = 0
if (gpio_read == 0) then
is_pressed = 1
else
is_pressed = 0
end
print("Pin " ..reset_pin .. " - state is: " .. is_pressed)
if(is_pressed == 1) then
--file.remove("wifi_config.lc")
node.restart()
end
else
tmr.stop(1)
print("\n====================================")
print("ESP8266 mode is: " .. wifi.getmode())
print("MAC address is: " .. wifi.ap.getmac())
--print("AP address is: " .. wifi.ap.getip())
print("IP is "..wifi.sta.getip())
print("====================================")
print("Connecting to DNS...")
return tmr.alarm(6, 10000, 1, isOnline)
--return true
end
end
local function wifi_start(list_aps)
print("Starting wifi_start for searching available wifi networks!")
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 120 sec
m = mqtt.Client(config.ID, config.KEEPALIVE, config.UN, config.PS)
--m:lwt("SmartHome/Roletna/Status", "Offline " .. config.ID, 0, 0)
m:lwt(config.STATUS, "OFFLINE", 0, 0)
mqtt_start()
end
return module