• 欢迎大家分享资料!前往留言板评论即可!

阿里云影子文件操作指南

合宙 模组资料网 5个月前 (05-15) 80次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

不废话,直接上代码吧

--- 模块功能:阿里云功能测试.
-- 支持数据传输和OTA功能
-- @author openLuat
-- @module aLiYun.testALiYun
-- @license MIT
-- @copyright openLuat
-- @release 2018.04.14

module(...,package.seeall)

require "aLiYun"
require "misc"
require "nvm"


--阿里云华东2站点上创建的产品的ProductKey,用户根据实际值自行修改
--local PRODUCT_KEY = "你自己的产品key"
--采用“一机一密”认证方案除了上面的PRODUCT_KEY外,还需要设备名称和设备密钥
--设备名称使用函数getDeviceName的返回值,默认为设备的IMEI
--设备密钥使用函数getDeviceSecret的返回值,默认为设备的SN
--单体测试时,可以直接修改getDeviceName和getDeviceSecret的返回值
--批量量产时,使用设备的IMEI和SN;合宙生产的模块,都有唯一的IMEI,用户可以在自己的产线批量写入跟IMEI(设备名称)对应的SN(设备密钥)
--或者用户自建一个服务器,设备上报IMEI给服务器,服务器返回对应的设备密钥,然后调用misc.setSn接口写到设备的SN中

local PRODUCT_KEY = "你自己的产品key"
local PRODUCE_SECRET="你自己的产品密钥"
local Shadow_Changed = false
--采用“一型一密”认证方案时打开上面的注释,比“一机一密”认证方式额外提供提供PRODUCE_SECRET,PRODUCE_SECRET的值根据实际值自行修改
--设备请求接入时,云端动态下发该设备的DeviceSecret,DeviceSecret的保存方法默认使用setDeviceSecret将设备的SN替换成DeviceSecret
--之后设备密钥的获取便使用函数getDeviceSecret的返回值,然后使用ProductKey、DeviceName和DeviceSecret进行认证并建立连接。
--请参考126行的aLiYun.setup(PRODUCT_KEY,PRODUCE_SECRET,getDeviceName,getDeviceSecret,setDeviceSecret)去配置参数 

--[[
函数名:getDeviceName
功能  :获取设备名称
参数  :无
返回值:设备名称
]]
local function getDeviceName()
    --默认使用设备的IMEI作为设备名称
    --用户单体测试时,可以在此处直接返回阿里云的iot控制台上注册的设备名称,例如return "868575021150844"
    --return "Air202Test13"
    --return "862991419835241"
    return misc.getImei()
end

--[[
函数名:setDeviceSecret
功能  :修改设备密钥
参数  :设备密钥
返回值:无
]]
local function setDeviceSecret(s)
    --默认使用设备的SN作为设备密钥
    misc.setSn(s)
end


--[[
函数名:getDeviceSecret
功能  :获取设备密钥
参数  :无
返回值:设备密钥
]]
local function getDeviceSecret()
    --默认使用设备的SN作为设备密钥
    --用户单体测试时,可以在此处直接返回阿里云的iot控制台上生成的设备密钥,例如return "y7MTCG6Gk33Ux26bbWSpANl4OaI0bg5Q"
    --return "y7MTCG6Gk33Ux26bbWSpANl4OaI0bg5Q"
    return misc.getSn()
end

--阿里云客户端是否处于连接状态
sConnected = false

--[[
函数名:pubqos1testackcb
功能  :发布1条qos为1的消息后收到PUBACK的回调函数
参数  :
        usertag:调用mqttclient:publish时传入的usertag
        result:true表示发布成功,false或者nil表示失败
返回值:无
]]
local function publishTestCb(result,para)
    log.info("myALiYun.publishTestCb",result,para)
end

--发布一条shadow更新消息
function updateShadow(desired)
    if sConnected then
        desired["rssi"] = net.getRssi()
        desired["PowerSwitch"] = nvm.get("PowerSwitch")
        local jdata = json.encode(desired)
        _G.shadow_version = _G.shadow_version + 1
        local resp = "{\"method\":\"update\",\"state\": {\"reported\":" .. jdata .."},\"version\":".._G.shadow_version.."}"
        aLiYun.publish("/shadow/update/"..PRODUCT_KEY.."/"..getDeviceName(), resp, 1,publishTestCb, resp)
    else
        log.info("sorry, sConnected=false")
    end
