Toggle navigation
首页
(current)
问答
文章
话题
商城
登录
注册
使用Lua脚本连接华为云物联网服务
华为云
使用Lua脚本连接华为云物联网服务
> 本教程代码在2G与4G模块上均可使用 如需查看AT命令方式连接方法,请查看:[教你用Air720 模块通过AT指令以MQTTS方式连接华为云(上篇)](http://oldask.openluat.com/article/902) # 准备工作 打开华为云物联网后台(如果无账号,需要注册): [OceanConnect开发中心](https://iot-dev.huaweicloud.com/#/developer-overview) 新建项目,项目名称和行业按需求填写: ![](/static/editormd/php/../uploads/5_18953.jpg) 记录下应用id与密钥,进入项目: ![](/static/editormd/php/../uploads/5_56927.jpg) ``` 应用ID ackQwtMh2hnjQzMoJE4fTc3ZtVoa 应用密钥 4BdXiylWLCFHHlLin_fwzgwAJfoa ``` 点`产品开发`,`新建产品`,内容按需求填写,注意`接入应用层协议类型`要选择`MQTT`: ![](/static/editormd/php/../uploads/5_16742.jpg) ![](/static/editormd/php/../uploads/5_23971.jpg) 给这个产品添加Profile定义: ![](/static/editormd/php/../uploads/5_78650.jpg) 按下图新建属性: ![](/static/editormd/php/../uploads/5_37611.jpg) 按照下图,再添加两个命令(string长度图里应为4): ![](/static/editormd/php/../uploads/5_30386.jpg) ![](/static/editormd/php/../uploads/5_71272.jpg) 保存设置。 左侧`设备管理`,`添加真实设备`,注意类型要选直连: ![](/static/editormd/php/../uploads/5_19642.jpg) ![](/static/editormd/php/../uploads/5_28688.jpg) ![](/static/editormd/php/../uploads/5_64676.jpg) 设备信息记下来,后面会用到: ``` 设备ID: 355d812e-ad55-47a5-b811-760f760b63a1 密钥: 10f0a44d66a582b3ddee ``` # 模块连接实现 > 模块连接需要使用MQTT+SSL的方式,具体鉴权协议可以参考华为云的文档:[MQTT CONNECT连接鉴权](https://support.huaweicloud.com/api-IoT/iot_06_3009.html) 首先需要注意,由于上面定义了int类型,并且在华为云的int类型会带小数点的尾缀,所以我们需要使用SSL+FLOAT的固件,并且保证固件版本大于0034以确保可以使用HMACSHA256计算函数 首先准备一下mqtt的证书文件,保存下面的文本内容为`hw.crt`: ```crt -----BEGIN CERTIFICATE----- MIID4DCCAsigAwIBAgIJAK97nNS67HRvMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV BAYTAkNOMQswCQYDVQQIEwJHRDELMAkGA1UEBxMCU1oxDzANBgNVBAoTBkh1YXdl aTELMAkGA1UECxMCQ04xDDAKBgNVBAMTA0lPVDAeFw0xNjA1MDQxMjE3MjdaFw0y NjA1MDIxMjE3MjdaMFMxCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJHRDELMAkGA1UE BxMCU1oxDzANBgNVBAoTBkh1YXdlaTELMAkGA1UECxMCQ04xDDAKBgNVBAMTA0lP VDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJxM9fwkwvxeILpkvoAM Gdqq3x0G9o445F6Shg3I0xmmzu9Of8wYuW3c4jtQ/6zscuIGyWf06ke1z//AVZ/o dp8LkuFbBbDXR5swjUJ6z15b6yaYH614Ty/d6DrCM+RaU+FWmxmOon9W/VELu2BB NXDQHJBSbWrLNGnZA2erk4JSMp7RhHrZ0QaNtT4HhIczFYtQ2lYF+sQJpQMrjoRn dSV9WB872Ja4DgcISU1+wuWLmS/NKjIvOWW1upS79yu2I4Rxos2mFy9xxz311rGC Z3X65ejFNzCUrNgf6NEP1N7wB9hUu7u50aA+/56D7EgjeI0gpFytC+a4f6JCPVWI Lr0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUcGqy59oawLEgMl21//7F5RyABpwwgYMG A1UdIwR8MHqAFHBqsufaGsCxIDJdtf/+xeUcgAacoVekVTBTMQswCQYDVQQGEwJD TjELMAkGA1UECBMCR0QxCzAJBgNVBAcTAlNaMQ8wDQYDVQQKEwZIdWF3ZWkxCzAJ BgNVBAsTAkNOMQwwCgYDVQQDEwNJT1SCCQCve5zUuux0bzAMBgNVHRMEBTADAQH/ MA0GCSqGSIb3DQEBCwUAA4IBAQBgv2PQn66gRMbGJMSYS48GIFqpCo783TUTePNS tV8G1MIiQCpYNdk2wNw/iFjoLRkdx4va6jgceht5iX6SdjpoQF7y5qVDVrScQmsP U95IFcOkZJCNtOpUXdT+a3N+NlpxiScyIOtSrQnDFixWMCJQwEfg8j74qO96UvDA FuTCocOouER3ZZjQ8MEsMMquNEvMHJkMRX11L5Rxo1pc6J/EMWW5scK2rC0Hg91a Lod6aezh2K7KleC0V5ZlIuEvFoBc7bCwcBSAKA3BnQveJ8nEu9pbuBsVAjHOroVb 8/bL5retJigmAN2GIyFv39TFXIySw+lW0wlp+iSPxO9s9J+t -----END CERTIFICATE----- ``` 新建`main.lua`: ```lua PROJECT = "HWMQTT" VERSION = "1.0.0" --加载日志功能模块,并且设置日志输出等级 require "log" LOG_LEVEL = log.LOGLEVEL_TRACE require "sys" require "net" --每1分钟查询一次GSM信号强度 --每1分钟查询一次基站信息 net.startQueryAll(60000, 60000) --加载硬件看门狗功能模块 --require "wdt" --wdt.setup(pio.P0_30, pio.P0_31) --加载网络指示灯功能模块 --require "netLed" --netLed.setup(true,pio.P1_1) --加载MQTT功能测试模块 require "mqttTask" --启动系统框架 sys.init(0, 0) sys.run() ``` 新建`mqttTask.lua`: ```lua require "mqtt" module(..., package.seeall) -- 这里请填写华为云后台对接信息所展示的设备信息MQTT接入方式信息 local host, port = "49.4.93.24", 8883 --这里设置设备的device id和密钥,之前新建设备时得到的两个字符串 --实际使用中,这两个值可以存在SN中,在生产时一个个烧录进去 local device = "355d812e-ad55-47a5-b811-760f760b63a1" local secret = "10f0a44d66a582b3ddee" --同步NTP时间,因为鉴权需要用到UTC时间 require"ntp" local function ntbcb(r) if r then sys.publish("NTP_OK")--时间同步完成后,发送命令,开始mqtt连接 else ntp.timeSync(nil,ntbcb) end end ntp.timeSync(nil,ntbcb)--开始同步时间任务 --此处参照华为云文档,生成连接时使用的密钥 local function keyGenerate(key) local clk = os.date("*t",os.time()-3600*8)--获取UTC时间的table local timeStr = string.format("%02d%02d%02d%02d",clk.year,clk.month,clk.day,clk.hour)--时间戳 local result = crypto.hmac_sha256(key,timeStr):lower() log.info("keyGenerate",timeStr,key,result) if crypto.hmac_sha256 then return result else log.error("crypto.hmac_sha256","please update your lod version, higher than 0034!") rtos.poweroff() end end socket.setSendMode(1) -- 测试MQTT的任务代码 sys.taskInit(function() sys.waitUntil("NTP_OK")--等待时间同步成功 while true do while not socket.isReady() do sys.wait(1000) end local clk = os.date("*t",os.time()-3600*8)--获取UTC时间的table local mqttc = mqtt.client( device.."_0_1_"..string.format("%02d%02d%02d%02d",clk.year,clk.month,clk.day,clk.hour),--时间戳鉴权模式 300, device, keyGenerate(secret)) while not mqttc:connect(host, port, "tcp_ssl",{caCert="hw.crt"}) do sys.wait(2000) end --topic订阅规则详细请见华为云文档:https://support.huaweicloud.com/api-IoT/iot_06_3008.html#ZH-CN_TOPIC_0172230104 if mqttc:subscribe("/huawei/v1/devices/"..device.."/command/json") then while true do local r, data, param = mqttc:receive(120000, "pub_msg") if r then log.info("这是收到了服务器下发的消息:", data.payload or "nil") sys.publish("rev_msg",data.payload)--把收到的数据推送出去 elseif data == "pub_msg" then log.info("这是收到了订阅的消息和参数显示:", param) --topic订阅规则详细请见华为云文档 mqttc:publish("/huawei/v1/devices/"..device.."/data/json", param) elseif data == "timeout" then --等待超时,进行下一轮等待 else break end end end mqttc:disconnect() end end) --接收到mqtt之后,对数据进行处理 sys.subscribe("rev_msg",function(data) local t,r,e = json.decode(data)--解包收到的json数据,具体参考手册:https://support.huaweicloud.com/api-IoT/iot_06_3011.html if r and type(t)=="table" then log.info("receive.msgType",t.msgType)--表示平台下发的请求,固定值“cloudReq” log.info("receive.serviceId",t.serviceId)--设备服务的ID log.info("receive.cmd",t.cmd)--服务的命令名,参见profile的服务命令定义 log.info("receive.mid",t.mid)--2字节无符号的命令id,平台内部分配(范围1-65535),设备命令响应平台时,需要返回该值 if t.cmd == "testcmd" then--匹配上了之前写的cmd名称 log.info("receive.paras.testControl",t.paras.testControl) local clk = os.date("*t",os.time()-3600*8)--获取UTC时间的table --组包回复用的json,具体参考手册:https://support.huaweicloud.com/api-IoT/iot_06_3012.html local reply = { msgType = "deviceRsp",--固定值“deviceRsp”,表示设备的应答消息 mid = t.mid,--2字节无符号的命令ID,根据平台下发命令时的mid返回给平台。建议在消息中携带此参数 errcode = 0,--请求处理的结果码。“0”表示成功。“1”表示失败 body = {--命令的应答,具体字段由profile定义 testReply = "done",--这是之前后台设置的那个 } } sys.publish("pub_msg",json.encode(reply))--上报返回的报文 --组包上报用的json,具体参考手册:https://support.huaweicloud.com/api-IoT/iot_06_3010.html local upload = { msgType = "deviceReq",--表示设备上报数据,固定值“deviceReq” data = {--一组服务的数据(具体结构参考下表ServiceData定义表),当需要上传批量数据时,可在该字段中添加数据 { serviceId = "testServer",--设备服务的ID serviceData = {--一个服务的数据,具体字段在profile里定义 testProperty = t.paras.testControl,--把刚刚下发的东西,上报上去 }, eventTime = string.format("%02d%02d%02d%02d%02d%02dZ",--设备采集数据UTC时间(格式:yyyyMMddTHHmmssZ) clk.year,clk.month,clk.day,clk.hour,clk.min,clk.sec)--时间戳 }, } } sys.publish("pub_msg",json.encode(upload))--上报返回的报文 end else log.info("json.decode error",e) end end) ``` 烧录到设备里,以备测试 # 测试 后台下发数据,模块回复 ![](/static/editormd/php/../uploads/5_10125.jpg)
发表于 2019-07-18 18:44
阅读 ( 4010 )
分类:
默认分类
1 推荐
打赏
收藏
你可能感兴趣的文章
相关问题
2 条评论
请先
登录
后评论
晨旭
菜鸟
20 篇文章
作家榜
»
技术销售Delectate
43 文章
陈夏
26 文章
国梁
24 文章
miuser
21 文章
晨旭
20 文章
朱天华
19 文章
金艺
19 文章
杨奉武
18 文章
×
发送私信
发给:
内容:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!