ラズベリーパイpicoでOpenWeatherMapから現在の天気を取得！！！

# ラズベリーパイ pico w で現在の天気予報を取得

# ラズベリーパイpico wで遊んでみた2

# この記事について
前回の記事でインターネットに接続できたということで、ラズベリーパイpicoにより、実現できることの幅が大幅に大きくなりました（多分）。
ということで、無料で利用できるOpenWeatherMapを利用し、現在の天気予報を取得していきましょう。

# OpenWeatherのAPIキーを取得
下記を参考にして下さい。

https://openweathermap.org/api

https://auto-worker.com/blog/?p=1612

# 今回の全体のコードはこちら

```python:get_weather.py
import network
import urequests
import json

#----------------------------------------------
sta_if = network.WLAN(network.STA_IF)

if not sta_if.isconnected():
    print('connecting to network...')
    sta_if.active(True)
    sta_if.connect('<ssid>', '<key>')
    while not sta_if.isconnected():
        pass
print('network config:', sta_if.ifconfig())
#ネットワークに接続
#----------------------------------------------

url = "https://api.openweathermap.org/data/2.5/weather?lat={緯度}&lon={経度}&appid={自身のAPIキー}"
json_data = urequests.get(url)

print(json_data.json().get('weather')[0].get('main'))

```
上記のコードを実行すると、シェル画面に現在の天気が表示されると思います。




# APIの呼び出しかた

https://openweathermap.org/current

上記のURLに事細かくAPIの呼び出しかたが公式によって記載されています。
自分はOneCallApiではなくCurrentWeatherDataの方を利用しています。
OneCallApiの方の説明は全然読んでいませんが、あまり違いはないような気がします。





```
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
```

上記のURLはHOW to make an API call（APIの呼び出しかた）と書いてある下のURLです。
天気予報を取得したい位置を緯度と経度で表し、apiidは自身のAPIキーを記入して下さい。

+ lat(緯度)
+ lon(経度)
+ apiid（自身のAPIキー）
+ mode（応答の形式をXML,HTMLかJSONの指定ができる。指定がなければデフォルトでJSON）
+ lang（言語の指定）

東京駅の現在の天気の情報が欲しい時は下記のURLにして下さい。
https://api.openweathermap.org/data/2.5/weather?lat=35.680&lon=139.767&appid=自分のAPIキー&lang=ja

このURLに自分のAPIキーを入れて、クリックすると下記のような画面が見られます。


![スクリーンショット 2024-02-05 14.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679937/c266b169-3036-24ee-f29f-5755c9e7a384.png)

つまり、本日のコードの下から二行目のコードで、上記の画像の情報を取得するというわけです。--json_data = urequests.get(url)--

# レスポンスの中身

```json:json_res.js
                          
{
  "coord": {
    "lon": 10.99,
    "lat": 44.34
  },
  "weather": [
    {
      "id": 501,
      "main": "Rain",
      "description": "moderate rain",
      "icon": "10d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 298.48,
    "feels_like": 298.74,
    "temp_min": 297.56,
    "temp_max": 300.05,
    "pressure": 1015,
    "humidity": 64,
    "sea_level": 1015,
    "grnd_level": 933
  },
  "visibility": 10000,
  "wind": {
    "speed": 0.62,
    "deg": 349,
    "gust": 1.18
  },
  "rain": {
    "1h": 3.16
  },
  "clouds": {
    "all": 100
  },
  "dt": 1661870592,
  "sys": {
    "type": 2,
    "id": 2075663,
    "country": "IT",
    "sunrise": 1661834187,
    "sunset": 1661882248
  },
  "timezone": 7200,
  "id": 3163858,
  "name": "Zocca",
  "cod": 200
}                        
                        
```

先ほどの画像とは天気と場所が違いますが、これを見ながら簡潔に説明していきます。
+ coord[lon,lat]　緯度と経度
+ weather[main] 現在の天気
+ main[temp,pressure,humidity]気温、気圧、湿度、体感温度や最高気温

ざっくり説明するとこんな感じです。

get_weather.pyに下記のコードを追加してあげれば、湿度や気圧も取得できます。
```python:get_weather.py
print(json_data.json().get('main').get('humidity'))
print(json_data.json().get('main').get('pressure'))

Temp = int(json_data.json().get('main').get('temp')) - 273.15
print(str(Temp)+"°C")
```

:::note warn
気温の単位はデフォルトでケルビンになっています。
気温が0℃の場合には273.15と表示されます。摂氏にするなら-273.15をしてあげましょう。

:::


# LCDに天気予報を表示してみた

![IMG_3946.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679937/bc614d53-f00f-9bae-f0fd-7906bcf7a4ac.jpeg)


waveshare製のPicoLCD1.8に現在の天気を取得して表示しました。
ラズパイ初心者であまり何も調べずに液晶を買ったため、情報量の少ない液晶ディスプレイを購入してしまいましたが、無事表示できました。
（日本語未対応のため文字化けしてしまいます...℃も文字化けしてしまうので使えず...
）
恐らく画像の取得もできないため、天気のマークは自作です...
(mistの天気なんか滅多にならんやろ...って思って渋々mistのマークを作ったら、偶々mistの天気でした)

このディスプレイの表示の仕方は下記を参考にしました。(別記事で少し詳しく説明するかもしれませんが)
特に[こちら](https://www.instructables.com/WaveShare-Pico-LCD-18-Display-Workout/)の方はすごく参考になりました。
[こちらはwaveshareの公式の参考サイトです](https://www.waveshare.com/wiki/Pico-LCD-1.8)
[こちらはmicropythonの公式の参考サイトです](https://micropython-docs-ja.readthedocs.io/ja/latest/library/framebuf.html)


# まとめ
APIを使うことで簡単に天気予報の情報を取得でき、APIについて学ぶことだできたのは
自分にとって良い経験でした。そのほかの無料のAPIも使ってみたいです。