概述

CFIOT内置了丰富的API接口,以模块的形式类聚这些API接口,并导入到内置的LUA虚拟机,供用户的LUA脚本调用,用户可使用CFIOT云端通讯协议远程更新LUA脚本和管理虚拟机,如关闭、启动虚拟机,以及清除脚本等操作。

CFIOT支持多个LUA虚拟机并行运行,充分发挥多核CPU并行计算优势,虚拟机个数由用户的LUA脚本目录数决定,虚拟机之间可以相互通信。

CFIOT目前提供了json、basic、mqtt、hardware、websocket、media等LUA模块,基本满足用户业务逻辑开发要求,可根据用户需求定制特定LUA模块。

LUA语言

Lua 是一种轻量小巧的脚本语言, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

  • 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
  • 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
  • 其它特性:
    • 支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
    • 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
    • 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
    • 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。

Lua 教程:https://www.runoob.com/lua/lua-tutorial.html

LUA脚本目录

对于复杂的业务逻辑,我们建议用户的LUA脚本文件组织到不同的目录下,可以解耦和充分利用CPU计算资源,一个目录下可以存放多个后缀为.lua的脚本,有且仅有一个main.lua文件,main.lua是启动脚本,CFIOT内置的LUA虚拟机管理器,会为每一个目录创建LUA虚拟机,并首先启动main.lua这个脚本。

DEMO程序

我们提供了一个DEMO程序,包含两个目录app1和app2,分别存放一个main.lua文件。

app1下main.go

