M5Stack で天気情報を表示する(OpenWeatherMap API)

 将来的には M5Stack で Google Calendar に登録してあるスケジュール情報を表示させたいと思っているのですが、認証周りなどが少しハードル高そうなので、まずは認証なしで情報を取ってこられる API から情報を取得して表示する処理を試してみたいと思います。その中でもそれなりに実用性がありそうなものとして、天気情報を取得して画面に表示する処理を作ってみました。

天気情報API

 ひとまず今回は無料で手軽に試せる API を探したところ、 OpenWeatherMap という API がみつかったのでこれを利用してみます。

openweathermap.org

 使い方についてはこちらも参考にさせていただきました。

qiita.com

 ユーザ登録をすると API Key が発行されるのでそれを使用します。アクセスする URL は下記のようになります。

http://api.openweathermap.org/data/2.5/weather?q=Tokyo,jp&appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 まずはブラウザでアクセスして確認してみて、情報が取得できていれば OK です。

ファームウェア実装

 MicroPython は基本的には Python3 と互換ですが、 Python の全てのモジュールが移植されているわけではありませんので、 API ドキュメント等を参照して Python との違いを確認しながら実装する必要があります。今回は天気情報の API にリクエストを送信して結果を取得するために、 MicroPython の urequests モジュールを使用しています。また、結果を json オブジェクトとして扱うためには ujson モジュールも必要になりますので、こちらも import しておきます。

 urequests の使い方についてはこちらのサイトを参考にさせていただきました。

blog.boochow.com

 ソース全体は下記のようになります。 self.api_key には実際に取得した API Key を設定します。対象の都道府県としては今回はとりあえず東京、埼玉、名古屋を指定しています。

from m5stack import lcd

import time
import ujson
import urequests

class Weather:
    def __init__(self):
        self.base_url = 'http://api.openweathermap.org/data/2.5/weather?q={},jp&appid={}'
        self.api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        self.prefectures = ['Tokyo', 'Saitama', 'Nagoya']

        lcd.setCursor(0, 0)
        lcd.setColor(lcd.WHITE)
        lcd.font(lcd.FONT_DejaVu24)
        self.fw, self.fh = lcd.fontSize()

    def get_weather(self, prefecture):
        response = urequests.get(self.base_url.format(prefecture, self.api_key))
        json = response.json()
        main = json['main']
        self.temp = main['temp']
        self.pressure = main['pressure']
        self.humidity = main['humidity']
        self.temp_min = main['temp_min']
        self.temp_max = main['temp_max']

    def display(self, prefecture):
        lcd.clear()
        lcd.print(prefecture, 0, self.fw * 0)
        lcd.print("temp: {}".format(self.temp), 10, self.fw * 1)
        lcd.print("pressure: {}".format(self.pressure), 10, self.fw * 2)
        lcd.print("humidity: {}".format(self.humidity), 10, self.fw * 3)
        lcd.print("temp_min: {}".format(self.temp_min), 10, self.fw * 4)
        lcd.print("temp_max: {}".format(self.temp_max), 10, self.fw * 5)

weather = Weather()
while True:
    for prefecture in weather.prefectures:
        weather.get_weather(prefecture)
        weather.display(prefecture)
        time.sleep(10)

動作確認

 それでは動作を確認してみます。上記コードを m5cloud から M5Stack にアップロードすると、10秒おきに東京、埼玉、名古屋の天気情報を API から取得して、順番に表示していきます。ちなみに API から取得できる温度は華氏表記になりますので、実際のサービスに使用するときには適宜変換する必要があるかと思います。

f:id:akanuma-hiroaki:20180922235422j:plain

f:id:akanuma-hiroaki:20180922235438j:plain

f:id:akanuma-hiroaki:20180922235455j:plain

まとめ

 認証不要で単純に情報を取得するだけであれば(API Key は必要ですが) API にリクエストを投げて処理を行うのも urequests を使用して簡単に行うことができました。 Google Calendar 等を使うには OAuth 等の認証を行う必要があるのですが、M5Stack でそれを行う方法はまだわかっていないので、調べてみたいと思います。