この記事は Retty Advent Calendar 2019 の20日目です。
昨日は、平野さんの『Retty データ分析チーム - 立ち上げ2年目の振り返り 〜データプラットフォーム/データ民主化/統計モデル〜』でした。
はじめまして。20卒エンジニアとして現在 Retty でインターン中の幸田です。
とりあえず参加登録して何を書こうか迷いましたが、通っている大学の研究室で運用している入退出管理システム(電子錠)を自作したので、その話をしようと思います。
経緯
研究室配属されてすぐ「部屋の鍵をどうしようか」という話になりました。
合鍵を人数分作るとなると、それなりに費用がかかったり、人数分の鍵を管理するのが面倒です。
3年生も合わせて20人程度になってくると、紛失する人も出てきたりします。
次に Qrio のようなスマートロックの導入を考えたのですが、弊研究室のドアはサムターンが「ドアノブ付きタイプ」で非対応でした。
(その他の対応サムターンについてはこちらのページに詳しくまとめられています。)
知る限りではこのタイプに対応したスマートロック製品がないので、ドア IoT のハードルがかなり上がります。
もう自作するしか手がなかったので作ることにしました。1
全体の構成
最終的に仕上がった構成はこんな感じです。
使いたい技術で好きなように作りました。
電子錠
電子錠本体は、RaspberryPi3 Model B+
にサーボモータ、リードスイッチ、カードリーダーを接続したものです。サーボモータを制御するプログラムは Python で書きました。
カードリーダーは2台使用しており、ドアの内側と外側につけることで 在室
又は 外出
の状態を管理しています。なぜ管理しているのかは後ほど。
オートロック にするため、リードスイッチをつけてドアの開閉状況を取得しています。
カードキー
全員が持っている学生証や ICOCA の idm
をデータベースに登録して、それをキーとして認証させる形にしました。
まだ対応させていないですが、対応させれば ApplePay などに登録されたカードでも解錠可能です。
副次的なメリットとして「鍵を紛失した時のリスクを低減できる」というのもあります。
これはデータベースから対象のデータを削除すれば、そのカードで入退出できなくなるからです。
検知するやつ
Amazon Dash Button のハックが流行っていた頃よく利用されていた maddox/dasher
ですが、久しぶりにリポジトリを覗いてみると Nekmo/amazon-dash
というのが出ていました。
設定はすべて yaml
形式で記述できて、Docker イメージも用意されています。
在室管理
大学の研究室でお馴染みの「在室表示板(ホワイトボード)」ですが、電子錠にすることでイイ感じにできそうだったのでイイ感じにしました。
次の機能紹介で説明します。
機能紹介
単に「電子錠」として動かすだけでなく、いくつか機能をつけたので紹介したいと思います。
Web 管理画面
メンバーの登録・編集・削除を行うための簡単な管理画面を Flask
で作りました。
フロントはみんな大好き Bootstrap + jQuery
です。
ちなみに idm
は自分で調べてから手動で入力する必要があります。
WebUSB
とかを使えば Felica リーダーを接続して、そこから読み取って登録とかができそうですが、まだ実装できていません。
ダッシュボード機能
どこからでも誰が居るのか確認できるように、在室状況をオンラインで見れるようにしました。
入り口にモニターアームでモニタを設置して、別の RaspberryPi で kiosk 端末を作って表示させています。
ホワイトボードの磁石を動かさなくてもいいので、便利ですね。
Slack 連携機能
ドアに設置されたボタンを押すと、Slack の通知用チャンネルにこんなメッセージが流れます。
Slack の InteractiveComponents と連携させており『ロック解錠』を押すことで、わざわざ入り口まで迎えに行かなくても鍵を開けることができます。
ちなみにこの場合、自席から大きめの声で「鍵あいてまーす!」と叫んで、自分でドアを開けて入ってきてもらいます。
画像のように「誰が対応したか」というログも残ります。
メッセージが上書きされる形なので、誰かが対応すると Slack の通知バッジが消えるのも地味に便利です。
工夫したところ
Slack の解錠ボタンと RaspberryPi を繋ぐ部分を少し工夫しました。
具体的には Slack のボタンが押された時に、こちらが指定したエンドポイントに Slack から POST
リクエストが送られてくるのですが、このエンドポイントをどこにしようかという話です。
直接 RaspberryPi にエンドポイントを設定するのが手っ取り早そうですが、電子錠をインターネットに晒したくなかったので間に MQTT
を挟むことにしました。
MQTT や MQTT ブローカーについては、『初めての MQTT』 が分かりやすかったので貼っておきます。
まず Slack からのリクエストを受け取るための API を立てて、「解錠ボタンが押された」というリクエストを受けたら対象の topic
に publish
します。
RaspberryPi 側でも同じ topic
を subscribe
することで、インターネットに晒さずにイベントの発生を検知できるという仕組みです。
解錠までに時間がかかりそうだなと思っていたのですが、Slack のボタンを押下してから1秒程度で解錠されるので実用?範囲内でした。
とある日のこと…
ある日の20時頃、自宅で作業中に研究室の呼び出しボタンから訪問通知がありました。
どうやらこの日は先生が残っており、電気をつけたまま少し外出していたそうです。
この時間の訪問はほとんどが守衛さんで、電気がついていると来ます。つけっぱなしで誰もいないと後日怒られます。
訪問通知が来た瞬間に「アッ」と思ってリモートで照明を消灯させました。2
これで事なきを得た(得てない)と思っていたら、こんな Slack が飛んできました。
守衛さんが研究室に入って室内を確認しているタイミングで、ちょうど僕が照明を消してしまった らしく、パニックになっていたそうですw
更に 室内を確認している間にオートロックによって施錠された と。
室内から解錠できるボタンを一時期付けていたのですが、必要なさそうだったので外した直後の出来事でした。
さいごに
守衛さん、怖い思いをさせて本当にごめんなさい。
IoT はやめませんが中から解錠できるボタンをつけておきます。