前置き
この記事は IoTLT Advent Calendar 10日目です。昨日は@hepppookさんのドローンが作りたかった でした。
このアドベントカレンダーが三つほどあります。それぞれ面白いものだらけです。
この内容は shizuoka.py #7 で行ったLTの中身です。スライドはこちらです。
Shizuoka.py #7 に参加&発表してきました #shizuokapy
この時はLTだったのでさらっと話をしたぐらいでしたが、アドベントカレンダーやらないかとのびすけ(@n0bisuke)さんから頂きましたので、具体的に何をしたのか書いてみようと思います。
タイトル通りですが、ESP32にMicropythonを乗せた上でLチカするときにAmazon Dash Buttonを使ってみた話です。ESP32を乗せたボードはIoT界隈でブームになっていると思いますが、ブームに乗った感じです。
ESP32の開発は通常だとArduino-IDEだと思います(C++の方がスペック出しやすいらしいです)が、Micropythonも利用できます。Arduinoのスケッチ言語でも良いのですが、Pythonを使っている身としてはPythonで書けるとなにかと心が安らぐ気がします。
と言う適当な理由ですが、MicropythonのファームウェアいれたESP32上でLチカをしてみました。ついでに塩漬けして使ってないAmazon Dash Buttonをハック化して連携など、混ぜ込んだらこうなった話です。
使ったものについて
Amazon Dash Buttonとは?
フルグラ Dash Button | |
ASIN : B01L2WPA0O こちらはAmazonアソシエイトプログラム参加リンクです |
Amazonが配布している定期購買向けのボタンデバイスです。各ボタンの対応製品とスマホを使ってAmazonアカウントと連携するとボタンを押しただけで商品が注文されます。
Amazon Dash Button 通販 | Amazon
なおWifiのAPが必須なデバイスです。
このボタンデバイスは本来ならそれでしか利用できませんが、ハックがされた結果、手軽なIoTデバイスとして利用できるようになりました。手軽といってもCLIやPythonが扱えることが前提です。
今回はamazon-dash というPythonで書かれたサービス(デーモン)アプリを使います。使い勝手がかなりいいのでおすすめです。
GitHub - Nekmo/amazon-dash: Hack your Amazon Dash to run what you want.
Lチカとは
電子工作を行う際の最初の入門的な作業です。プログラミングのHello Worldと似ています。扱うボードにLEDを乗せるor搭載されているLEDを光らせたり消したりして動作確認や環境の使い方を覚えます。
Lチカとは (エルチカとは) [単語記事] - ニコニコ大百科
ESP32とは
最近話題のこちらです。自分は秋月さんで売ってるESP32-DevKitCを使ってます。
ESP32-DevKitC ESP-WROOM-32開発ボード: 無線、高周波関連商品 秋月電子通商-電子部品・ネット通販
Micropythonとは?
Micropythonは、Pyboardというボードメーカーが開発した組み込みボード向けの軽量なPython処理系です。Python3の文法が利用でき搭載されているライブラリや専用の外部ライブラリを利用できます。
MicroPython - Python for microcontrollers
Pythonといっても、標準的なCPython(Win,macOS,Linuxなどで利用できるPython)とは違い搭載されていない機能も多数あり、また各ボードで利用できるリソースも違うので、どこでも同じように扱えるものではないのですが、Arduinoを描くのが苦手だけど普段Python触ってる方ならぴったりな処理系です。
今回はESP32にMicropythonのファームウェアを搭載してしています。Interface 2018 09月号でESP32の特集がされていて、Micropythonの導入方法も書かれていたのでそちらを見るのをお勧めします。(というかそちらを見てこのネタをやってますw)
Interface(インターフェース) 2018年 09 月号 | |
ASIN : B07D58QQ5G こちらはAmazonアソシエイトプログラム参加リンクです |
ボタンを押したらLEDが光るLチカを実装してみる
ではIoTなLチカを試してみます。実際に動くような状態で shizuoka.py #7 で発表した時の図はこういう形でした。
じつはもう少しシンプルにすることもできます。本日はこちらを紹介。
Amazon Dash ButtonとESP32の間にあったNode-redが消えています。このNode-Redはいろんなサービスの中間で橋渡ししてくれるサービス(アプリ)です。クラウド上だとIBM Cloud上のNode-Redや enebular が有名だと思われます。(Node-Redは元々はIBMのプロジェクトです)
enebular - あらゆるデバイスとクラウドサービスを「つなぐ」、IoTのためのデータ連携プラットフォーム
フローベースド・プログラミング「Node-RED」のご紹介 | IBM ソリューション ブログ
Node-RED日本ユーザ会 : Running on IBM Bluemix
ただ今回は利用しなくてもよくなりました。(ディスってるわけではないです)amazon-dashライブラリは結構高機能なので使いこなすとオートメーションの幅が広がりそうです。
実装方法を詳解したかったのですが、時間の都合上箇条書きと簡単な解説でまとめておきます。年末のアドベントカレンダーは綺麗にまとめるのは至難の技ですね。。
- Raspberry Piにpythonのamazon-dash ライブラリをインストール
- Amazon Dash Buttonをamazon-dash側に登録
- ESP32にMicroPythonをインストール
- MIcropythonでURLを叩くとLチカする回路, コードを作成
- MicropythonのURLをAmazon Dash Buttonに登録
Raspberry Piにamazon-dashライブラリをインストール
amazon-dashのインストールの仕方ですが、公式ではPythonのパッケージ管理ツールでのインストールがオススメの様です。今回は上の図にもあるように Raspberry Piにインストールしています。
pip install -U amazon_dash
sudo python -m amazon_dash.install
pip...
でamazon-dashのインストールして。 sudo python...
でシステムのサービス(デーモンモード)として登録してくれます。ラズパイを起動時に動かしたい時には必須だと思います。
(詳しくいうとsystemdのマネージャーへ登録してsystemctlで操作できる様にする)
ちなみに、amazon-dash自体はRasberry Piでなくても、Linux系のOSなら大抵大丈夫の様です。またDockerのイメージもあります。
Amazon Dash Buttonをamazon-dashデーモンに登録
amazon-dashがインストールできたら、Dash Buttonを登録します。Dash ButtonをAmazonアプリで登録する前に、このコマンドを起動します。
sudo amazon-dash discovery
起動すると、コマンド側で検知できたネットワーク内のMacアドレスが見つかるたびに画面内に出てきます。
Dash Button自体はAmazonアプリでWi-Fi APの設定が済むと単独でWi-Fiへ接続します。その時の接続した状態をamazon-dashが調べて識別子となるMacアドレスを見つけてくれます。
(仕組みとしてはamazon-dash自体はパケットキャプチャをおこない、Wifiで接続しようとしているDash Buttonが発するパケットをMacアドレスのメーカー識別子を利用してると思います。多分)
Macアドレスを取得したら、/etc/amazon-dash.yml
へ登録します。
# amazon-dash.yml
# ---------------
settings:
delay: 10
devices:
[先程見つけたMacアドレス]: # Url Webhook example
name: [適当な名前]
url: '[動かしたいurl/path/]'
method: get
content-type: plain
Dash Buttonの登録は商品選択の前まで進めてキャンセルすることで、商品の注文がされないがamazon-dash側でなんらかのタスクが実行できるボタンにすることができます。
もちろん、商品の注文も出来るボタンにした上で、注文したら何らかのタスクを実行させる ことも可能です。(これを使えば注文をしたらSlackに連絡が来るとか、帳簿に自動記帳するとかも出来ますね)
ESP32にMicropythonをインストール
ESP32にMicropythonをインストールします。こちらはMicropythonのドキュメントがあるのと、Interfaceに詳細が記載されているので、そちらをお勧めします。
1. Getting started with MicroPython on the ESP8266 — MicroPython 1.9.4 documentation
ちなみに、ESP32ではなくてESP8266のドキュメントを出した理由はというのは、MicropythonのESP32用は現状ありません。ESP32はESP8266の上位版(BLEなど機能追加含む)ですがESP8266のファームウェアでも動くのでそちらで行っています。Interfaceの特集でも同じ方法を取られています。
MicropythonでURLを叩くとLチカする回路, コードを作成
Micropythonがインストールできたら、Lチカをする回路と、Lチカを叩くコードを作ります。ESP32はWEBサーバーとしても扱えるので、簡易的なWEBサーバーとなる様にコードを書きます。
Lチカさせるコードはこちらです。
# hello.py
# MicropythonのREPLで hello.pyをimportで呼び出し、hello.l_chika() で実行すると動きます
from machine import Pin
import time
def l_chika():
p4 = Pin(4, Pin.OUT)
print("start Lチカ!")
p4.value(0)
time.sleep(2)
p4.value(1)
time.sleep(2)
p4.value(0)
print("end Lチカ!")
Micropythonのサーバーはsocketライブラリで作ります。実はこちらもMicropythonのドキュメントにあるコードをほぼ丸コピーです。
5. Network - TCP sockets — MicroPython 1.9.4 documentation
# http_server.py
# httpサーバーとして動かすモジュールです
import socket
import machine
import hello
import sys
def run_pin4_server():
html = """<!DOCTYPE html>
<html>
<head> <title>Run Pin4</title> </head>
<body> <h1>Run Pin4</h1>
</body>
</html>
"""
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('listening on', addr)
try:
while True:
cl, addr = s.accept()
print('client connected from', addr)
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
hello.l_chika()
response = html
cl.send(response)
cl.close()
except KeyboardInterrupt:
pass
finally:
s.close()
print("close server socket")
sys.exit(0)
boot.pyはMicropythonを入れたボードが最初に実行するスクリプトです。Wifiの接続はこちらに書いておくと起動時に自動的に接続してくれるので便利です。
# boot.py: Micropythonを入れたボードが最初に実行するスクリプト
# これで動きますが一度しか実行できない不具合があります。まだ潰してません。。
# connect wifi
import network
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("[ssid]", "[ssidのシークレットキー]")
print(sta_if.ifconfig())
import http_server
http_server.run_pin4_server()
書いたスクリプトはESP32へアップロードする必要があります。こちらもIntrefaceあたりでご勘弁下さい。。
(一言だけいうと、adafruitのampyというライブラリを使ってアップロード可能です。boot.py, http_server.pyをそれぞれアップロードして下さい。)
MicropythonのURLをamazon-dashに登録
最後にamazon-dashにMicropythonでつくったサーバーのURLを登録します。登録は /etc/amazon-dash.yml
を書く必要があります。
登録することでamazon-dashに紐づけたDash Buttonを押すとURLへアクセスしてくれるようになります。今回はただURLへのアクセスをさせたいだけなのでgetですが、POSTメソッドでjsonを送るなども出来ます。かなり高機能です。
# amazon-dash.yml
# 注意:この設定は実は試していなくて動くことを想定して書いてます。動かなかったらすみません。
# ---------------
settings:
delay: 10
devices:
[Macアドレス]: # Url Webhook example
name: esp32_dashbutton_l_chika
url: 'http://[esp32のIP]'
method: get
content-type: plain
ここまでで、ESP32を電源に接続して起動するとWi-Fiに接続し、自力でhttpサーバーになります。URLを叩けばLチカするはずです。Amazon Dash Button側も連携ができていれば URLを叩いたときと同じようにLチカするはずです。
問題点
ここではコード内に書いた不具合以外の問題です。
Amazon Dash Buttonを押すと毎回通知が来る問題
期待通りに動くようにはなりましたが、問題点が一つ。Amazon Dash Buttonをハックして利用する時の共通の問題です。
ボタンに登録する商品を登録しないでamazon-dashライブラリにボタンを押した情報を拾わせることになります。その際に、Amazonアプリ側では、まだ商品が登録されていない状態でストップしているので、それでボタンを押すと商品は注文されませんよという通知がアプリを入れたデバイスに毎回届くようになります。
解決策として通知を無視するでも良いのですが、ボタンを押したタイミングでボタンがAmazon側と通信するので、その通信を遮断すればいいのですが、ルーターなどの設定がやや必要になります。ルーターの外から入るのではなく、中から防ぐ必要があるので家庭用ルーターだと設定が難しいかもしれません。
終わりに
ESP32に入れたMicropythonとハックしたAmazon Dash Buttonを連携してLチカをしてみました。
Micropythonを扱うのもそれほど難しくない上にサードパーティのライブラリも見かけるようになって盛り上がりを感じてます。
最近だと機械学習のライブラリがあったり、利用の幅が広がってるのでESP32+Micropythonの組み合わせは今後よく見られるかもしれません。(この話はunagi.pyで得た知見で、unagi.py参加の記事も近々あげようと思います)
- Unagi.py@豊橋 東海ちほー合同大勉強会 - connpass
- MicroPythonで作る人工生命っぽい何か
- jczic/MicroMLP: A micro artificial neural network multilayer perceptron (used on ESP32 and Pycom modules)
Amazon Dash Buttonも定価は500円(初回に商品が注文されるとその分割り引かれるので一度注文してからハックした方がお得)で、たまに100円で販売されている時もあるので、タイミングを見計らって買っておくといいかもしれません。 ただ塩漬けしすぎるともしかしたら使えなくなるかもしれませんが。
余談ですが、Dash Buttonを使うとインターネット越しにサービスを利用しているのにもかかわらず、ボタン一つで実行されるのがどうも物理的にも心地よさを感じます。これなしではいられないわけでもないのですが、なんとなく押したくなります。
IoTデバイスではあるのにIoTっぽくない感じです。これが有線LANならサイバーパンクっぽかったかも(しれないですかね?というかESP32の話だったのになぜかボタンの話で締めてます)
宣伝ですが今年の終わりのIoTLTに参加できそうで、夏場のお風呂IoTの時にアイディアを頂いていた 蛇口IoT をやってみることにしました。どんなものになるかは当日で。ぶっちゃけ今まだ動くものもできていないので、生暖かい目で見ていただけると幸いです。
IoT縛りの勉強会! IoTLT vol.46 @オムロン - connpass
明日は @wamisnet(わみ)さん です。2のneoは@gadgetrenesas_suzuki(がじぇるね鈴木)さん 、3のmitzは@a-yoshinoさんです。よろしくお願いします!