json = require("json")
basic=require("basic")
mqtt=require("mqtt")
hardware=require("hardware")
websocket=require("websocket")
media=require("media")
local Debug=true
local Timer1_data={count=0,name="Timer1"}
local Timer2_data={count=0,name="Timer2"}
local Gps_data={Longitude=0,Latitude=0,N_S="",E_W="",Speed=0,Direction=0,Mode="",DateTime=""}
local Parameters={}
local LuaVMName=this().LuaVMName--当前虚拟机的名称
function testWebsocket()--Websocket测试local websocket_OnMessage = function(msg)--消息处理函数local msgObj=json.decode(msg)local channel=msgObj.channelif channel~=nilthenlocal DeviceNo=msgObj.DeviceNolocal Data=msgObj.Datalocal info=channel..DeviceNo..json.encode(Data)websocket.SendMessage(info)    endendwebsocket.SetOnMessageHandler(LuaVMName,websocket_OnMessage)--设置消息处理回调函数websocket.SendMessage("testWebsocket")
end
function testMQTT()--MQTT测试if mqtt.WaitMQTTClientReady()--等待mqtt主通道准备好thenlocal MQTTSettings=mqtt.GetMQTTSettings()--获取MQTT参数设置mqtt.Publish(MQTTSettings.PublishTopic,0,false,json.encode(MQTTSettings))--采用默认发布主题推送mqtt参数mqtt.AddSubscribeTopic("CloudEmbedded/testlua")--订阅mqtt主题mqtt.AddSubscribeTopic("CloudEmbedded/testlua1")local mqtt_OnMessage = function(msg)--消息处理函数info=msg.Toppic .. ":" .. msg.Payloadmqtt.Publish("CloudEmbedded/lua/print",0,false,info)if (msg.Toppic=="CloudEmbedded/testlua1")thenmqtt.DeleteSubscribeTopic("CloudEmbedded/testlua1")--删除订阅主题end endmqtt.SetOnMessageHandler(LuaVMName,mqtt_OnMessage)--设置消息处理回调函数mqtt.Publish("CloudEmbedded/test123",0,false,"test")end
endfunction testJson()--json测试--[====[  json相关函数》json字符串转tablejson.decode(str)》table转json字符串json.encode(obj)]====]local FirmwareInfoStr=basic.GetFirmwareInfo()mqtt.Publish("CloudEmbedded/lua/print",0,false, FirmwareInfoStr)basic.print(FirmwareInfoStr,Debug)--打印固件信息FirmwareInfo=json.decode(FirmwareInfoStr)local Revisionstr=FirmwareInfo.Revision--固件版本号local ModuleState=FirmwareInfo.ModuleState--模块状态local IMEIstr=ModuleState.IMEI--模块序列号local CCIDstr=ModuleState.CCID--sim卡标识local CSQstr=ModuleState.CSQ--信号强度local CSQtimestr=ModuleState.CSQtime--信号时间local data={IMEI=IMEIstr,CCID=CCIDstr,CSQ=CSQstr,CSQtime=CSQtimestr,Revision=Revisionstr}mqtt.Publish("CloudEmbedded/lua/print",0,false, json.encode(data))
end
function testTimer()--定时器测试--[====[  定时器相关函数》增加定时器器AddTimer(name,Interval,Handler)name:定时器名字Interval:定时器间隔Handler:定时器执行函数》删除定时器DeleteTimer(name)》检测定时器是否存在TimerExist(name)》启动全部定时器StartTimer()》停止所有定时器StopTimer()注意:增加定时器器会自动执行StartTimer(),删除最后一个定时器后自动执行StopTimer()]====]--增加一个2秒间隔的定时器Timer1basic.AddTimer(LuaVMName,"Timer1",2000,function()Timer1_data.count=Timer1_data.count+1mqtt.Publish("CloudEmbedded/lua/print",0,false, json.encode(Timer1_data))end)--增加一个5秒间隔的定时器Timer2local Timer2=function()Timer2_data.count=Timer2_data.count+1mqtt.Publish("CloudEmbedded/lua/print",0,false,json.encode(Timer2_data))endbasic.AddTimer(LuaVMName,"Timer2",5000,Timer2)--增加一个1秒间隔的定时器deleteTimerbasic.AddTimer(LuaVMName,"deleteTimer",1000,function()if (Timer1_data.count>=10)thenTimer1_data.count=0basic.DeleteTimer(LuaVMName,"Timer1")mqtt.Publish("CloudEmbedded/lua/print",0,false, "Delete Timer1")endif (Timer2_data.count>=10)thenTimer2_data.count=0basic.DeleteTimer(LuaVMName,"Timer2")mqtt.Publish("CloudEmbedded/lua/print",0,false, "Delete Timer2")endif (not basic.TimerExist(LuaVMName,"Timer1") and not basic.TimerExist(LuaVMName,"Timer2"))thenbasic.DeleteTimer(LuaVMName,"deleteTimer")mqtt.Publish("CloudEmbedded/lua/print",0,false, "The timers are all deleted")endend)
end
function testHardware()--测试硬件--[====[  》发送AT指令SendAt(cmd,Formatter,Timeout)cmd:AT指令内容Formatter:格式化标签,将AT响应内容格式化,如果为空,则返回原始数据,需要手动编写格式化函数Timeout:AT响应内容超时时间,单位毫秒,连续响应数据超时返回》发送字符短信SendSMS(No,Content)No:短信号码Content:短信内容》设置短信处理回调函数SetOnSMSHandler(fn)》设置gps处理回调函数SetOnGPSHandler(fn)]====]mqtt.Publish("CloudEmbedded/lua/print",0,false, "testHardware")local atResponseStr=hardware.SendAt("at+cgsn\r","",100)local Revisionstr=hardware.SendAt("ati\r","Revision",100)local IMEIstr=hardware.SendAt("at+cgsn\r","imei",100)local CCIDstr=hardware.SendAt("at+qccid\r","ccid",100)local CSQstr=hardware.SendAt("at+csq\r","CSQ",100)local data={IMEI=IMEIstr,CCID=CCIDstr,CSQ=CSQstr,cgsnResponse=atResponseStr,Revision=Revisionstr}mqtt.Publish("CloudEmbedded/lua/print",0,false, json.encode(data))hardware.SendSMS("15395016712","send sms")local LteModule_OnSMS = function(msg)--短信处理函数local info="sms:" .. msg.No .. ":" .. msg.Contentmqtt.Publish("CloudEmbedded/lua/print",0,false,info)endhardware.SetOnSMSHandler(LuaVMName,LteModule_OnSMS)--设置短信处理回调函数local GPSModular_OnGPS = function(data)--gps处理函数Gps_data.Longitude=data.LongitudeGps_data.Latitude=data.LatitudeGps_data.N_S=data.N_SGps_data.E_W=data.E_WGps_data.Speed=data.SpeedGps_data.Direction=data.DirectionGps_data.Mode=data.ModeGps_data.DateTime=data.DateTimemqtt.Publish("CloudEmbedded/lua/print",0,false,json.encode(Gps_data))endhardware.SetOnGPSHandler(LuaVMName,GPSModular_OnGPS)--设置gps处理回调函数hardware.SetSerialDataRoute(1)--设置串口数据路由,0:服务器,1:lua虚拟机local Hardware_OnEvent= function(data)--硬件事件回调函数local portName=data.portNamelocal EventName=data.EventNamelocal Message=data.Messagelocal info=portName ..":".. EventName .. ":" .. Messagemqtt.Publish("CloudEmbedded/lua/print",0,false,info)endhardware.SetHardwareOnEvent(LuaVMName,Hardware_OnEvent)local Serial1_OnData= function(data)--串口1数据处理函数--16进程字符数组 data.hexArray--byte数组data.byteArray--local info="Serial1_OnData:" .. data.hexprint(data.hexArray,data.byteArray)--mqtt.Publish("CloudEmbedded/lua/print",0,false,info)endhardware.SetSerialWriteDataSleep("Serial1",30)--设置串口发送数据包后延迟时间,单位毫秒,延时是在CFIOT固件中执行,防止粘包hardware.SetSerialOnDataHandler(LuaVMName,"Serial1",Serial1_OnData)hardware.SerialOpen("Serial1",9600,8,"None",1)--打开串口1hardware.SerialWriteData("Serial1","01 05 00 00 FF 00 8C 3A")hardware.SerialWriteData("Serial1","01 05 00 00 00 00 CD CA")hardware.SerialWriteDataByte("Serial1",{0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0X3A})hardware.SerialWriteDataByte("Serial1",{0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0XCA})
end
function testVMMessage()--测试虚拟机收发消息local VM_OnMessage= function(data)--接收其他虚拟机消息函数mqtt.Publish("CloudEmbedded/lua/print",0,false,json.encode(data))endbasic.SetOnMessageHandler(LuaVMName,VM_OnMessage)local msg={Source=LuaVMName,Dst="app2"}basic.SendMessage(LuaVMName,"app2",msg)--给app2虚拟机发消息
end
function testMedia()--测试摄像机,拍照、推流等media.SearchAllIPCamera()--onvif搜索摄像机media.GetIPCameraParameters("")--获取摄像机信息,json字符串media.GetIPCameraState("")--获取摄像机状态信息,json字符串media.Screenshot("007D50117625","SecondStreamProfileToken_640_352","testScreenshot","/Media")--摄像机拍照media.VideoRecording("007D50117625","SecondStreamProfileToken_640_352","testVideoRecording","/Media",10,"flv")media.StartPushStream("007D50117625","SecondStreamProfileToken_640_352","rtmp://tx.direct.huya.com/huyalive/1199558764847-1199558764847-6888343667394952147-2399117653150-10057-A-1603817515-1?seq=1605155499051&type=simple","","","")
end
function Start()--[[basic.Sleep()延时函数请慎用,不应该出现在定时器、回调函数里,只能用于初始化阶段]]basic.SetDebug(LuaVMName,Debug)--当开启Debug模式,虚拟机运行异常信息会上行到主要上传通道basic.SetWatchdogTimeout(LuaVMName,300)--设置看门狗超时,单位秒,>=20,喂狗信号超时会导致虚拟机重启--增加一个2秒间隔的定时器MainTimer,可以作为主控制线程basic.AddTimer(LuaVMName,"MainTimer",2000,function()basic.Watchdog(LuaVMName,1)--发送看门狗信号end)Parameters=json.decode(basic.GetParameters())--固件参数if(Parameters.ServerSettingsData.ProtocolType==3)--判断上传通道的协议类型,后续上传数据要根据这个协议类型选择相应的通道thentestWebsocket()elseif(Parameters.ServerSettingsData.ProtocolType==4)thentestMQTT()elseendbasic.Sleep(30000)--延时60秒testJson()testTimer()basic.Sleep(60000)--延时60秒testHardware()testVMMessage()testMedia()
endStart()

