NodeMCU阿里云平台的远程温度查看实现

参考文章

NodeMCU 通过MQTT 连接阿里云物联网 https://blog.csdn.net/weixin_43368807/article/details/82984796
谢谢。

概要

本文与参考文章有一点的重复,但有几点会不同,一,更加具体的添加了一个实际功能,本文监控了温度与湿度信息;二,对代码进行了重新的组织,更加清晰简单。

阿里云平台方面的准备工作

创建产品、创建设备

可以参考最前边列出的参考文章。另外,阿里云平台也有很好的引导,按着引导下一步下一步就可以了。

添加功能

这个是与参考文章不同的地方。对了让读者更容易理解为什么要添加功能,我把产品、设备、功能的关系简单描述下。产品就像一个抽象的概念,例如电视机,只有把电视机变成具体的东西,我们才能具体触摸感知,这个就是设备,很类似于类与对象的概念。而一个产品对普通人来说,主要就是关注与它能做什么,也就是它的功能。功能是在产品中定义的,每个设备都会具备这个功能,这个就类似与类方法。

首先,选择产品,进入产品查看页面


选择产品
进入产品查看信息页面

然后,选择功能定义,在功能定义中选择自定义功能的添加


添加自定义功能

最后,进行自定义功能的设置


自定义功能设置

信息复制

后期设备端连接阿里云服务器时有几个信息需要设置,所以现在就要把对应的信息准备好:

  1. 在产品查看页面获取ProductKey与ProductSecret两个信息;
  2. 在功能定义页面获取温度、湿度的标识名,例如:


    功能标识选择

    上图中,温度标识符:CurrentTemperature,湿度标识符:humidity,这两个是读者在前边自己设置。

  3. 在设备查看页面获取DeviceName信息;
  4. 在设备查看页面获取Topic链接信息,是一个类似/sys/*********/DeviceA/thing/event/property/post的字符串。

到此为止,阿里云端的设置就已经完成了。

设备端操作

固件烧写

请参考本文最前的参考文章的说明,以及本人其他关于NodeMCU操作的文章。但需要注意的是,固件注意选择温度传感器模块,例如我使用了DHT温度传感器模块。
我的固件包含了如下模块:This was built against the master branch and includes the following modules: crypto, dht, encoder, enduser_setup, file, gpio, http, i2c, mqtt, net, node, pwm, sntp, spi, tmr, uart, wifi, wifi_monitor.

代码编写逻辑

在代码设计上,分为了五个文件,一个是初始化wifi逻辑文件,init.lua,另一个是mqtt的连接处理文件,再一个就是配置文件,用来记录不同使用者信息的文件,config.lua,再一个是mqtt的逻辑处理文件,这个是针对一个物联网项目需要编写的逻辑,mqtt_app.lua。最后一个文件是应用模块管理文件application.lua。未来,可能会有其他功能添加,例如添加一个HTTP服务器支持,那么很可能会需要添加新的模块实现,那么就在application.lua中加载新的模块实现。

配置文件config.lua

-- WIFI 设置
SSID = "HiWiFi_**********"
PASSWORD = "**********"


-- MQTT设置
ProductKey ="************"   
DeviceName ="*******"  
DeviceSecret="*********************************************"

RegionId="cn-shanghai"     --华东2
-- MQTT发送消息的topic
publish_topic = "/sys/"..ProductKey.."/"..DeviceName.."/thing/event/property/post"

Wifi初始化逻辑文件init.lua

dofile("config.lua")


function startup()
    if file.open("init.lua") == nil then
        print("init.lua deleted or renamed")
    else
        print("Running")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        dofile("application.lua")
    end
end

-- Define WiFi station event callbacks
wifi_connect_event = function(T)
  print("Connection to AP("..T.SSID..") established!")
  print("Waiting for IP address...")
  if disconnect_ct ~= nil then disconnect_ct = nil end
end

wifi_got_ip_event = function(T)
  -- Note: Having an IP address does not mean there is internet access!
  -- Internet connectivity can be determined with net.dns.resolve().
  print("Wifi connection is ready! IP address is: "..T.IP)
  print("Startup will resume momentarily, you have 3 seconds to abort.")
  print("Waiting...")
  tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end

