更多内容,请访问我的网站:https://jiangge12.github.io/
----------------------------------------- 什么是 API---------------------------------------------------------
有很多天气数据网站可以查询天气情况,通常用浏览器访问其网站就行了。
如果单片机想抓取网页数据并显示到 TFT / OLED 小屏幕呢,这就需要了解 API 这个关键字。
自行百度 API ( Application Programming Interface )
简单说,点击网页获取信息这件事:
人去点,眼睛收货,大脑验货。
程序怎么去点?模拟鼠标点击?不是的,网站会提供 API ,告知怎么用程序访问网站获得数据。
具体到天气网站,通常会开放注册,并给每个账号一些 key, 有了这个 key 就可以按照特定的规则提出数据查询请求 request ( http 的 GET 方法 ),然后网站返回需要的数据。下面两个英文和中文各列出一家供参考。为了节约时间先可以不看。后面看了之后,查找具体指引的时再来看。
openweather: https://openweathermap.org/api
高德天气: https://lbs.amap.com/api/webservice/guide/api/weatherinfo
--------------------------------------------手工请求数据-----------------------------------------------------
以 openweather 为例,没有APPID没关系,暂时不急去注册账号申请。把下面的连接粘贴搭配浏览器地址栏回车:
你会看到浏览器的页面上出现这么一大堆数据:
{"coord":{"lon":-0.13,"lat":51.51},"weather":[{"id":300,"main":"Drizzle","description":"light intensity drizzle","icon":"09d"}],"base":"stations","main":{"temp":280.32,"pressure":1012,"humidity":81,"temp_min":279.15,"temp_max":281.15},"visibility":10000,"wind":{"speed":4.1,"deg":80},"clouds":{"all":90},"dt":1485789600,"sys":{"type":1,"id":5091,"message":0.0103,"country":"GB","sunrise":1485762037,"sunset":1485794875},"id":2643743,"name":"London","cod":200}
这个是某一天的伦敦历史数据,并不是实时准确的数据,不过用来练习编程足够了。
----------------------------------------------JSON-----------------------------------------------
上面的信息显示比较乱,这里有个在线转换工具 ,把上面的这一大堆贴到左边,点击“格式化”按钮,右边会出现其缩进结构,还可以折叠,这样学习JSON就直观多了。
----------------------------------------------Python-----------------------------------------------
下面这个python代码:
import requests
r = requests.get('https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22')
temp = r.json()['main']['temp']-273.15 # float
humidity = r.json()['main']['humidity'] # int
pressure = r.json()['main']['pressure'] # int
weather = r.json()['weather'][0]['description'] # str print(type(weather))
wind = r.json()['wind']['speed'] # float
visibility = r.json()['visibility'] # int
print('%.2f'%temp,humidity,pressure,weather,wind,visibility) # '%.2f'%temp 保留小数点后两位
输出是这样的:
7.17 81 1012 light intensity drizzle 4.1 10000
有了数据至于怎么用,看需求了,比如上传到 MQTT ,SQL ,输出到 TFT 等。
实测 Micropython 几乎可以直接用这个代码,把 requests 替换为 urequests 即可。(把联网的代码写道boot.py里可以实现自动连接网络)
什么?电脑里python环境都没有?这个在线 python IDE 很好用呢,赶紧用邮箱注册一个吧。
--------------------------------------------------------------------------------------------------
下面是 五天天气预报的数据获得(网站返回的是每间隔3小时整点数据,一天8条,总计40条)
都到这一步了,也该去申请一个key吧
import requests
import json
url = "http://api.openweathermap.org/data/2.5/forecast?q=Chengdu,CN&APPID=xxxxxx"
r = requests.get(url)
j = r.json()['list'] # 返回40条, j[0] 查看第一条数据
i=5
while i < 40:
print('\nDay', int((i-2)/8) )
print('预报时刻:' , j[i]['dt_txt'])
print('温度 :' , '%.2f'%(j[i]['main']['temp'] -273.15)) # 注意 '%.2f'% 的用法
print('湿度 :' , j[i]['main']['humidity'])
print('气压 :' , j[i]['main']['pressure'])
print('天气 :' , j[i]['weather'][0]['description'])
print('风速 :' , j[i]['wind']['speed'])
print('能见度 :' , j[i]['visibility'])
i += 8
接下来可以做一些更有意思的事,比如收到下雨的预报,微信提醒带伞什么的。。。
--------------------------------------------------------------------------------------------------
这里再简单提一下 Json ,有很多文章教程可以去看,我的经验是看的 { } [ ] ( ) : 所划分的数据块。
比如把 j[0] 打印出来看:weather 看起来和 main 差不多,但是多了一层 { },所以代码里是 ['weather'][0]
再具体一些就是:
如果对象是 list ,里面的元素没名字, 用 ['weather'][0] 获得这一坨,再进一步处理
如果对象是 dict,里面的元素有名字, 用 ['wind']['speed'] 获得冒号后的数据
--------------------------------------------------------------------------
下面是 ESP8266 Micropython 输出到 I2C OLED
import urequests,network
import utime
from machine import I2C,Pin
from ssd1306 import SSD1306_I2C
i2c = I2C(scl = Pin(4),sda = Pin(5),freq = 10000) #软件I2C
oled = SSD1306_I2C(128, 64, i2c) #创建oled对象
oled.rect(0,0,127,63,1)
oled.show()
oled.text("Hello World!",15,27)
oled.show()
print('IP:',network.WLAN(network.STA_IF).ifconfig()[0] );
url = "http://api.openweathermap.org/data/2.5/weather?q=Chengdu,CN&APPID=xxxxxx"
r = urequests.get(url)
temp = r.json()['main']['temp']-273.15 # float
humidity = r.json()['main']['humidity'] # int
pressure = r.json()['main']['pressure'] # int
weather = r.json()['weather'][0]['description'] # str
wind = r.json()['wind']['speed'] # float
visibility = r.json()['visibility'] # int
print('%.2f' %temp,humidity,pressure,weather,wind,visibility)
temp = int(temp * 100)/100 # oled 库基本都不支持浮点数直接保留小数点后两位显示
oled.fill(0)
oled.text("temp:",0,0)
oled.text(str(temp),64,0)
oled.text("hum:",0,8)
oled.text(str(humidity),64,8)
oled.text("weather:",0,16)
oled.text(weather,64,16)
oled.show()