※この記事は、ソラコムのSoftware Design 誌 巻頭特集記念リレーブログ5月10日分です
※続編を書きました! Slackでトイレを予約できるシステムをサーバーレスで構築した話
皆さんこんにちは!
サーバーワークス IoT担当の中村です。
4月末くらいから急に暖かくなってきましたね。最近の天候の変わり具合は本当によくわかりません。
さて、今日はSORACOM AirとRaspberry Piを使ってトイレの空き状況を物理的に可視化してみます。
14時過ぎのトイレ争奪戦
当社は昼休みはいつ取っても良い事になっていますが、比較的13時~14時に昼食を取る社員が多いです。
昼食を取った後に来るものといえば、眠気と便意です。こうなると大変なのが、トイレの個室(2部屋)の争奪戦です。
当社は引っ越してからオフィスが横長になったこともあって、席とトイレの間の距離は比較的長めです。そのため、トイレまで歩いた結果個室が埋まっていた場合、トイレまで歩く時間を無駄にしてしまったショックと、今後いつ個室が空くのか、という緊張感で午後働く気力がなくなってしまいます。
…というわけで、現在TWE-Lite 2525a(加速度センサー)を使用して、トイレの個室の扉の開閉を検知しようとしています。トイレの個室を増やすことはオマルでも用意しないかぎり物理的に困難なので、まずは満室のトイレに向かうという無駄足を減らそう、といった取り組みです。
TWE-Lite 2525aは無線モジュールと3軸の加速度を検出できる加速度センサーがセットになった製品で、小型な上、長い期間(年単位)で電池を持たせることができます。
トイレの個室の扉の開閉は、このセンサーをトイレの扉に貼り付け、検出される動きによって閉じたのか、開いたのか、を予測します。(今のところ精度は8割程度です)
いざ可視化
さて、センサー回りが少し不完全なシステムではありますが、このシステムをSORACOM Air + Raspberry Piと連携して、トイレの空き状況を可視化してみましょう。
現状のAWSの構成
まず、現状のシステムから紹介します。
図のように、TWE-Lite2525aから中継器を経てEdisonへ、そしてEdisonからインターネット経由でAWS IoTにMQTTを使ってセンサーのデータを送信(Publish)しています。AWS IoTで受け取ったあとは、Kinesis Firehoseに流し、Kinesis Firehoseの機能を使ってRedshiftにデータを貯めています。
TWE-Lite周辺については、前回の記事に詳しく記載しておりますので興味の有る方はぜひ御覧ください。
(図の凡例にSORACOM Airがありますが、この図にはSORACOM Airは出てきません。次の図に出てきます)
新しいAWSの構成
データの貯める仕組みは上記の通りです。
この構成において、Raspberry Piからトイレの状況を取得する方法として、今回はRaspberry PiでSORACOMの回線を使ってAWS IoTのtopicをSubscribeすることにしました。
Raspberry PiとSORACOMが加わっただけですが、構成がこちらです。
SORACOMのSIMは、富士ソフト社のFS01BUを使ってRaspberry Piで利用しています。
AWS IoTがMQTTブローカーになってくれるため、任意のTopicをSubscribeしていれば、そのTopicにメッセージがPublishされた時、Publishされた内容を受け取ることができます。
具体的には、Raspberry PiからAWS IoTのtoilet TopicをSubscribeすることで、EdisonからAWS IoTにtoilet TopicがPublishされた時、Publishされた内容をRaspberry Pi側で受け取ることができるようになります。
Raspberry Piの構成
続いてRaspberry Piの構成です。
今回はシンプルにLEDを2つ用意し、LEDをそれぞれの個室に割り当てました。向かって左側の個室が埋まっているときは左側のLEDが、向かって右側の個室が埋まっているときは右側のLEDが光ります。
Raspberry PiとLEDは以下のように接続します(モデルはRaspberry Pi3 Model Bを使用しています)。
プログラム
LEDを繋いだら次はプログラムです。
切腹します!という割に中々切腹しない人が、「これからはPythonがアツい!」と言うのでPython3で書きました。MQTTのクライアントにはpahoを使っています。
ざっくり流れを説明すると以下の様な感じです。
- 23ピンと24ピンをアクティブにする
- JSONを受け取ったらParseする
- statusが0(空)の場合はLEDを消す
- statusが1(満)の場合はLEDを付ける
- 2に戻る
import paho.mqtt.client as mqtt import wiringpi as pi import ssl, time, json # AWS IoT host = 'xxxxxxxxx.iot.us-west-2.amazonaws.com' port = 8883 cacert = './cert/rootCA.pem' clientCert = './cert/certificate.pem.crt' clientKey = './cert/private.pem.key' topic = 'toilet' # GPIO man_right_pin = 23 man_left_pin = 24 pi.wiringPiSetupGpio() pi.pinMode(man_right_pin, 1) pi.pinMode(man_left_pin, 1) def on_connect(client, userdata, flags, respons_code): """接続時のcallback関数 """ client.subscribe(topic) def on_message(client, userdata, msg): """受信時のcallback関数 """ data = json.loads(msg.payload.decode('utf-8')) print(str(data)) if data['devicePlace'] == 'ToiletRoomRight': if data['door'] == 0: pi.digitalWrite( man_right_pin, 0 ) else: pi.digitalWrite( man_right_pin, 1 ) if data['devicePlace'] == 'ToiletRoomLeft': if data['door'] == 0: pi.digitalWrite( man_left_pin, 0 ) else: pi.digitalWrite( man_left_pin, 1 ) if __name__ == '__main__': client = mqtt.Client(protocol=mqtt.MQTTv311) client.tls_set(cacert,certfile = clientCert,keyfile = clientKey,tls_version = ssl.PROTOCOL_TLSv1_2) client.tls_insecure_set(True) ### callback関数 client.on_connect = on_connect client.on_message = on_message client.connect(host, port=port, keepalive=60) client.loop_forever()
動かしてみた
LEDを繋いで、スクリプトも書いたら、実際に動かしてみましょう!
最初はスクリプト起動後しばらく眺めていたのですが、誰も個室に入らないので意味もなくトイレの個室をバタバタしてもらいました。
わかりずらいですが、右側のLEDが光っています。
まとめ
…というわけで、今回はRaspberry PiとSORACOMを使って、トイレの状態をAWS IoTからSubscribeしてみました。そして、SubscribeしたデータによってLEDを点灯・消灯させる、という事を行いました。
SORACOMを使うことで、NTTドコモ社の電波が届く限り、ネットワーク的な場所の制限はなくなります。特に、トイレ等は執務室から離れていることが多く、WiFiが届かないこともあると思います。ですが、SORACOMを使えばWiFiを気にせずに、さらにローコストでデバイスを設置できるようになりますね!
(トイレの個室増えないかな…)