作者:candylie520 | 更新时间:2019-09-14 | 浏览量:1367
github上的程序我就不贴了, 先说现象
问题一:断开路由器后重连不上路由器的问题,
init.lua程序里面的问题就是, 没有自动重连, 所以当板子连接到wifi获取到ip后, 主动关闭路由器, 再打开路由器就连不上wifi了, 这个解决办法是加一句
wifi.sta.autoconnect(1)
这样每次断开路由器后就能重新连接上路由器了
问题二:先上git上贝壳的主程序
--use sjson
_G.cjson = sjson
--modify DEVICEID INPUTID APIKEY
DEVICEID = "458"
APIKEY = "9cb78xxx9"
INPUTID = "36"
host = host or "www.bigiot.net"
port = port or 8181
LED = 5
isConnect = false
gpio.mode(LED,gpio.OUTPUT)
local function run()
local cu = net.createConnection(net.TCP)
cu:on("receive", function(cu, c)
print(c)
isConnect = true
r = cjson.decode(c)
if r.M == "say" then
if r.C == "play" then
gpio.write(LED, gpio.HIGH)
ok, played = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn on!"})
cu:send( played.."\n" )
end
if r.C == "stop" then
gpio.write(LED, gpio.LOW)
ok, stoped = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn off!"})
cu:send( stoped.."\n" )
end
end
end)
cu:on('disconnection',function(scu)
cu = nil
isConnect = false
--停止心跳包发送定时器,5秒后重试
tmr.stop(1)
tmr.alarm(6, 5000, 0, run)
end)
cu:connect(port, host)
ok, s = pcall(cjson.encode, {M="checkin",ID=DEVICEID,K=APIKEY})
if ok then
print(s)
else
print("failed to encode!")
end
if isConnect then
cu:send(s.."\n")
end
tmr.alarm(1, 60000, 1, function()
if isConnect then
cu:send(s.."\n")
end
end)
end
run()
在kaiguan.lua程序中,如果路由器关了, 会走disconnection回调, 然后重新执行run方法, 但是此时路由器还没有开启, 那么程序最底下的定时器1就永远也发不出心跳包, 当然也会重连不上服务器了....
所以为了解决这个问题, 我改了下代码, 添加了一个看门的狗子
改动后的代码如下:
--use sjson
_G.cjson = sjson
--modify DEVICEID INPUTID APIKEY
DEVICEID = "1"
APIKEY = "11111111"
INPUTID = "36"
--host = host or "www.bigiot.net"
host = host or "121.42.180.30"
port = port or 8181
LED = 5
isConnect = false
gpio.mode(LED,gpio.OUTPUT)
local _Me = {}
autoTime = 1000
hadCloseRoter = false
count = 1
function watch()
--此定时间用来判断ip是否被中断过,因为当直接路由器断电后, wifi会自动连接,但是不会走自动登录服务器,
tmr.alarm(2, autoTime, 1, function()
print("zk,"..count)
count = count+1
if wifi.sta.getip() == nil then
--记录已经有过wifi断线 那就把循环次数调低到1分钟检测一次ip是否有获取到
autoTime = 6000
--关闭定时器节约资源
tmr.stop(1)
--如果是首次记录到断线,就重新按照新时间记录定时器
if hadCloseRoter == false then
tmr.stop(2)
--记录下已经有过断开wifi的记录
hadCloseRoter = true
print("dog watch Time set 6s once")
watch()
end
else
--如果记录过有wifi断线 并且当前ip已经获取到了,连上了路由器,就重新走run方法
if hadCloseRoter then
print("check had close wifi link, now need auto link service,and dog watch time set 1s once")
isConnect = false
hadCloseRoter = false
autoTime = 1000
tmr.stop(1)
tmr.stop(2)
cu = nil
watch()
run()
end
end
end)
end
watch()
function run()
--获取cu
local cu = net.createConnection(net.TCP)
--收到服务器消息的回调
cu:on("receive", function(cu, c)
print("zk,receive\n")
print(c)
isConnect = true
r = cjson.decode(c)
if r.M == "say" then
if r.C == "play" then
gpio.write(LED, gpio.HIGH)
ok, played = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn on!"})
cu:send( played.."\n" )
end
if r.C == "stop" then
gpio.write(LED, gpio.LOW)
ok, stoped = pcall(cjson.encode, {M="say",ID=r.ID,C="LED turn off!"})
cu:send( stoped.."\n" )
end
end
end)
--服务器断开连接的回调 如果是直接路由器断电会走此方法, 但是路由器的wlan断了不会走此方法
cu:on('disconnection',function(scu)
cu = nil
isConnect = false
--停止心跳包发送定时器,5秒后重试
print("zk,disconnection")
tmr.stop(1)
tmr.alarm(6, 3000, 0, run)
end)
--连接服务器 连接成功后会在Reciver中返回:{"M":"WELCOME TO BIGIOT"} 并且isConnet设置为true
cu:connect(port, host)
--encode密钥ID
ok, s = pcall(cjson.encode, {M="checkin",ID=DEVICEID,K=APIKEY})
--如果密钥ID正常就 打印密钥ID
if ok then
print(s)
else
print("failed to encode!")
end
--发送心跳
if isConnect then
cu:send(s.."\n")
end
--启动5s定时器 如果已连接就定时发送心跳
tmr.alarm(1, 8000, 1, function()
if isConnect then
print("auto send headPackge")
cu:send(s.."\n")
else
print("not connected ...")
end
end)
end
run()
添加了一个定时器的方法, 由于一点不懂lua还有nodemcu的api, 就这样搞了下, 核心逻辑是这样的:
连上网后每秒钟检测ip, 如果检测到ip为空了就把这个定时器的时间改成每6s运行一次查询ip, 如果检测到ip又获取到了,表示重连上了路由器, 这时候就再次把这个定时器的时间改为1s一次,
并且重新执行run方法, 所以 现在问题2就已经改好了, 每次被断开wifi后, 重连上了就能主动连接贝壳服务器了, 但是这样还是有问题......
问题三: 当脸上贝壳后台后, 路由器的网断了, 这时候虽然板子连上了路由器, 也一直在执行定时器1的心跳包, 但是,这种情况是不会走disconnection回调的,
所以造成的现象就是板子并不知道自己已经没有外网了,还一直以为自己在线, 不断地发心跳包, 这是没什么卵用的, 这时候, 当路由器又连接到了外网后, 板子还是处于蒙蔽状态
还是以为自己在线, 也收不到disconnection回调改变自己状态, 贝壳的服务器也是检测不到设备在线的
由于就昨天晚上研究下了lua, 还不是很懂, 所以问题3无法搞定, 目前就是 只要解决了路由器的wlan掉线后, 板子能知道自己掉线了, 然后等路由器的wlan外网连接好后板子能主动重连服务器 ,那这个程序就算完整了,
然后在环境中遇到各种现象应该都能自动的上线了... 有没有大神知道这个问题怎么搞定, 贴个代码看看怎么弄