应用程序开发

应用程序开发,应用程序开发包括时间同步,信号强度同步,socket通信(数据收发),设计器实现UI开发和手动写实现UI开发会略有不同,不同地方会做相应的说明。 # 时间同步 时间同步实现见service_time.lua脚本,这里创建了一个task,500m获取一次时间,然后通过sys.publish()发布SYSTEM_CHANGE_TIME消息,通知UI界面去更新时间。 ```lua -- --bTimeSyned :时间是否已经成功同步过 local bTimeSyned=false --注册基站时间同步的URC消息处理函数 ril.regUrc("+NITZ", function() log.info("cell.timeSync") bTimeSyned = true end) local weekTable={"日","一","二","三","四","五","六"} sys.taskInit(function() while not bTimeSyned do sys.wait(50) end while true do local tClock = os.date("*t") local date=string.format("%d/%02d/%02d 周%s %02d:%02d:%02d",tClock.year,tClock.month,tClock.day,weekTable[tClock.wday],tClock.hour,tClock.min,tClock.sec) -- print(date) sys.publish("SYSTEM_CHANGE_TIME",date) sys.wait(500) end end) ``` 更新时间的处理,设计器实现UI开发是放在UiHandle.lua脚本中实现,手动写实现UI开发是放在main.lua脚本中实现,通过sys.subscribe()订阅SYSTEM_CHANGE_TIME消息,通过lvgl.label_set_text()来设置时间对应的lable内容来更新时间。 设计器实现UI开发UiHandle.lua脚本中对应代码如下: ```lua sys.subscribe("SYSTEM_CHANGE_TIME",function(date) lvgl.label_set_text(ScreenA.LvglLabel2.self, date) end) ``` 手动写实现UI开发main.lua脚本中对应代码如下: ```lua sys.subscribe("SYSTEM_CHANGE_TIME",function(date) lvgl.label_set_text(dateLabel,"#FFFFFF "..date) end) ``` # 信号强度同步 时间同步实现见service_sim.lua脚本,这里创建了一个task,1000m获取一次信号强度,如果信号有变化然后通过sys.publish()发布RSSI_CHANGE消息,通知UI界面去更新信号强度。信号有变化的情况下也会做对应的操作。这里消息上报的内容是信号对应的图片路径。 ```lua function RSSIchange() local Rssi=0 sys.taskInit(function() while true do local s=net.getRssi() if s~=Rssi then Rssi=s sys.publish("RSSI_CHANGE","/lua/sin_icon_"..math.ceil((5/31)*Rssi)..".png") end sys.wait(1000) end end) end sys.subscribe("NET_STATE_REGISTERED",RSSIchange) ``` 更新信号强度的处理,设计器实现UI开发是放在UiHandle.lua脚本中实现,手动写实现UI开发是放在main.lua脚本中实现,通过sys.subscribe()订阅RSSI_CHANGE消息,通过lvgl.img_set_src()来设置信号强度对应的img图片来更新信号强度。 设计器实现UI开发UiHandle.lua脚本中对应代码如下: ```lua sys.subscribe("RSSI_CHANGE",function(img) lvgl.img_set_src(ScreenA.LvglImg6.self,img) end) ``` 手动写实现UI开发main.lua脚本中对应代码如下: ```lua sys.subscribe("RSSI_CHANGE",function(img) lvgl.img_set_src(signImg,img) ``` # socket通信 socket通信,主要功能是实现数据的收发,代码在longConnection文件夹下面,包含有3个脚本文件,分别处理socket连接,数据接收,数据发送。 ## socket连接 socketTask.lua创建socket客户端任务,这里通过sys.waitUntil("CONNECT_IND")一直等待CONNECT_IND消息,CONNECT_IND消息是点击连接按钮后发布的,等到CONNECT_IND后,等待网络就绪后,会创建并连接服务器,连接成功后,循环处理接收和发送的数据。 ```lua sys.taskInit( function() while true do sys.waitUntil("CONNECT_IND") disconnect = nil log.info("UI @@ CONNECT_IND",_G.ipProtocol,_G.ipAddress,_G.ipPort) if not socket.isReady() then --等待网络环境准备就绪,超时时间是5分钟 sys.waitUntil("IP_READY_IND",300000) end if socket.isReady() then --创建一个socket tcp/udp客户端 local socketClient if _G.ipProtocol == "udp" then socketClient = socket.udp() else socketClient = socket.tcp() end --阻塞执行socket connect动作,直至成功 if socketClient:connect(_G.ipAddress,_G.ipPort) then ready = true socketOutMsg.init() --循环处理接收和发送的数据 while true do if not socketInMsg.proc(socketClient) then log.error("socketTask.socketInMsg.proc error") break end if not socketOutMsg.proc(socketClient) then log.error("socketTask.socketOutMsg proc error") break end end socketOutMsg.unInit() ready = false else log.error("socketTask connect fail") end --断开socket连接 socketClient:close() sys.wait(5000) else --进入飞行模式,20秒之后,退出飞行模式 net.switchFly(true) sys.wait(20000) net.switchFly(false) end end end ) ``` 设计器实现UI开发发布CONNECT_IND在UiHandle.lua脚本中实现,连接按钮的消息回调函数,对应代码如下: ```lua function Connect_CLICKED() ------------USER CODE DATA-------------- _G.BEEP() log.info("Connect_CLICKED",_G.fragmentConnect) if _G.fragmentConnect then lvgl.style_set_value_str(Style_LvglButton3_1, lvgl.STATE_DEFAULT, "断开连接") _G.fragmentConnect = false sys.publish("CONNECT_IND") else lvgl.style_set_value_str(Style_LvglButton3_1, lvgl.STATE_DEFAULT, "连接") _G.fragmentConnect=true sys.publish("SOCKET_DISCONNECT_IND") socketOutMsg.sndTest("disconnect") end ------------USER CODE DATA-------------- end ``` 按键消息回调的注册是在UI设计器设计的时候,通过添加按钮点击事件函数名称,自动生成后放在UiDesign.lua脚本中的。 ```lua --This is callBack function of ScreenA.LvglButton3 local handleLvglButton3 = function(obj, e) ScreenA.LvglButton3.cb(e) ScreenA.LvglButton3.cb = function(e) if (e == lvgl.EVENT_CLICKED)then Connect_CLICKED() end end end lvgl.obj_set_event_cb(ScreenA.LvglButton3.self, handleLvglButton3) ``` 手动写实现UI开发发布CONNECT_IND在fragment_systemSet.lua脚本中实现,连接按钮的消息回调函数,对应代码如下: ```lua event_handler_btn = function(obj, event) if event == lvgl.EVENT_CLICKED then _G.BEEP() log.info("UI makeQRbtn",_G.fragmentConnect) if _G.fragmentConnect then lvgl.label_set_text(_G.connLabel, "#FFFFFF 断开连接") _G.fragmentConnect = false sys.publish("CONNECT_IND") else lvgl.label_set_text(_G.connLabel, "#FFFFFF 连接") _G.fragmentConnect=true sys.publish("SOCKET_DISCONNECT_IND") socketOutMsg.sndTest("disconnect") end end end lvgl.obj_set_event_cb(btn, event_handler_btn) ``` ## 数据接收 在socketInMsg.lua脚本里,处理数据的接收。数据接收时通过socketClient:recv()来接收数据,接收到的数据通过sys.publish("RECV_DATA_IND")发布消息给UI去更新接收的数据。 ```lua function proc(socketClient) local result,data while true do result,data = socketClient:recv(60000,"APP_SOCKET_SEND_DATA") --接收到数据 if result then log.info("socketInMsg.proc",data) _G.recvData = data sys.publish("RECV_DATA_IND") else break end end return result or data=="timeout" or data=="APP_SOCKET_SEND_DATA" end ``` 接收数据的更新,设计器实现UI开发是放在UiHandle.lua脚本中实现,手动写实现UI开发是放在fragment_systemSocket.lua脚本中实现,通过sys.subscribe()订阅RECV_DATA_IND消息,通过lvgl.label_set_text()来设置时间对应的lable内容来更新接收到的数据和数据长度。 设计器实现UI开发UiHandle.lua脚本中对应代码如下: ```lua --接收到数据 function recvDataInd() --if RecvLabel then lvgl.label_set_text(RecvLabel, _G.recvData) end --if RecvLabel then lvgl.label_set_text(RecvLenLabel, "已接收"..#_G.recvData.."个字节")end log.info("recvDataInd",_G.recvData,#_G.recvData) lvgl.label_set_text(ScreenA.LvglLabel10.self, _G.recvData) lvgl.label_set_text(ScreenA.LvglLabel9.self, "已接收"..#_G.recvData.."个字节") end sys.subscribe("RECV_DATA_IND",recvDataInd) ``` 手动写实现UI开发fragment_systemSocket.lua脚本中对应代码如下: ```lua function recvDataInd() if RecvLabel then lvgl.label_set_text(RecvLabel, _G.recvData) end if RecvLabel then lvgl.label_set_text(RecvLenLabel, "#FFFFFE 已接收"..#_G.recvData.."个字节")end end sys.subscribe("RECV_DATA_IND",recvDataInd) ``` ## 数据发送 在socketOutMsg.lua脚本里,处理数据的发送。数据发送是先把发送的数据放到msgQueue消息队列,发送的时候从消息队列中取出后在通过调用socketClient:send()去发送。 ```lua --发送数据放到消息队列 local function insertMsg(data,user) table.insert(msgQueue,{data=data,user=user}) sys.publish("APP_SOCKET_SEND_DATA") end --数据发送处理 function proc(socketClient) while #msgQueue>0 do local outMsg = table.remove(msgQueue,1) local result = socketClient:send(outMsg.data) if outMsg.user and outMsg.user.cb then outMsg.user.cb(result,outMsg.user.para) end if disconnect and outMsg.data == "disconnect\r\n" then log.info("@@ outMsg proc disconnect") return end if not result then return end end return true end ``` # 相关参考文档 [SOCKET(套接字)](https://easydoc.net/doc/50207163/vRKgmDaY/TCjrYW25) [sys API](https://doc.openluat.com/wiki/21?wiki_page_id=2295)