GPRS(Air202) Lua开发: 物联网MQTT ,继电器远程控制
硬件
协议规定
上位机同时控制两路继电器协议: "data":"switch":开关指令; "bit":"1&2":第一路和第二路
询问两路继电器状态: {"data":"switch","bit":"1&2","status":"-1"}
控制两路继电器吸合: {"data":"switch","bit":"1&2","status":"1&1"}
控制两路继电器断开: {"data":"switch","bit":"1&2","status":"0&0"}
控制第一路吸合,第二路断开: {"data":"switch","bit":"1&2","status":"1&0"}
控制第一路断开,第二路吸合: {"data":"switch","bit":"1&2","status":"0&1"}
下位机回复两路继电器状态:
第一路断开,第二路吸合: {"data":"switch","bit":"1&2","status":"0&1"}
上位机控制一路继电器协议: "bit":"1":第一路
询问第一路继电器状态: {"data":"switch","bit":"1","status":"-1"}
询问第二路继电器状态: {"data":"switch","bit":"2","status":"-1"}
控制第一路继电器吸合: {"data":"switch","bit":"1","status":"1"}
控制第二路继电器断开: {"data":"switch","bit":"2","status":"0"}
下位机回复两路继电器状态:
第一路断开 {"data":"switch","bit":"1","status":"0"}
第二路吸合 {"data":"switch","bit":"2","status":"1"}
处理继电器消息
--- 模块功能:MQTT客户端数据接收处理 -- @author openLuat -- @module mqtt.mqttInMsg -- @license MIT -- @copyright openLuat -- @release 2018.03.28 module(...,package.seeall) require"pins" local IntoFlag=false; local JsonTable = {};--组合JSON使用 --继电器引脚 RelayPin1 = pins.setup(pio.P0_4,0) RelayPin1In = pio.P0_4 RelayPin2 = pins.setup(pio.P0_2,0) RelayPin2In = pio.P0_2 --记录继电器的状态,状态改变发送状态 local RelayState1; local RelayState2; --处理继电器数据 local function Relay(jsondata) IntoFlag = false; if jsondata["bit"] ~= nil then if jsondata["bit"] =="1&2" then --两路继电器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查询 IntoFlag=true; elseif jsondata["status"] =="0&0" then IntoFlag=true; RelayPin1(0); RelayPin2(0); elseif jsondata["status"] =="0&1" then IntoFlag=true; RelayPin1(0); RelayPin2(1); elseif jsondata["status"] =="1&0" then IntoFlag=true; RelayPin1(1); RelayPin2(0); elseif jsondata["status"] =="1&1" then IntoFlag=true; RelayPin1(1); RelayPin2(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "1&2"; JsonTable["status"] = pio.pin.getval(RelayPin1In).."&"..pio.pin.getval(RelayPin2In); --拼接继电器状态 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end elseif jsondata["bit"] =="1" then --控制第一路继电器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查询 IntoFlag=true; elseif jsondata["status"] =="0" then IntoFlag=true; RelayPin1(0); elseif jsondata["status"] =="1" then IntoFlag=true; RelayPin1(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "1"; JsonTable["status"] = pio.pin.getval(RelayPin1In); --继电器状态 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end elseif jsondata["bit"] =="2" then --控制第一路继电器 if jsondata["status"] ~= nil then if jsondata["status"] =="-1" then--查询 IntoFlag=true; elseif jsondata["status"] =="0" then IntoFlag=true; RelayPin2(0); elseif jsondata["status"] =="1" then IntoFlag=true; RelayPin2(1); end if IntoFlag==true then JsonTable["data"] = "switch"; JsonTable["bit"] = "2"; JsonTable["status"] = pio.pin.getval(RelayPin2In); --继电器状态 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end end end end local function LoopTimer(param) if RelayState1 ~= pio.pin.getval(RelayPin1In) then--继电器状态变化,发送继电器状态 RelayState1 = pio.pin.getval(RelayPin1In) JsonTable["data"] = "switch" JsonTable["bit"] = "1" JsonTable["status"] = pio.pin.getval(RelayPin1In) --继电器状态 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end if RelayState2 ~= pio.pin.getval(RelayPin2In) then--继电器状态变化,发送继电器状态 RelayState2 = pio.pin.getval(RelayPin2In) JsonTable["data"] = "switch" JsonTable["bit"] = "2" JsonTable["status"] = pio.pin.getval(RelayPin2In) --继电器状态 mqttOutMsg.insertMsg(json.encode(JsonTable),1) JsonTable = {} end end sys.timerLoopStart(LoopTimer,1) --- MQTT客户端数据接收处理 -- @param mqttClient,MQTT客户端对象 -- @return 处理成功返回true,处理出错返回false -- @usage mqttInMsg.proc(mqttClient) function proc(mqttClient) local result,data while true do result,data = mqttClient:receive(2000) --接收到数据 if result then local jsondata,result,errinfo = json.decode(data.payload)--判断是不是json --dup,topic,id,payload,qos,retain if result and type(jsondata)=="table" then -- 是json数据 if jsondata["data"] ~= nil and jsondata["data"] =="switch" then Relay(jsondata) --处理继电器 end else --非JSON数据 end uart.write(1, data.payload) --串口输出接收的数据 --如果mqttOutMsg中有等待发送的数据,则立即退出本循环 if mqttOutMsg.waitForSend() then return true end else break end end return result or data=="timeout" end
测试
打开MQTT调试助手
提示:设备的IMEI可看自己模块上的
订阅的主题: device/设备的imei号
发布的主题: user/设备的imei号
控制两路继电器吸合
{"data":"switch","bit":"1&2","status":"1&1"}
控制两路继电器断开
{"data":"switch","bit":"1&2","status":"0&0"}