app2下main.lua

json = require("json")
basic=require("basic")
mqtt=require("mqtt")
hardware=require("hardware")
local Debug=true
local LuaVMName=this().LuaVMName--当前虚拟机的名称function Start()basic.SetDebug(LuaVMName,Debug)--当开启Debug模式,虚拟机运行异常信息会上行到主要上传通道basic.SetWatchdogTimeout(LuaVMName,300)--设置看门狗超时,单位秒,>=20,喂狗信号超时会导致虚拟机重启--增加一个2秒间隔的定时器MainTimer,可以作为主控制线程basic.AddTimer(LuaVMName,"MainTimer",2000,function()basic.Watchdog(LuaVMName,1)--发送看门狗信号end)mqtt.WaitMQTTClientReady()--等待mqtt主通道准备好--测试虚拟机收消息local VM_OnMessage= function(data)--接收其他虚拟机消息函数mqtt.Publish("CloudEmbedded/lua/print",0,false,json.encode(data))local msg={Source=LuaVMName,Dst="app1"}basic.SendMessage(LuaVMName,"app1",msg)--给app1虚拟机发消息endbasic.SetOnMessageHandler(LuaVMName,VM_OnMessage)
endStart()

开发步骤

首先我们要使用云端通讯协议来控制CF-IOT设备下载您的LUA脚本固件,并启动LUA虚拟机运行脚本,LUA脚本固件应使用ZIP压缩包格式。

