カテゴリー
m5stack micropython python requests

m5stickC plusのmicropythonでurequestsを使う

教室に通っている中学3年の生徒がm5stickC plusを使って消毒用のアルコール噴霧器を作っています。

3Dプリンターなどを使いハードはほとんどできたのですが、機能追加をしようということになり、画面に前日のコロナの感染者を表示しようという話になりました。

感染者数の取得は下記のサイトからapiが提供されています。
https://corona.go.jp/dashboard/

ページに記載のある通り、2020年5月9日までの北海道の累計感染者数は、下のurlを叩けば取得できます。
https://opendata.corona.go.jp/api/Covid19JapanAll?date=20200509&dataName=北海道

jsonの取得データはこんな感じです

{
    "errorInfo":{"errorFlag":"0","errorCode":null,"errorMessage":null},
    "itemList":[{"date":"2020-05-09","name_jp":"北海道","npatients":"934"}]
}

pythonならこんな感じのコードで取得できます。
※実際には2日前と前日の差をとり、前日の新規感染者数を求めますが、長くなるので昨日までの累計感染者数を取得するコードになります。

import requests
import datetime

#日付を連続した数字に変換
def date_to_num(date_data):
    d = str(date_data)
    d_list = d.split("-")
    d_num = "".join(d_list)
    return d_num


today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
date_num = date_to_num(yesterday)

params = {"date":date_num,"dataName":"徳島県"}
url = "https://opendata.corona.go.jp/api/Covid19JapanAll"

try:
    r = requests.get(url,params)
    r = r.json()
    if r["itemList"]:
        print(r["itemList"][0]["npatients"])
    else:
        print("No data")
except:
    print("error")

m5stackではmicropythonを使用することができます。
apiを叩くときはurequestsを使います。
https://makeblock-micropython-api.readthedocs.io/en/latest/public_library/Third-party-libraries/urequests.html
使い方はpythonのrequestsとほぼ一緒ですが、使ってみて困った点がいくつかありました。

  • 日本語をクエリパラメータにすることができないため、事前にエンコードする必要があった

通常のpythonならrequestsのパラメータでそのまま日本語を渡せましたが、どうやらurequestsにはパラメータが渡せないようでした。
また、日本語をそのまま使用するとうまく動作しなかったのでエンコードした文字列をformatを使用して入れ込みました。通常のpythonの場合はurllib.parseを使って変換できますが残念ながらmicropythonにはないようでした。

  • 前日を取得するのに手間がかかる

通常のpythonならtimedeltaを使いますがmicropythonにはないため、エポック秒から取得しました。

from m5stack import *
from m5ui import *
from uiflow import *
import time
import utime
import ntptime
import urequests as requests


setScreenColor(0x111111)

#日付を連続した数字に変換
def date_to_num(date_form):
    L_d = list(map(lambda x: str(x) if x >= 10 else "0" + str(x), date_form))
    n_d = "".join(L_d)
    return n_d

#時計合わせ
ntp = ntptime.client(host='jp.pool.ntp.org', timezone=9)
#現在時刻エポック秒取得
e_today = utime.time()
#現在時刻の24時間前
e_yesterday = e_today - 60*60*24
#エポック秒を日付に変換
yesterday = time.localtime(e_yesterday)[:3]

date = date_to_num(yesterday)
tokushima = "%E5%BE%B3%E5%B3%B6%E7%9C%8C"
payload = {"date": date, "dataName": tokushima}

url = "https://opendata.corona.go.jp/api/Covid19JapanAll/?date={date}&dataName={dataName}".format(**payload)

try:
    r = requests.get(url).json()
    if r["itemList"]:
        lcd.print(r["itemList"][0]["npatients"], 0, 0, 0xffffff)
    else:
        lcd.print("No data", 0, 0, 0xffffff)
except:
    lcd.print("error", 0, 0, 0xffffff)

もっとうまく書く方法があるかもしれませんが、いかんせんmicropythonの情報があまりみつからなくて…

raspberry piのほうが通常のpythonが使えるのでやりやすいですが、m5stackは気軽に使えるのが利点です。

追記:
日付を整形するコードに違和感があったのでこちらに投稿しました