インターホン内部基板を電気的にハックしてAWS IoTに接続し、Slack通知とおしゃべり機能を追加、Amplify WebアプリとAlexaから解錠操作までできるようにIoT化したお話です。
完成品の紹介
ハックされているのは外見からは分からないようになっていますが、集合玄関で部屋番号が押されて呼び出しがかかると、Slackに通知が飛びます。
呼び出しがかかっている時にWebアプリからUnlockボタンをタップするかAmazon Echoに「アレクサ、セキュリティードア開けて」と話すと、インターホン内部に埋め込まれたマイコンにより「通話→解錠」のボタン操作が電気的に行われて集合玄関のドアが開きます。その際スピーカーから「どうぞお入りください」と音声が流れ、訪問者に伝えます。
ハックのきっかけと目標
これだけ色々と技術が出てきているにも関わらず、日本のマンションのインターホンはあまりスマートになっていないのが現状かと思います。最新の機種ではスマホとの連動操作も可能なようですが、現在稼働しているインターホンのほとんどはIoTの機能がなく、建物のシステム内に閉じています。
困ることといえば、料理などで手がふさがっている時に操作できない、鍵を持っていない時に集合玄関から入れない、等があると思います。さらに不在時に来訪があったことを知らせる機能がないのも不便です。これらの不便さから玄関呼び出しをADCや光・音センサーで検出したり、解錠ボタンをサーボモーターやSwitchBotを使って遠隔操作するハックをされている方もいらっしゃいます。
個人的には、内部機能としてあたかも元からIoTの機能があったかのようなハックが好きなので、今回は
- ハックされているのが外見からは分からず、元の機能も損ねない
- 呼び出しの検出、および集合玄関の解錠を電気的に確実に実行する
- AWSからセキュアに操作できるようにする
- 訪問者に音声でお知らせする
を目標にハックを進めることにしました。
全体アーキテクチャーとしくみ
インターホン基板に接続するマイコンにはESP32にMongoose OSを導入したものを使用し、呼び出し検出およびボタン押下操作を電子的に実行するのにフォトカプラを使用しています。音声はAmazon Pollyで予め作成したmp3ファイルをmicroSDカードに保存し、DFPlayerMiniを使用してスピーカーから再生しています。
クラウドのバックエンドにはAWSを使用しています。AWS IoT CoreをMQTTブローカーとして使用し、集合玄関呼び出し時にESP32からMQTTでtopic1(intercom/detect)にメッセージが発行されます。この際AWS IoT Core Rulesを使用してAWS Lambdaを自動起動してSlack通知を行っています。
解錠操作はAWS Amplify Webアプリ及びAlexaスキルからMQTTでtopic2(intercom/unlock)にメッセージを発行し、ESP32が受け取ってフォトカプラを動作させることで実現しています。
全体アーキテクチャー
集合玄関呼び出し検出
元の機能として、集合玄関で呼び出しがかかるとインターホンのパネルの緑の鍵マークLEDが解錠スタンバイ通知のために点滅します。このLEDから並列に引き出した線をフォトカプラの一次側(発光側)に抵抗を介して接続し、二次側(受光側)にプルアップしたGPIOとGNDを接続することで、検出時にGPIOがHighからLowになることで検出しています。検出時にはAWS IoTのtopic1(intercom/detect)にpublishするようになっており、後続のLambdaを自動起動してSlackやLINEに通知を出したり、topic1をsubscribeしたデバイスを動作させてお知らせをしたりと、色々なことが可能です。
集合玄関呼び出し時
解錠操作
元の機能として、集合玄関で呼び出しがかかっている最中に室内のインターホンパネルの通話ボタンを押すと訪問者と会話ができる状態になり、解錠ボタンを押すと集合玄関の自動ドアが開くようになっています。これらのボタンは共通のGNDを持っていたので3本の線で引き出し、フォトカプラの二次側(受光側)に接続し、一次側(発光側)は2つの別々のGPIOと共通の抵抗を介してGNDに接続しています。これらのGPIOを数百ミリ秒の間隔をはさんでHigh→Lowすることで人間のボタン押下動作を電気的に実現しています。
GPIOの制御はAWS IoT Coreのtopic2(intercom/unlock)にメッセージが発行された時に発動するようになっています。AWS Amplifyで作成したWebアプリはS3にホストされているApp.jsがAmazon Cognitoの認証を経由してAWS IoTへ、Alexaスキルの方はIntentを定義しているLambdaのPythonコードがboto3を利用してAWS IoTへ、それぞれメッセージを発行するようになっています。
また、上記の発動の数秒前に、DFPayerMiniをシリアル通信で操作し、スピーカーから「どうぞお入りください、please come in」の音声ファイルを再生しています。スピーカーはインターホンのマイクの近くに配置してあり、訪問者にAmazon Pollyの合成音声を届けています。
解錠操作時
ハックの手順
ここから先を真似される方は自己責任でお願いしますね。
step
1インターホンの分解
左右のカバーを外して4つのネジをゆるめるとフロントパネルが外れます。
フロントパネルの分解
フロントパネルが外れたら埋め込みユニットの電源を切ります。電源スイッチがない場合はAC100Vラインを外すかブレーカーを切ります。それから埋め込みユニットとフロントパネルを接続しているケーブルを外します。
フロントパネルと埋込ユニットの分離
断線で火災を検出する機能がある機種の場合、電源を切らずにケーブルを外すと火災アラームが鳴るので注意が必要です。
基板とフロントパネルを固定しているネジやスピーカーのコネクタを外せば、基板を分離できます。
step
2インターホン基板の改造
今回は信号の解析などはやりません。基板を観察して簡単にハックできそうな箇所を探します。集合玄関呼び出しの検出に使えるのはリレー接点やLEDなどの状態が変化する箇所です。手で操作が必要なのは通話ボタンと解錠ボタンです。
基板の観察とハックポイントの決定
ハックする箇所が決まったらリボンケーブルをはんだ付けして接点を引き出します。(実際に使用したケーブルの色)
1 集合玄関呼び出し時に点滅する解錠ボタンのLEDの+(オレンジ)
2 集合玄関呼び出し時に点滅する解錠ボタンのLEDのー(赤)
3 解錠ボタンの接点(青)
4 通話ボタンの接点(緑)
5 解錠/通話ボタン共通のGND(黄)
インターホン基板から接点引き出し
step
3インターホン操作用電子回路の作成
ミニブレッドボード上にESP32開発ボード(ESP32-DevKitC)を配置して電子回路を作成していきます。集合玄関呼び出し時に1秒間隔で点滅する解錠ボタンのLEDにかかる電圧を調べたところ3Vだったので、フォトカプラの発光側のLEDの推奨動作順電流 IF=7.5mAを満たすように250Ωの抵抗を配置し、受光側はプルアップしたGPIOとGNDを接続しています。
上記の抵抗値を小さくしすぎると、インターホンパネル上の鍵マークLEDが電流不足で点滅しなくなります。また大きくしすぎるとフォトカプラが動作せず、呼び出しを検出できません。
解錠/通話ボタンの接点およびボタン共通のGNDは、別のフォトカプラの受光側に接続し、発光側はGPIOと抵抗をはさんでGNDに接続しています。IF=15mAとして抵抗は120Ωにしています。
DFPlayerMiniとESP32は電源、GND、そして今回は受信しか使用しないのでRxのみ接続しています。SDカードには01フォルダに001.mp3を配置しています。
インターホンとマイコンの電子的な接続
実際に完成した電子回路はこちらです。プリント基板に起こしてもいいと思いますが、1個しかつくらないのでブレッドボードのままにしています。
実際の電子回路
step
4ESP32制御プログラムの作成
今回はESP32にはMongoose OSを入れて使用していますので、制御プログラム(init.js)はCではなく簡単なJavaScriptでデバイスロジックを記述できます。init.jsの完全版はGitHubをご参照ください。
まずは以下のコマンドでESP32にMongoose OSをインストールし、WiFiに接続します。
mos flash esp32
mos wifi SSID PASSWORD
以下は集合玄関の呼び出しを検出するコードです。フォトカプラの受光側に接続したledPinはプルアップしてあるので通常時はHigh、検出時はLowとなります。Mongoose OSではGPIOのHigh→Low検出は便利なボタンハンドラーが用意されていますのでこれが利用できます。呼び出しの検出は即時、検出後の状態維持は15sにしています。呼び出しを検出するとtopic1にMQTTでメッセージをpublishします。
GPIO.set_button_handler(ledPin, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 20, function(x) {
if (!callState) {
callState = true;
let message = JSON.stringify({ });
let ok = MQTT.pub(topic1, message, qos);
print(ok);
print("-----Call detected, published to AWS IoT-----");
Timer.set(15000, false, function() {
callState = false;
print("-----Back to normal-----");
}, null);
}
}, true);
以下はtopic2にsubscribeし、メッセージを受け取った時に「通話ボタン押下 → 2s後に音声再生 → 4.5s後に解錠ボタン押下 → 9.5s後に通話ボタン押下(通話終了)」を電気的に実行するコードです。talk()やunlock()は短いdelay(Mongoose OSではusleep)をはさんでGPIOをHigh/Lowしています。
MQTT.sub(topic2, function(conn, msg) {
print('-----Received message from AWS IoT-----')
talk();
Timer.set(2000, false, function() {
play();
}, null);
Timer.set(4500, false, function() {
unlock();
}, null);
Timer.set(9500, false, function() {
talk();
}, null);
}, true);
Mongoose OSのAPIリファレンスはこちら。
step
5ESP32のAWS IoT Coreへの接続(プロビジョニング)
Mongoose OSがAWS IoT Device SDK for Embedded Cを含んでいるので、IAMでAccess Key IDとSecret Access Keyのクレデンシャルを払い出し、以下のコマンドを実行すれば証明書の発行や格納、Thingの登録、Policyの設定などすべてやってくれます。
mos aws-iot-setup --aws-region AWS_REGION
step
6電気工事
まずインターホンの埋込ユニットを壁から引き出します。
埋込ユニット
その後AC100Vラインを外し、適当な長さのVVFケーブルを使用してAC100Vラインを分岐させて埋込USB給電用コンセントを接続します。最後に埋込ユニットにAC100Vラインを接続しなおします。
埋込USB給電用コンセントの増設電気工事
AC100Vラインの分岐にはワンタッチコネクターがあると便利です。
step
7壁に埋め込んで完成
埋込USB給電用コンセントからマイコンにマイクロUSBケーブルで給電し、壁の中に入れて元通りにします。この時、マイコンから音声が再生されるスピーカーをインターホンのパネル基板のマイク近くに配置します。
埋込前のハック部品一式
これでインターホンハック完成です。外からはハックされているのがわかりません
ハック後の外見
今回使用したAWSサービス
AWS IoT Core
MQTTブローカーとして使用しています。Rulesはtopic1にメッセージが発行された時、Lambdaを起動してSlackに通知するのに使用しています。
なお、呼び出し検出時に自動で集合玄関が開くようにするには、topic1にメッセージが来た時にtopic2にメッセージを再発行するルールを作成して有効化しておくことで可能です。ルールの有効化・無効化の変更はAWSコンソールからのほか、AWS CLIやPythonスクリプトからも可能です。
# to enable rule
aws iot enable-topic-rule --rule-name "Republish_Rule_Name"
# to disable rule
aws iot disable-topic-rule --rule-name "Republish_Rule_Name"
import boto3
client = boto3.client('iot')
# to enable rule
response = client.enable_topic_rule(
ruleName='Republish_Rule_Name'
)
# to disable rule
response = client.disable_topic_rule(
ruleName='Republish_Rule_Name'
)
AWS Lambda
Slackに通知するのに使用しています。
AWS Amplify
解錠用Webアプリを作成するのに使用しています。裏でホスティング用にS3、認証にAmazon Cognitoを使用しています。
Alexa Skill
解錠用Alexaスキルを作成するのに使用しています。裏でLambdaを使用しています。
Amazon Polly
「どうぞお入りください」および「Please come in」のmp3音声ファイルを作成するのに使用しました。
AWSアーキテクチャーは以下の通りです。
AWSアーキテクチャー
今回使用した部品リスト
おわりに
2017年に初めて壁に埋め込み型のインターホンをハックしました。当時はアイホン製で何もわからない中恐る恐るやっていて、断線火災アラームが鳴って管理人が来てしまうというトラブルにも見舞われましたが、今回は2回目なので大きな失敗もなく最後まで完成させることができました。
ハック中の事故
前回はShadowを用いて通常モード、アレクサに解錠をお願いするモード、自動解錠モードをマイコン内部で切り替えていたのですが、今回は自動解錠モードにする必要がある時はtopic1とtopic2の連携をAWS IoTのRulesで行うようにしました。今回はESP32とMongoose OSを使用していますが、ESP32とArduino、ESP32とAmazon FreeRTOS、Raspberry PiとAWS IoT Device SDK for Pythonなどの組み合わせでも同じことが実現可能です。ただ、Mongoose OSを使うと断然に簡単で早いのでおすすめです。
しかしあれですね、こんなハックをせずとも便利なIoTインターホンが日本にもっと広まってほしいと切に願います。ちなみに今回のハックは10分で現状復帰が可能です。
なお筆者は今回使用したAWS、ESP32、Mongoose OSを使って楽しくIoTが学べるハンズオン講座をこれまで数百名の方にご提供してきております。ご興味ありましたら以下をごらんください。