IoTにおけるソフトと特徴
- Arduino
- イベント駆動
- MQTT
- 軽量プロトコル
- publish/subscribe型のMQ
Arduinoとは
- 無償で使えるマイコン用プログラム作成アプリ
- マイコン毎にアドオンがある(ex, ESP8266)
- スケッチ(=プログラム)はsetup/loopで構成
- setup: 電源入り後一度だけ呼ばれる
- loop: (電源切るまで)繰り返し呼ばれる
- 提供されているスケッチ例を改造して動かす
$brew cask install arduino
MQTTとは
- Message Queuing Telemetry Transport
- 非常に軽量なプロトコル
- 2000年代初めに登場し標準化
- TCP/IP上で動く
- publish/subscribe型のメッセージ転送
- IoT/モバイルに適する
- センサーデバイス
- Facebook Messengerで使われている
HTTPよりも
- 軽量(ヘッダが最小2バイト)1・優れた処理速度・省電力
- HTTPではヘッダのオーバーヘッドが高い
- AgostoのテストによるとHTTPSの10倍以上オーバーヘッドが低い
- IoTの利用場面に適している
- 貧弱な電波環境(通信帯域制限)
- バイト毎に料金・バッテリーを消費する環境
HTTPヘッダとの比較
$curl --head https://www.yahoo.co.jp/
HTTP/1.1 200 OK
Date: Tue, 18 Jul 2017 18:10:57 GMT
(中略)
$curl --head https://www.yahoo.co.jp/ | wc -c
703
- 最小まで減らすとしたら
HTTP/1.1 200 OK
の15byte - MQTTでは最小2バイト1
- 通信量が膨大になるほどこの10byteの差が意味を持つ
暗号化
- TLSを使った暗号接続が可能
- port: 8883
- ただし通信毎に認証が必要なので軽量さは失われる2
- メッセージ全体のサイズが大きいならヘッダの10バイト差は誤差
- MQTTとHTTPsどちらが適しているか要検討
HTTPとのすみ分け
protocol | 適した用途 |
---|---|
http | 1対1で画像など大きなデータをやりとりしたい, secureな通信がしたい |
mqtt | 複数台から小さいデータを大量にもらいたい |
Publish/Subscribe
- メッセージの送信者(publisher)が特定の受信者(subscriber)に直接メッセージを送信しない
- メッセージのやりとりにはBrokerと呼ばれる中継serverが必要
- サーバーがメッセージを保管するため受信側の状態に関係なくメッセージを送れる
- オフラインでもOK
- publisher/subscriberがMQTT client
- サーバーがメッセージを保管するため受信側の状態に関係なくメッセージを送れる
- 接続時のデバイスIDが被ると古い接続が切れる
出典: Securing MQTT - BuildingIoT 2016 slides
message(= topic + data)
- subscriberはbrokerへtopicの受信を申し込む
- 接続後一度だけで良い
- brokerはtopicへのpublishがあると接続中のtopicを申し込んだsubscriberへmessageを送信
- 過去分は送れない(最後のmessageはオプションで受け取れる)
- publisherにsubscriberのアクセス情報は通知されない
出典: Paho Python client for MQTT and G-code Visualization Talks, Chennaipy
topic
- 一般的に/(スラッシュ)で階層化3
- ex, tokyoA/temp
- ワイルドカード(#,+)
- mosquittoなどの一部ブローカーにはACL機能有り
QoS
- client間のメッセージ到達保証レベル(Quality of Service)
- 通常は0、コントロール系のメッセージは1以上、が基本
- 1以上はbrokerでstoreが必要
- Kafkaの例だが佐伯さんのスライドがわかりやすい
level | desc | example |
---|---|---|
0 | At most once(メッセージ到達保証無) | subscriberの受信失敗時のケアがない、など |
1 | At least once(届くけど重複するかも) | subscriberのACK受信失敗時に再送、など |
2 | Exactly once(確実に重複無く届ける) | transaction制御、速度低下 |
(閑話)ログの質が精度を分ける
- 米テックジャイアントのログ収集は実は雑
- 重複やロストは気にしない
- ログ設計はすごい。デモグラなど混ぜて1レコードに豊富な情報量
- 重複もロストも許さないログでディープラーニングにかけたら、モデルの精度がテックジャイアントより高かった
- precision/recallがほぼ1
- 1レコードは購買やPVなど基本情報のみ
- 日本向けサービス同士の比較なので、日本語の壁など外的要因な可能性も
※社外秘のため詳細は公開しません
MQTTブローカー
- OSS
- cloud
- 公開MQTTテスト用ブローカー
MQTTクライアント
- OSS
-
paho
- 様々な言語に対応
-
PubSubClient
- Arduinoクライアント
- 日本語のスケッチ例はこちら
-
paho
mosquitto & paho by Python
MQTT通信の実例
Macで下記セットアップ
$brew install mosquitto
# mosquitto起動のため以下のどちらかを実行
# bg
$brew services start mosquitto
# fg
$/usr/local/opt/mosquitto/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf
$pip install paho-mqtt
paho pub.py
Pythonクライアントのチュートリアルを真似つつ
pub.py
import paho.mqtt.client as mqtt
import time
client = mqtt.Client()
client.connect('localhost', 1883, keepalive=60)
client.loop_start()
while True:
client.publish('world/darai0512', 'test')
time.sleep(1)
paho sub.py
sub.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, respons_code):
print('connected')
client.subscribe('world/#')
def on_message(client, userdata, msg):
print(msg.topic + ' ' + str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect('localhost', 1883, keepalive=60)
client.loop_forever()
Let's try MQTT
$python pub.py &
$python sub.py
world/darai0512 test
world/darai0512 test
...