Python / Micropython 获取天气数据

更多内容,请访问我的网站: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没关系,暂时不急去注册账号申请。把下面的连接粘贴搭配浏览器地址栏回车:

bhttps://samples.openweathermap.org/data/2.5/weatherbq=London,uk&appid=b6907d289e10d714a6e88b30761fae22

你会看到浏览器的页面上出现这么一大堆数据:

{"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()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值