なんで作ったの?
シンガポールではhazeと呼ばれる煙害がひどい年があり、知ったところでどうしようもないのであるが、今日の様子はどんな具合かな、が知りたくなる。AirVisualというケータイアプリがきれいなマップを表示してくれるので(web pageはここ)よく利用していたのだが、あるときAPIがあるのを見つけてしまった。月に10,000 callまでは無料とある。一時間に一回情報を取るとすれば、月に700回程度なので、十分だ。
ということで、なんで作ったのか、に対する答えは以下の二つです。
- 今日のhazeの具合(air quality)はどんなかな、が知りたいと思ったときにすぐ見られるようにしたかったから
- AirVisual APIがあるのを見つけてしまったから
なにをするもの?
AirVisualから一時間に一度情報を取得してアナログな感じで値を表示したかったので、一本のアームでqualityの段階を指すようにした。微妙な違いがよく分からないことがあるとイヤなので、数値も7セグLEDで表示するようにした。
実際の動作のようす
どういう仕組み?
Raspberry pi Zero W(一号機)上、すべてpythonで処理しています。AirVisual APIで最寄りの都市のデータを取得し、いったんログに記入しています。これはあとで眺めるためです。(月刊ログがあれば、たぶん買うだろうな、と思うほどログ好きなので)データを取ってログに書く、までを一つのコードで処理し、二つ目のコードで今取ってきた値の表示をするようにしています。針の動きはstepper motorで、数値の表示には7 segment LED displayを使っています。
使っている技(わざ)
興味のある方は、ここに出てくる文や単語をGoogle検索してさらに調べてみてください。
- AirVisual APIを使う
- Raspberry piでstepper motorを使う (python)
- Raspberry piで7 segment LED displayを使う (python)
作り方
材料
- Raspberry pi Zero W
- Stepper motor (Adafruit PRODUCT ID: 858)
- 7 segment LED display (Adafruit PRODUCT ID: 879)
- H-Bridge Motor Drive (L293D)
- Bread board
- Jumper pins
接続
Stepper motorをdriveするための配線が多くてみにくいですが、以下のように配線しました。Raspberry piからの5V供給がmotorを動かすには足りないようで、L293Dのvcc2には別途USBから5V供給したところ、なめらかに動くようになりました。
Ref pages:
- Adafruit’s Rapberry pi Lesson 10. Stepper Motors
- LED Backpack Displays on Raspberry Pi and BeagleBone Black
表示板の作成
AirVisualの説明ページにあった以下のiconを参考にして、回転する針で指し示すことができるpie型の図を用意しました。
powerpointであれこれ工夫して作った図が以下。これを印刷して厚紙にはりつけました。
code
まずはこれ。これを走らせてデータをとり、log_path
で指定したファイルに記録します。24行目のapi_keyはご自分のものを(取得はここから)。
crontabを使ってこれらのコードを定時に走らせています。
# Sep29, 2019
# airvisualAPI.py
# ref: https://pypi.org/project/pyairvisual/
import asyncio
from aiohttp import ClientSession
from pyairvisual import Client
from datetime import datetime
def timestamp():
dt = datetime.now()
ts1 = dt.strftime('%b%d-%Y_%H:%M:%S')
return ts1
log_path = './AQI_log.txt'
async def get_aqi() -> None:
async with ClientSession() as websession:
client = Client(websession,
api_key='YOUR-KEY')
data1 = await client.api.nearest_city()
print(data1)
current_aqi = data1['current']['pollution']['aqius']
temp = data1['current']['weather']['tp']
pressure = data1['current']['weather']['pr']
humidity = data1['current']['weather']['hu']
w_speed = data1['current']['weather']['ws']
w_direction = data1['current']['weather']['wd']
ts = timestamp()
# write log
data_line = ['data:', ts,
temp, pressure, humidity,
w_speed, w_direction, current_aqi]
print(data_line)
# write to log
with open(log_path, mode='a') as LOG:
LOG.write('\t'.join([str(e) for e in data_line]) + '\n')
asyncio.get_event_loop().run_until_complete(get_aqi())
つぎにこれを走らせます。二つ補助コード( sevenSeg.pyとstepMotor.py )がありますので、それらもこのコードと同じdirectoryに置いておきます。
このページを作るために使っているコード表示プラグインがsquare bracket pair中に数字を入れると間違って解釈してしまうので、スクリーンショットでコードを貼り付けます。
二つの補助コードたち。stepper motorと7 segment displayは別々に勉強しながら作ったので別コードになっています。
sevenSeg.pyのつづき。
使ってみて
いいです。なんか外がかすんでる、のどが少しイガイガする、hazeのにおいがしない?というときに数字を見るとたいてい高めで納得する。このフィードバックをしばらく繰り返すと、表示より先に今日は高めじゃない?というのがわかったりする。環境を知る、ということは大切ですね。
このあとの予定
特に考えていませんが、以下のような機能を追加するといいかもしれないなあ、となんとなく思っています。
- 設定値を超えるとGoogle Homeが
“AIQが設定値を超えました。戸締りをしたほうがいいんじゃないかな。”
と言ってくれる。 - AIQを定時にSlackに飛ばす
- 更新ごとにベルなどを鳴らす
うらばなし
このガジェット実は、コードや仕組みどうこうよりも、pie chart風の表示部分や裏にあるフレームづくりが一番楽しかった。LEGOのtechnicシリーズのパーツが裏で活躍しています。