为了方便调试,我们将设备协议类型设置为MQTT,采用一台免费并可网页调试的MQTT服务器来完成相关功能测试。

MQTT调试网址:http://mqtt.p2hp.com/websocket/

CF-IOT云端通讯协议调试:https://blog.csdn.net/c1991786907/article/details/109570972

在MQTT调试页面,设置好订阅主题和发布主题,首先下发开发者密钥,鉴权成功后,我们就可以使用LUA虚拟机相关协议来调试和运行LUA脚本。

将以上demo程序压缩为zip格式文件,文件名可以随意,压缩包内目录结构如下:

下载LUA脚本

{"channel": "LuaVM_Upgrading","DeviceNo": "864977047765106","Data": {"URL": "http://www.***/lua.zip"}
}

下载结果会以事件上行

{"channel": "LuaVM_onEvent","DeviceNo": "862607059076223","Data": {"EventName": "LuaVM_Upgrading_Success","Message": ""}
}

启动虚拟机

{"channel": "LuaVM_Load","DeviceNo": "862607059076223","Data": null
}

停止虚拟机

{"channel": "LuaVM_Stop","DeviceNo": "862607059076223","Data": null
}

脚本清除

{"channel": "LuaVM_Clear","DeviceNo": "862607059076223","Data": null
}