wifi_disconnect_event = function(T)
  if T.reason == wifi.eventmon.reason.ASSOC_LEAVE then
    --the station has disassociated from a previously connected AP
    return
  end
  -- total_tries: how many times the station will attempt to connect to the AP. Should consider AP reboot duration.
  local total_tries = 75
  print("\nWiFi connection to AP("..T.SSID..") has failed!")

  --There are many possible disconnect reasons, the following iterates through
  --the list and returns the string corresponding to the disconnect reason.
  for key,val in pairs(wifi.eventmon.reason) do
    if val == T.reason then
      print("Disconnect reason: "..val.."("..key..")")
      break
    end
  end

  if disconnect_ct == nil then
    disconnect_ct = 1
  else
    disconnect_ct = disconnect_ct + 1
  end
  if disconnect_ct < total_tries then
    print("Retrying connection...(attempt "..(disconnect_ct+1).." of "..total_tries..")")
  else
    wifi.sta.disconnect()
    print("Aborting connection to AP!")
    disconnect_ct = nil
  end
end

-- Register WiFi Station event callbacks
wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_disconnect_event)

print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config({ssid=SSID, pwd=PASSWORD})
-- wifi.sta.connect() not necessary because config() uses auto-connect=true by default

应用模块管理文件application.lua

-- MQTT 模块 ----
dofile("mqtt.lua")
--print("Hello ...")

mqtt的连接处理模块mqtt.lua

-- 加载配置信息
dofile("config.lua")
-- 加载MQTT应用逻辑
mqtt_app = require("mqtt_app")

-- 连接阿里云
ClientId =wifi.sta.getmac()  

myMQTTport=1883    
myMQTT=nil      

myMQTThost=ProductKey..".iot-as-mqtt."..RegionId..".aliyuncs.com"   
myMQTTusername=DeviceName.."&"..ProductKey         


myMQTTtimes='1234567890'
hmacdata="clientId"..ClientId.."deviceName"..DeviceName.."productKey"..ProductKey.."timestamp"..myMQTTtimes  
myMQTTpassword=crypto.toHex(crypto.hmac("sha1",hmacdata,DeviceSecret))    
myMQTTClientId=ClientId.."|securemode=3,signmethod=hmacsha1,timestamp="..myMQTTtimes.."|"      


myMQTT=mqtt.Client(myMQTTClientId, 120,myMQTTusername,myMQTTpassword) 

mqtt_app.MQTT_Init(myMQTT)

print("Attempting client connect...")
local re = myMQTT:connect(myMQTThost, myMQTTport,0, mqtt_app.MQTTSuccess,mqtt_app.MQTTFailed)

mqtt的应用逻辑实现模块mqtt_app.lua

dofile("config.lua")

local myqq_app = {};

MQTTconnectFlag = 0;
mClient = nil;

function myqq_app.MQTT_Init(client)
    --[设备offline 事件]-----
    myMQTT:on("offline", function(client) 
        print ("offline") 
        --tmr.start(0)
    end)

    --[注册 设备接收到订阅的topic 事件]-----
    myMQTT:on("message", function(client, topic, data) 
        print(topic ..":") 
        if data ~= nil then
            print(data)
        end
    end)
end

---[连接成功]---
function myqq_app.MQTTSuccess(client)
    print("MQTT connected")
    
    -- 注册通道
    --client:subscribe(topic0,0, function(conn)     --注册topic0
    --    print("subscribe success") 
    --end) 

    mClient = client;
    MQTTconnectFlag=1
    --tmr.stop(0)        --关闭定时连接
    
    --[topic 定时上传数据]
    tmr.create():alarm(5000, 1, function()    --等待连接上
        if MQTTconnectFlag==1 and mClient~=nil then   
            re,t,s,x = dht.read11(1);
            msg = "{\"id\":\"bc:dd:c2:30:cb:dc\", \"params\":{\"CurrentTemperature\":"..tostring(t)..",\"humidity\":"..tostring(s).."},\"method\":\"thing.event.property.post\"}"
            mClient:publish(publish_topic,msg,0,0,function(client)
                            print("send ok" ) 
            end)
        end
    end)
end

---[连接失败]---
function myqq_app.MQTTFailed(client,reson)
    print("Fail reson:"..reson)
    MQTTconnectFlag=0
    --tmr.start(0)     --重新启动连接
end

return myqq_app;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容