end



---数据接收的处理函数
-- @string topic,UTF8编码的消息主题
-- @number qos,消息质量等级
-- @string payload,原始编码的消息负载
local function rcvCbFnc(topic,qos,payload)
    log.info("myALiYun.rcvCbFnc",topic,qos,payload)
    if topic == "/shadow/get/"..PRODUCT_KEY.."/"..getDeviceName() then
        local shadow,result,errinfo = json.decode(payload)
        if result then
            log.info("Shadow Method=" .. shadow["method"])
            if shadow["version"] ~= nil then
                _G.shadow_version = shadow["version"]
                log.info("Shadow Version = " .. _G.shadow_version)
            end
            local desired = nil
            if shadow["method"] == "reply" and shadow["payload"]["state"] ~= nil and shadow["payload"]["state"]["desired"] ~= nil then
                return
            end
            if shadow["method"] == "control" and shadow["payload"]["state"] ~= nil and shadow["payload"]["state"]["desired"] ~= nil then
                desired = shadow["payload"]["state"]["desired"]
            end
            if desired ~= nil then
                -- reply如果有数据,那么肯定是get请求, 要更新本地状态
                log.info("Shadow control/reply begin ...")
                --if shadow["payload"]["status"] == "success" then
                    local tmp = json.encode(desired)
                    log.info("desired=" .. tmp)
                    Shadow_Changed = false
                    -- 这里写业务逻辑
                    if Shadow_Changed then 
                        updateShadow(desired)
                    end
                    --else
                    --    log.info("desired is emtry")
                    --end
                --end
                log.info("Shadow control ... end")
            end
        else
            log.info("Bad Shadow JSON!")
        end
        return
    end
    local tjsondata,result,errinfo = json.decode(payload)
    if result then
        -- 处理mqtt payload
    else
        log.info("BAD JSON")
    end
end

--- 连接结果的处理函数
-- @bool result,连接结果,true表示连接成功,false或者nil表示连接失败
local function connectCbFnc(result)
    log.info("testALiYun.connectCbFnc",result)
    sConnected = result
    if result then
        --订阅主题,不需要考虑订阅结果,如果订阅失败,aLiYun库中会自动重连
        aLiYun.subscribe({["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=0, 
                          ["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=1,
                          ["/shadow/get/"..PRODUCT_KEY.."/"..getDeviceName()]=0})
        --注册数据接收的处理函数
        aLiYun.on("receive",rcvCbFnc)
        --PUBLISH消息测试
        aLiYun.publish("/shadow/update/"..PRODUCT_KEY.."/"..getDeviceName(), "{\"method\":\"get\"}", 1,publishTestCb, "{\"method\":\"get\"}")
    end
end

--配置产品key,设备名称和设备密钥;采用一机一密的认证方式是,第二个参数传入nil,采用一型一密认证方式时,需要PRODUCE_SECRET,并提供第五个参数
--注意:如果使用imei和sn作为设备名称和设备证书时,不要把getDeviceName和getDeviceSecret替换为misc.getImei()和misc.getSn()
--注意:采用一型一密认证方式时,仅在首次激活时动态下发DeviceSecret
--因为开机就调用misc.getImei()和misc.getSn(),获取不到值
--一机一密
--aLiYun.setup(PRODUCT_KEY,nil,getDeviceName,getDeviceSecret)
--一型一密
aLiYun.setup(PRODUCT_KEY,PRODUCE_SECRET,getDeviceName,getDeviceSecret,setDeviceSecret)

--setMqtt接口不是必须的,aLiYun.lua中有这个接口设置的参数默认值,如果默认值满足不了需求,参考下面注释掉的代码,去设置参数
--aLiYun.setMqtt(1, nil, 65)
aLiYun.on("connect",connectCbFnc)


--要使用阿里云OTA功能,必须参考本文件124或者126行aLiYun.setup去配置参数
--然后加载阿里云OTA功能模块(打开下面的代码注释)
require"aLiYunOta"

流程

  1. 开机
  2. 连接阿里云
  3. 定义shadow更新的topic
  4. 发送一个{“method”:”get”}到/shadow/update的topic,以获取最新的shadow version
  5. 阿里云下发最新的shadow,读取verison,更新本地状态
  6. 根据业务逻辑发送最新shadow或者处理下发的shadow状态

转载请注明原文链接:阿里云影子文件操作指南
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址