私の会社のサードパーティのモノのインターネットプロジェクトは、前のテナントから取得したドアロックを再インストールできなかったときに始まりました。 これは、新しいオフィスに移った後に学んだ小さなことの1つでした。
通常、人々は新しいお城の費用を支払うだけです。 しかし、私たちにとってはあまりにも浅く、誰もドアベルを望んでいませんでした。 さらに、私たちはエンジニアであり、ある種のハードウェアで遊びたいと思っていました。
目標は、電話またはウェアラブルガジェットでドアを開くことでした。 問題にアプローチする方法はいくつかありました。 理論的には、アプリケーション、別のプラットフォームへの統合、またはロックを開くためのシグナルを送信できるものを使用できます。
PebbleとiOSのChima Open Door
今日まで、私たちのドアの実験では、Slack、ネイティブiOSおよびAndroidアプリケーション、Apple WatchおよびPebbleと統合するためのソリューションを開発しました。 モバイルアプリケーションのアーキテクチャについて説明します。 最終製品が少し単純化しすぎていることは認めますが、私たちはそれをとても気に入っています!
IoTドアロックの設計アーキテクチャ
iOS / Androidアプリでボタンを押すと、正確に何が起こりますか? HTTPリクエストがクラウドサーバーに送信されます。これは、クライアントサーバーを介してドアベルデーモンにメッセージを送信する信号であり、その後、リレーボードにロックを開くように指示します。
従来、ドアロックは、ドアの横にあるボタンを押すことで開きます。 しかし、最新のテクノロジーでは、物理的なボタンをすぐに超えることができます。 図の
Doorlock Daemon
に信号を
Doorlock Daemon
物理ボタンに加えて、ハードウェアの選択のおかげで、クラウドトリガーとBluetooth Low Energy(BLE)トリガーの2つのトリガーを追加しました。
この記事では、ドアロックが依存するクラウドトリガーについて説明します。
ボタンのクリックから、Skygearサーバーに保存された記録まで
ユーザーがモバイルアプリケーションのドアを開くボタンをクリックすると、クラウドサーバーにアクセスします。
クラウドサーバーでは2つのことが起こります。 最初に、レコードが保存されます。 Skygear Cloud Databaseサーバーを選択しました。これにより、データをクラウドと同期できます。 サーバーは、ドアを開ける要求のログを保持します。
SKYDatabase *db = [[SKYContainer defaultContainer] publicCloudDatabase]; SKYRecord *openDoor = [SKYRecord recordWithRecordType:@"OpenDoor"]; [db saveRecord:openDoor completion:^(SKYRecord *record, NSError *error) { NSLog(@"saveOpenDoorRecordWithCompletion failed: %@", error); if (completion) { completion(error); } }];
レコードが保存されるとすぐに、 Skygear Cloud Functionsセットのafter_save関数が有効になり、サーバーに直接デプロイする必要なくクラウドでコードを実行します。
after_save
関数
after_save
、レコードが保存されたという事実によって呼び出されます。
def after_open_door_save(record, original_record, db):
は、タイプ
'OpenDoor'
レコード
'OpenDoor'
れるときに非同期的に呼び出さ
'OpenDoor'
ます。 この関数は、
'xxx-channel'
メッセージを投稿します。
@skygear.after_save('OpenDoor', async=True) def after_open_door_save(record, original_record, db): publish('xxx-channel', { 'source': 'record-after-save', 'data': record.get('data', None), })
Raspberry Pi上のノードクライアントとClojureサーバー
次のステップは、リクエストのリスナーを作成することです。 これが、Raspberry Pi上のNodeクライアントとClojureサーバーの時代の到来です。 Nodeクライアントは、指定されたSkygearサーバーチャネルでメッセージをリッスンします。 Clojureサーバーは、Raspberry Pi 3スキームにアクセスできる唯一のサーバーであり、Nodeクライアントはメッセージを受信するとすぐにClojureサーバーにリクエストを発行します。
Nodeクライアントスクリプトを次に示します。これには、特定のSkygear構成に関連するコードが含まれています。 Skygearのメインサーバーにアクセスするには、指定されたendPointとAPIキーが必要です。
skygear.on('xxx-channel', onReceiveOpenDoor)
は、チャンネル
'xxx-channel'
メッセージを受信したときの関数(
onReceiveOpenDoor
)のコールバックを意味します。
function onReceiveOpenDoor(data) { console.log('daemon-trigger-skygear: open door'); exec(`curl localhost:8090 --header 'X-Source: Skygear'`); } skygear.config({ endPoint: 'https://chimagun.skygeario.com/', apiKey: apiKey, }).then(() => { skygear.loginWithUsername('xxx', 'xxx').then(() => { skygear.on('xxx-channel', onReceiveOpenDoor); }); });
Clojureサーバーは、Raspberry Piの汎用入出力(GPIO)ピンを直接監視します。 GPIOはRaspberry Pi 3のピンです。GPIOはドアマグネットに接続する外部回路に接続されます。
Raspberry Piがどのようにドアを開けるかを示すClojureコードは次のとおりです。 Clojureサーバーは、Nodeクライアントからリクエストを受信すると、3秒間ロックを開きます。 ただし、この3秒間に新しい要求が到着すると、タイマーはさらに3秒間再配置されます。 時間がなくなると、ドアが再び閉じます。
; listen on unlock-chan for unlock events ; if a new unlock event is received before the 3000ms timeout, the door is kept open. (go-loop [unlock nil] (when unlock (sh "gpio" "write" "1" "1") (loop [[trigger _] [unlock nil]] (when trigger (log/info (str "Unlock triggered by " (:source trigger))) (recur (alts! [unlock-chan (timeout 3000)])))) (sh "gpio" "write" "1" "0") (log/info "Door Locked")) (recur (<! unlock-chan))) ; http event listener (run-server (fn [req] (>!! unlock-chan {:source (or (get-in req [:headers "x-source"]) :network)}) {:status 200}) {:ip "127.0.0.1" :port 8090})
注:SkygearはアメリカのAWSを使用していますが、ドアとRaspberry Piは香港にあります。 実際、私たちのリクエストである芝麻開門(Chima Open Door)は、ドアに届く前に世界中を旅します。
Raspberry Piを選ぶ理由
Raspberry Piを選んだ理由をお尋ねください。 Arduinoボードもオフィスにあるため、Arduinoボードも検討しました。 事実、特定のArduinoモデルを使用できなかったのは、Skygear JS SDKとデータを同期させたいためであり、この特定のArduinoはNodeサーバーのインストールを許可しなかったためです。
さらに、Raspberry PiはBluetooth Low Energyをサポートしています(つまり、3番目の方法であるBluetoothを使用してドアを開けることができます)。
Ourskyオープンソースサーバーレスプラットフォームと互換性のあるLinux Raspberry Pi
追加の統合
Ourskyの各従業員はSlackにアクセスできるため、アプリケーションが内部使用専用であることを考慮して、
/chima-open-door
カスタムSlack
/chima-open-door
コマンドを実装しました。
その後、他の同僚がプロジェクトに参加し、WatchOSアプリケーションとAndroidアプリケーションを作成しました。これらは内部プラットフォームに投稿しました。 アプリケーション内のボタンを押すことに加えて、iOS 3D、Today拡張機能、Androidウィジェット、さらにPebble統合に触れるなど、ドアを開くための代替方法も提供します。
それはそれが行われる方法です! 開発に飛び込む前に、逆電流(この場合はRaspberry Piの場合)と各統合のセキュリティという2つの要因を考慮してください。 たとえば、2要素認証用の自己実装オプションであるBluetooth Low Energy(BLE)を介したBluetoothアプリケーションへのアクセスも統合しました。 他の統合の中でも、ドアが開いたときの通知(ドアベル、LED)を考慮することができます。
上記の技術について知りたい場合は、お気軽にご連絡ください!
同僚のDavid Ng、Boris( akiroz )、Brian(b壹貳參零零零)、およびMay Jungに、Androidアプリケーション、スキームの実装、Clojure、Pebbleアプリケーション、およびこの記事のテキストにそれぞれ感謝します。 これはチームワークです!
リポジトリ/ファイルへのリンク
→ CloudCode
→ iOSクライアント
→ Androidクライアント
→ ペブルクライアント