CF-IOT之LUA语言开发相关推荐

  1. lua语言开发esp8266接入巴法云,mqtt和tcp协议

    第一步,lua语言开发环境配置 下载安装java环境,下载地址:点击下载 选择windows版本下载安装即可,如图所示: 下载开发环境包: 下载地址:点击下载 esp8266串口驱动:点击下载 下载后 ...

  2. lua 给userdata设置元表_提高Lua语言开发效率的简单方法

    概述 首先,lua是一门高效的(efficient).轻量级(lightweight)的嵌入式脚本语言(embeddable scripting language),这是它的官方网站的标语. 其次,l ...

  3. android lua 开发环境搭建,使用 lua 语言开发Android应用

    做移动端开发,做蛋疼的就是不能动态发版,不能像 web 那样发版立即全部用户生效,然而 lua语言 为其提供了可能性.使用 lua 来构建跨平台原生应用有许多好处,比如 lua 语言简洁高效,可移植性 ...

  4. 3D游戏精灵-兔子脚本 (lua语言开发,xfun平台)最新版

    require "XLuaBase" --{{XFUN EVENT     --在此处添加事件 X_ON_LUAINIT(OnItemInit)   X_ONSPRITECLOSE ...

  5. 3D游戏精灵-蝴蝶脚本 (lua语言开发,xfun平台)

    require "XLuaBase" --{{XFUN EVENT     --在此处添加事件 X_ON_LUAINIT(OnItemInit) X_ONCURANIMATEEND ...

  6. 用Nginx+Lua(OpenResty)开发高性能Web应用

    在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Nginx开 ...

  7. 使用Nginx+Lua(OpenResty)开发高性能Web应用

    在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Nginx开 ...

  8. 「京东开涛」使用Nginx+Lua(OpenResty)开发高性能Web应用

    几乎所有互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Ngi ...

  9. slua 是c语言开发的吗,初学者必备文档:LUA新手快速学习笔记

    LUA程序设计语言 是一个简洁.轻量.可扩展的脚本语言.LUA读作/'lua/(噜啊),是葡萄牙语中"Luna"(月亮)的意思. LUA的目标是成为一个很容易嵌入其它语言中使用的语 ...

最新文章

  1. 小程序之 转发/分享
  2. ASP.NET MVC (三、表单与文件上传)
  3. anacondapythonyolo3配置_Windows anaconda 运行yolov3
  4. MySQL 删除视图
  5. mysql cast报错_mysql数据库cast
  6. anaconda版本选择_Python环境搭建之Anaconda快速学习
  7. PYQT5+PYTHON杂谈
  8. 关于jQuery获取html标签自定义属性值或data值
  9. QQ音乐下载的flac文件转码mp3文件
  10. STM32G070用HAL库与AT24C08通讯
  11. 微信小程序开发之视频video组件报错:渲染层网络层错误
  12. Exception in thread main java.lang.OutOfMemoryError: Java heap space(Java堆空间内存溢出)解决方法...
  13. LaTeX中文字体设置
  14. 终于来了!腾讯数据分析证书!
  15. 0x7fffffff解析
  16. python3中 os.path.realpath(__file__) 的使用
  17. Element el-icon 图标组件详解
  18. ant编译错误:不再支持源选项 1.5,请使用 1.6 或更高版本。
  19. lr cc 2019 mac版激活教程
  20. PROFIBUS总线光纤模块在矿场设备的应用案例

热门文章

  1. 深度学习 Fine-tune 技巧
  2. 自动驾驶决策控制及运动规划史上最详细最接地气总览现状!
  3. 哈希冲突的常见解决方式
  4. 基于异质网络的武器装备体系结构抗毁性研究 赵丹玲 主功能程序
  5. centos服务器版安装selenium
  6. 江苏农牧科技职业学院考计算机,江苏农牧科技职业学院2020年提前招生简章
  7. 染色基础知识(三)——用什么染?
  8. input输入框输入时对特殊字符进行检查,禁止特殊字符输入
  9. 啥是搜索引擎优化?SEO优化到底怎么做?
  10. 向便利店老大7-ELEVEN连锁加盟学生意-