RaspberryPiでスマートホーム 〜JavascriptでMQTTを使って指令を送る〜

更新履歴:
2019/09/12 AWSの画面を最新版に合わせて更新しました。PahoMqttとAWSSdkを新しいバージョンにしました。
2017/12/18 新規作成。

前回AWS IoTを使いMQTTでJSONデータをラズパイ側で受信、USB赤外線リモートアドバンスを使って照明の操作ができるようになりました。今度はJSONデータを組み立てて送信する側を作成したいと思います。

いろんなデバイスから送信したいので、HTMLとJavascriptを使って送信することにしました。これならWebSocketに対応したブラウザがあればどの端末からでも操作できるようになります。

準備

IAMユーザーの作成

まずAWS IoTにMQTTでデータを送信するために、今回のアプリ(送信側)専用のIAMユーザーをAWSで作成しておきます。AWSにログインし、IAMの画面に行きます。

画面左のメニューで”ユーザー”を選択し、”ユーザーを追加”ボタンを押します。

”ユーザー名”はここでは”homeapp”としています。今回はJavascriptからの送信に使うので”プログラムによるアクセス”にチェックを入れます。”次のステップ:アクセス権限”ボタンを押して、次へ進みます。

”既存のポリシーを直接アタッチ”を選択し、検索窓で”iot”を検索して出てきた”AWSIoTDataAccess”を選択します。”次のステップ:タグ”を押して次へ。

今回はタグは必要ないので、”次のステップ:確認”を押して進みます。

確認画面です。問題なければ”ユーザーの作成”を押します。

これで、JavaScriptからAWSIoTへアクセスする用のユーザーができました。

”アクセスキーID”と”表示”を押すと表示される”シークレットアクセスキー”は、Javascriptからの呼び出し時に使用するのでコピーしておきます。

作ってみる

JavascriptでAWS IoTに接続

AWSを呼び出す場合はURLを署名する必要があり、以下を参考にします。

”ウェブアプリケーションでの WebSocket プロトコルの使用”に書かれているコードを”SigV4Utils.js”という名前で保存して、呼び出して使えるようにしておきます。以下のコードです。

これを使ってアクセス先のURLを組み立て署名、そこへWebSocketで接続、JSONを送信という流れになります。

以下のスクリプトを”homeapp.js”という名前で保存します。

(アクセスキー)、(シークレットキー)、(エンドポイント)、(リージョン)は自分のものに置き換えておきます。

(アクセスキー)、(シークレットキー)は先ほどIAMでユーザーを作成したときに最後に表示された”アクセスキーID”と”シークレットアクセスキー”です。

(エンドポイント)は前回ラズパイを登録したときに指定されたものです。

AWSのサービス一覧で”iot”で検索、”IoT Core”選択

IoT Coreの画面で”管理”→”モノ”をクリック、登録したラズパイを選択。

”操作”をクリック、表示されたHTTPSがエンドポイントになります。

(リージョン)は東京なら”ap-northeast-1”になります。

次に画面を作ります。

AWS IoTのJavascript用SDKと、前回も使用したPaho MQTTのJavascript版を使用します。いずれもCDN経由で使ってます。また先ほど保存した2つのスクリプトも読み込ませます。

とりあえずこんな感じです。何も飾ってないのでデザインはちょっとださいですが…

各コンポーネントがクリックされた時に送信するようにしています。

テスト

上記3つのファイル

  • SigV4Utils.js
  • homeapp.js
  • homeapp.html

を同じフォルダに入れ、homeapp.htmlを読み込ませてテストします。ローカルでJavascriptを動かせない場合は、apacheでも使ってローカルにWebサーバーを立てましょう。

照明をつけて見ます。つきました!

前回使ったAWSのテスト用ページも使うと便利です。トピックに接続して監視しておくと、メッセージが来ると表示されるはずです。

もしメッセージが来なければ送信側の問題、メッセージが来てるのに照明がつかなければメッセージが間違っている、もしくはラズパイ側の問題、と原因の切り分けが簡単になります。

運用する

これでブラウザから家の照明を操作できるようになりました。

レンタルサーバーに置けば外からでも…

このHTMLとスクリプトをレンタルサーバーにでも置いてアクセスできるようにしておけばどこからでも操作できるようになります。もちろんBasic認証などパスワードかけとかないとやばいですけど…

ただ、外からだと本当に照明がついたかどうかはわからないんですよね…赤外線リモコンだと命令送るだけでステータスが取れません。WEBカメラで見れるようにするとかしないといけないですね。

あとページを表示したままの場合、スリープするとWebSocketの接続が切れるので、ページをリロードしてやる必要があります。

感想

接続先はAWSIoTになるのですが、接続時にURLを署名しないといけないのが面倒ですね。と、いってもライブラリ呼び出すだけではあるんですが…

前回のコマンドラインで照明がついたり消えたりも感動しましたが、今回のWEBページをクリックしたら照明がつく、というのもなかなかのものです。他にも赤外線リモコンの家電があるので随時追加していこうと思います。

追記

PCの電源のオン・オフができるようになりました。