IoTなスマートロックシステムをreact-native、アリババクラウド、3Dプリンターで作った


3年くらい前少し流行ったスマートロックシステムを自作しました。結構前に作ったやつをようやく記事にします。

作ったもの

スマホアプリ鍵開けデバイスを作成しました。アプリ名はGenkanです。ダサい。

以下のリンクはデモ動画です。Qiitaに動画直接埋め込みたい。


実現したかったこと

最近入居したアパートの鍵がちょっと大きめで扱いにくさを感じていたのでスマホからドアを開けられたら良さそうだなと思っていたのが始まりです。

諸々のコスト

期間: 2週間くらい
費用: 20000円程度

項目 値段(円)
RPi Zero wh 4000
サーボモーター 500
3Dプリント料金 15000
合計 19500

パーツはだいたいアキバの秋月か千石電商で揃えました。

既製品

これらを実現するために、まずどんなものが売っているのかを調べました。

Akerun
Qrio
gogogate2

概ね以下のように鍵のツマミ(サムターン)を物理的に回す装置を扉に貼り付けてスマホで操作するタイプです。

こんな感じをイメージしながら作りました。

先人の知恵

2015年の記事です。カッケエ。別記事のコメント欄で大阪の商社さんから声がかかっていて夢がありますね。
https://qiita.com/toshi-saito/items/ef7fd9a2154f7db92831

2017年末の記事です。しっかり作っていてめちゃくちゃすごい。
https://ehbtj.com/electronics/diy-smart-lock/

2017年5月の記事です。スマホでsshしてRPiにログインする方法なんてのもあるんですね。
https://www.indetail.co.jp/blog/170519/

技術

以下の技術等を使ってシステムを設計/製作しました。

  • MQTT
  • RPi zero
  • react-native
  • golang
  • CI
  • 3Dプリンター

構成

なるべく管理する対象を減らしたいので、シンプルにデバイスとスマホの間でMQTTのやりとりをするだけのものにしました。

最初の設計はこんな感じにノートに書いていました。

玄関にコンセントがあるので電源はケーブル這わせてコンセントから取ることにしました。

MQTT

MQTTとは、ソケット通信を開きっぱなしにして双方向の通信を行うためのプロトコルです。通信の中間にMQTTブローカーというサーバーを置いて双方向の通信を実現します。

そしてこの MQTTによりデバイスへのpush型の通信が可能になります。
詳しくは時雨堂さんの https://gist.github.com/voluntas/89000a06a7b79f1230ab が非常に分かりやすいです。

Alibaba Cloud IoT Platform

MQTTブローカーにはAlibaba Cloud IoT Platformを使用しました。

IoT Platformでは(1) デバイス管理(2)MQTTでpublish/subscribeなどが可能です。

MQTTをsubscribe/publishしてる様子はこんな感じで見ることができます。

もう少し詳しい使い方についてはIoT Platformを日本版Alibaba Cloudで使うをご覧ください。

react-native

最初のアプリUIです。最終版は上の画像です。コンポーネントキットはnative-baseを使用しました。

アプリからデバイスを操作するという要件なので、サクッとreact-nativeでスマホアプリを作りました。ただMQTTでイベントを発生させるだけのアプリです。

一番有名そうなeclipseのjsライブラリlocalStorageに依存していてそのまま使うことができないので別のものを使う必要があって、探した結果react-native-mqttを見つけたのでこれを使いました。

使用したreact-native-mqttはpaho.mqtt.javascriptをラップしているので基本的な使い方は同じです。

ちょっとハマったところ

client.connect({ onSuccess: this.onConnect, userName: userName, password: password, useSSL: true })

golang

クロスコンパイル環境が優秀だしリリースもGitHub Releasesにバイナリ投げるだけで済むのでgolangを使いました。

MQTT環境だとErlangがよく使われるらしいのですが、そんなにデバイスが増える予定もないのでやめました。

まず、golangでサーボモーターを回します。golangからRPiのGPIOを操作するためにこの記事を参考にしてgobot を使いました。

このgobotは標準でMQTTをサポートしています。サイコー。

公式ドキュメントの通りにやれば簡単にsubscribeできます。

TravisCI

リリースは自動でやって欲しいのでTravisCIに任せます。

作るデバイスは扉に固定するものなのでインターネット越しにデプロイできるようになりたいです。ですのでTravisCIから自動でGitHubReleasesにリリースするようにします。

以下のようなフローでリリースできるようにしました。

$ git tag v_1.0.0
$ git commit -m "Bump v1.0.0"
$ git push origin v_1.0.0

GitHub Releasesへのリリースはこの記事を参考にしました。

RPiの上にはupdateManagerというプロセスを立てて、genkan/updateをsubscribeします。TravisCIからリリースされたバージョンをpayloadに包んでgenkan/updateに投げます。

このTravisCIからpublishするプログラムがpushNewVersion.goです。TravisCIのジョブ上でgo buildして実行します。

新しいバージョンを受け取ったら、exec.Command().Run()./updater.shを実行します。このupdater.shは新しいバージョンの.tar.gzをダウンロード、解凍して既存のプロセスをkillして新しいバイナリを起動します。

ケースを3Dプリント

一番最初、市販のタッパーに無理くり穴開けてプロトタイプを作ったのですがさすがにしんどかったので、イケるんちゃうかと思ってモデリングから3Dプリントまでやってみました。

DMM.AKIBAでイカしたケースを3Dプリントしました。

一番下の直方体がサムターンを回すツマミ部分です。印刷には1セット3時間くらいかかったような気がします。

BLE

インターネット経由のMQTTが動いたのでBLEで動くようにもしたのですが、サーボモーターとBLEの同時使用にRPiが耐えられなくてraspbianが再起動してしまうので結局インターネット経由でしか使えませんでした。でもさほど遅延はなかったです。

まとめ

3Dプリント代が高すぎた・・・20000円はしんどい。

自作はめちゃくちゃ楽しかったのですが、鍵持たずに外に出てデバイスが死ぬと締め出されて大変(一回やった)なので、本当にスマートロックシステムが欲しかったら大人しく買いましょう!私は結局Qrioを使っています。