【Raspberry Pi】MQTTで自宅のラズパイカメラを外出先から操作する

【Raspberry Pi】MQTTで自宅のラズパイカメラを外出先から操作する


MQTT Brokerを使えば外から家のラズパイを操作するのは簡単

家庭の同一ネットワーク内であれば、ラズパイの操作はネットワーク経由で簡単に操作できるが、出先から操作しようと思うとセキュリティの問題もありなかなか難しい。
だが、MQTT Brokerを使用すれば比較的手軽に実現できる。
今回はその方法についてまとめる。

全体の処理の流れ

  1. MQTT BrokerにHTTP Requestで実行を指示
  2. MQTT Brokerがメッセージを発行
  3. 家のラズパイがメッセージをトリガーに撮影
  4. 撮った写真をDropboxにUpload
  5. スマホで写真を閲覧する

4.5.については以下の記事で既に紹介しているので参考にしてほしい。
【Raspberry Pi】ラズパイでUSBカメラを制御する
【Raspberry Pi】ラズパイからDropboxへファイルをアップロードする
今回は1.2.3.のやり方について説明する。

Beebotteの設定方法

今回はMQTT BrokerとしてBeebotteを使わせてもらう。
理由は、1日50000メッセージまでは無料で利用できるからだ。

Beebotte
こちらからログインできるのでアカウントを作成しよう。
ログインしたらChannelsのメニューからCreate Newで新しいチャンネルを作成しよう。

上から
チャンネル名:raspi_oneshot
チャンネル名説明:camera oneshot
Configured resources名:oneshot
Configured resources説明:camera oneshot

としたが、各自適当な名前をつければいいだろう。チャンネル名とresource名は、後ほど使うので覚えておく。
SoSは受け取り側がオフラインのときにデータを保存しておき、受け取り側がオンラインになったときに送信する機能らしいが、今回は不要。
チャンネルの作成が終わったら、Tokenが取得できるのでこちらもメモしておく。

Beebotte 発行のWebAPIを叩いてみる

URL: https://api.beebotte.com/v1/data/write/[作成したChannnel名]/[resource名]?token=[取得したトークン]
Method: POST
Content Type: application/json
Body: { "data": "oneshot" }

なので、curlコマンドを使える場合は以下のコマンドを実行してみよう。

$ curl https://api.beebotte.com/v1/data/write/raspi_oneshot/oneshot?token=token_XXXXXXXXX -X POST -H "Content-Type: application/json" -d '{"data": "oneshot"}'
成功していれば、trueが返ってくるはずだ。

ラズパイ側でメッセージを受け取る

いろいろ方法があるようだが、私はrubyを使った。
rubyがインストールされていない場合は各自調べてほしい。
私のラズパイ環境では、

$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [armv7l-linux-eabihf]
だった。beebotteのGemを使っているのでインストールする。
$ gem install beebotte

作成したスクリプトは以下のようになった。
参考:Amazon EchoとRaspberry Piで部屋の照明を制御する #おうちハック

require "rubygems"
require 'beebotte'

s = Beebotte::Stream.new({token: "token_XXXXXXXXXXXXX"})
s.connect()
s.subscribe("raspi_oneshot/oneshot") #[channel name/ resouce name]

s.get { |topic, message|
  if message.include?("oneshot")
    value = %x( "[ラズパイで撮影してDropboxにあげるスクリプト].sh" )
    puts "oneshot"
  end
  puts "Topic: #{topic}\nMessage: #{message}"
}
ラズパイで撮影してDropboxにあげるスクリプトの作成方法は別記事で紹介しているので参考にしてほしい。
【Raspberry Pi】ラズパイでUSBカメラを制御する
【Raspberry Pi】ラズパイからDropboxへファイルをアップロードする
curlコマンドでWebAPIを叩くと、受け取り側のラズパイで”oneshot”が画面に表示されれば成功だ。

実行するWebページを作成する

ここまでで、出先からMQTTメッセージを発行して、ラズパイで写真をとってDropboxにUploadできるようになった。
しかし、毎回curlコマンドを実行するのも面倒。スマホから手軽にできるようにしたい。
そのために実行するWebページを作成する。

<!DOCTYPE html>
<html>
  <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  </head>
<body>
<div class="container">
    <div class="contents margin">
        <button id="oneshot" class="button"  style="WIDTH: 200px; HEIGHT: 60px" >ボタン</button>
    </div>
    <hr><br><br>
    <div id="output"></div>
</div>
<script type="text/javascript">
//ボタンが押された時のイベント
document.getElementById('oneshot').addEventListener('click', function(){
oneshot();
});

function oneshot(){
    var url = 'https://api.beebotte.com/v1/data/write/raspi_oneshot/oneshot?token=token_XXXXXXXXXXXX';
    var param = {
        "data" : "oneshot",
    };
    const headers = new Headers( { "Content-type" : "application/json" } );
    return new Promise((resolve, reject) =>{
        fetch(url, {
            method : 'POST',
            body : JSON.stringify(param),
            headers: headers
        })
        .then((response) => {
            target = document.getElementById("output");
            target.innerText = "OK"
        })
     });
}
</script>
</body></html>

これを.htmlファイルとして保存し、Chromeなどで開いてボタンを押すとラズパイにメッセージが送信される。
channel名やリソース名やトークンは自分の環境に合うように変更してね。
これをWebサーバに配置するなり、AWSのS3に静的ページとして配置するなりしておけばスマホから実行可能。
もちろんページのURLを公開してしまうと勝手に家のカメラ撮影されてしまうし、トークンも丸見えなので扱いには気をつけてください。


よかったら「いいね」お願いします!
Text by Takashi Yoshida