一点客套话
我写了一个名叫nodeMCU入坑系列的文集,主要介绍nodemcu的一些模块,内容也是相对简单的。如果你有一直关注笔者的话,想必对这个小玩具应该相当熟悉了。
考虑到那些传感器模块,笔者一时半会也不可能拥有,入坑系列后面可能不怎么会更新了。又考虑到你可能意犹未尽(纯粹YY),厚颜无耻的笔者决定在挖一个坑(文集),不定时的更新一些综合性比较强的文章,以点燃你继续玩这个玩具的热度。
对了,顺便说一句,笔者和项目组没有什么利益往来。nodemcu原项目组似乎也不在维护,而是由GitHub上的大牛在维护。
目标
用nodemcu做一个天气预报的小玩具。通过wifi获取来自彩云天气提供的实时天气状态,并在OLED上面显示。
需要用到的主要模块包括,但不仅限:
大致的思路是这样的,http模块获取天气状态的json数据,再用sjson模块解析得到需要的数据。而要将数据显示在OLED上,则需要借助u8g模块。既然要联网,wifi模块不能少!
这里用的天气数据是由彩云天气提供的API,彩云提供免费的API接口,注册成为开发者即可用。笔者没有注册成为开发者,本文使用彩云wiki提供的测试用公开API_KEY来获取数据。
开始实践
为了避免一口吃成胖子,本文先实现一个简单的demo。
为了方便,直接在ESPlorer上用wifi.sta.config("ssid", "password")
接入wifi。ssid表示wifi的名字,password表示wifi密码。可以使用wifi.sta.getip()
确认是否连上wifi。
获取天气数据
获取天气数据很简单,直接使用http模块的get方法即可。
http.get("http://api.caiyunapp.com/v2/TAkhjf8d1nlSlspN/116.667,23.3667/realtime.json", nil, function(code, data)
if (code < 0) then
print("http request failed")
else
print(data)
end
end)
如果成功,会得到一串json字符串。注意使用http,因为使用https会报超时错误。
当然了,拿到这一串json后,并不能直接使用。所以需要借助sjson模块,把json转换成table。只有这样才能将json数据当做变量来访问。
json转table
实际上,彩云返回的数据内容相当丰富。但有些内容并不是我们需要的,这时候可以借助元表来过滤掉一些数据项。这里,笔者只提取了四个数据,分别是温度、天气状况、湿度、pm2.5。
weather = {}
mt = {}
t = {metatable = mt}
mt.__newindex = function(table, key, value)
if
(key == "temperature") or
(key == "skycon") or
(key == "humidity") or
(key == "pm25")
then
rawset(weather, key, value)
end
end
在元表的__newindex元方法里面对key做一下过滤。将想要的数据存入到weather表里面。这样就可以使用weather.xxxx来访问了。
下面是demo完整的源码,复制粘贴即可看到效果。当然了,天气数据是我这个城市的数据。关于彩云API的内容,请移步彩云wiki。
weather = {}
mt = {}
t = {metatable = mt}
mt.__newindex = function(table, key, value)
if
(key == "temperature") or
(key == "skycon") or
(key == "humidity") or
(key == "pm25")
then
rawset(weather, key, value)
end
end
obj = sjson.decoder(t)
http.get("http://api.caiyunapp.com/v2/TAkhjf8d1nlSlspN/116.667,23.3667/realtime.json", nil, function(code, data)
if (code < 0) then
print("http request failed")
else
obj:write(data)
for k, v in pairs(weather) do
print(k, v)
end
end
end)
OK,到此我们的气象站就有个粗糙的样子了。后面在加上u8g美化,就可以变成一个有模有样的迷你气象站了。
最后,需要说明的是,因为数据带浮点。下载的时候请选择float固件,否则天气等浮点数据显示为0!
点个赞再走啊