ラズパイとMESHで始めるお手軽IoT


Ubiregi Advent Calendar 2019 4日目はラズパイとMESHを使ったお手軽IoTを紹介します。

作るもの

MESHブロックの「ボタン」を押すと、Slackに決まったメッセージが投稿される、という非常に簡単なものを作ります。
応用としてはラズパイにモニタを付けてドアホンとして使う、見たいのはアリかなとか思っています。一人暮らしだと留守の間、人が訪問してきてるか分からない問題があり、代わりにMESHボタンを配置しておけば人が来たことをスマホに通知する、みたいなことができてよさそうです。

用意するもの(今回使ったもの)

  • MESHのボタンブロック
  • Raspberry Pi Zero WH(以下ラズパイ)
  • スマホ

前提条件

  • ラズパイでRaspbianが動くようになっていること
  • MESHアプリがスマホにインストールされていること
  • Slackのアカウントを持っていること

手順

ラズパイを「MESHハブ」にする

これに関しては公式が非常に手厚いので、そちらを参照した方がよいです。

Raspberry Piに「MESH ハブ」アプリをインストールする方法を教えてほしい – MESHサポート | 遊び心を形にできる、アプリとつなげるブロック形状の電子タグ

補足

今回使ったラズパイはZeroなので、ブラウザを立ち上げると大変重たいです。
ということで、上記手順のブラウザでアクセスする部分は通常のPCで行ない、
②Raspberry Piにログインしてダウンロード用のコマンドを実行する方法
のコマンドをコピーしてSSH経由でダウンロードするのが楽だと思います。

Incoming WebhookのURLを取得

事前に通知先のチャンネルを決める/作るなどしておきます。

次に、
SlackのIncoming Webhooksを使い倒す - Qiita
を参考にIncoming Webhookを追加してURLをコピーしましょう。
メモ帳でもなんでもいいのでURLを退避させておくことをおすすめします(次で使います)。

PythonでServerを書く

Pythonを使っているのは単純に僕がPythonをよく使うので使っている感じなので、同じことができれば言語は何でもいいです。
ちなみにRasbianはデフォルトでPythonがインストールされているため特にPythonそのものをインストールしたりする必要はありません。
なお、今回使用したPythonのバージョンはPython 2.7.13となります。

MESHからラズパイのプログラムを叩くための簡単なHTTP Serverを作ります。
今回はbottleという軽量マイクロWebフレームワークを使いました。

事前準備

ソースコード内で使用するライブラリをpipでインストールしておきます。
(requestsはSlackをたたきに行くときに使います)

$ pip install bottle requests

ソースコード

場所はどこでもいいので適当なところにファイルを作り、下記ソースコードを書きます。
名前は何でもいいですが今回はserver.pyとしました。
(「ラズパイ版MESHを使って、Apple Watchで操作するおしゃべりロボットを作る - Qiita」を参考にしました)

server.py
# -*- coding: utf-8 -*-

from bottle import route, run, template
import json
import requests

slack_settings = {
    # channel_nameは任意で変えましょう
    # こうしておくと他のチャンネルにも通知したくなったとき設定を増やしやすいのでこうしてあります
    'channel_name': {
        'url'    : '{「Incoming WebhookのURLを取得」の工程で取得したURL}',
        'botname': 'test',
        'icon'   : ':muscle:',
        'message': '<!here>\nMESHからの通知だよ'
    }
}

def push(setting):
    datas = {
        'username'   : setting['botname'],
        'icon_emoji' : setting['icon'],
        'text'       : setting['message'],
        'contentType': 'application/json'
    }
    payload = json.dumps(datas)
    result  = requests.post(setting['url'], payload)
    print(result)

@route('/post/slack/<command>')
def mesh_button(command):
    if command == 'channel_name':
        push(slack_settings['channel_name'])
    else:
        raise Error

run(host='localhost', port=8080, reloader=True)

サーバの起動

以下コマンドでサーバを起動します。特に難しいことは無いと思います。

$ python server.py

上手く起動すればこんな表示が出ます。

Bottle v0.12.17 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

試しにcurlで叩いて試してみましょう。python server.pyをしているコンソールを閉じてしまうとサーバが止まってしまうので、別コンソールを開きましょう(SSH接続してる場合も)。

$ curl http://localhost:8080/post/slack/channel_name

サーバを起動している側に

<Response [200]>
127.0.0.1 - - [04/Dec/2019 13:46:15] "GET /post/slack/channel_name HTTP/1.1" 200 0

というログが出ると思うので、出ていれば成功です。

MESH SDKからカスタムブロックを作成する

MESHではブロックと呼ばれる定型処理を線でつなぐことで処理を作っていきます。
(のちに設定します)
ということで、先ほど作成したserver.pyのURLを叩くブロックを作成しておく必要があるんですね。なので、まずはそれを先に作ります。

カスタムブロック作成ページへアクセス

SDK_TOP_JPにアクセスします。
「MESH SDKを使う」からカスタムブロックの管理画面に行けます。

カスタムブロックを作成する

Create New Blockをクリックすると、カスタムブロックの作成画面になるので設定していきます。
設定は下記の通りです。一通り設定できたら左上の「Save」をクリックして保存しましょう。


Codeに設定したソースコード
var localhost = 'http://localhost:8080' + properties.path;

ajax({
  url    : localhost,
  type   : 'get',
  timeout: 5000,
  success: function (data) {
    callbackSuccess({
      resultType : 'continue'
    });
  },
  error: function(request, errorMessage) {
    log('ERROR: ' + errorMessage);
    callbackSuccess({
      resultType: 'continue'
    });
  }
});

return {
  resultType: 'pause'
}

設定の簡単な説明

この辺の設定は「ラズパイ版MESHを使って、Apple Watchで操作するおしゃべりロボットを作る - Qiita」を参考にしました。

Connector

これはInput Connectorのみを設定しました。
あとでMESHアプリを触れば分かるんですが、MESHのブロックにはInputとOutputがあります。
今回はボタンを押したあとこのカスタムブロックの処理を起動して終わりという感じになるので、Output Connectorには設定なしという状態です。
もしもこのカスタムブロックが動いた後に何か他のことをしたいとなったら、Output Connectorの方にも設定が必要です。

Property

これはコード内で参照できるプロパティを作れるものになります。カスタムブロック配置時に、プロパティの値をいじれます。なので、例えば別のチャンネルに通知したくなったとかでも、ブロックを新しく作る必要はなく、配置するときにプロパティの値だけいじればOKみたいな風にできるということです。

Code

これはカスタムブロックがキックされたときに実行されるJavaScriptのコードになります。コードがキックされたら、Ajaxで先ほどPythonで書いたサーバを叩きに行ってます。

MESHアプリでレシピを作成する

MESHアプリの簡単な説明

MESHを使って処理を作るには必ずMESHアプリで「レシピ」を作る必要があります。このレシピはMESHアプリからでないと作れません。ラズパイで動作させるレシピもMESHアプリから作ることになります。

MESHハブの登録

事前準備として、スマホとラズパイのBluetoothはオンにしておきましょう。
スマホからMESHアプリを起動します。右上にスマホマークがありますが、これをタップすると以下の「他の端末に変更する」っていうのが出てくると思うのでこれをタップします。

すると「端末を選ぶ」画面になるので、サインインして「ハブの追加」をタップします。

「ハブの追加」をタップすると次の画面になります。「セットアップを始める」をタップして次へ行きましょう。

この画面も「次へ」で進みます。

スマホとラズパイの接続に成功すると以下の画面になります。もし何分待ってもつながらないということであれば、Bluetoothを確認するか、ラズパイがセットアップ可能な状態か確認しましょう(画面に表示されているリンクをタップすればやり方が書いてあると思います)。

この画面ですが、ラズパイのWi-Fi設定をするかしないかの画面です。有線で接続してしまっている場合は別ですが、基本的にはWi-Fiの接続も終わっているはずなのでスキップします。

適当にハブの名前を決めて次へ進めます。

上手くいくと最終的にこの画面になるので、先ほど追加したラズパイのMESHハブを選択して、画面下の「選択」をタップしましょう。

ブロック/カスタムブロックの追加・レシピの作成

※この工程を始める前にスマホのBluetoothを切っておくことをおすすめします。MESHブロックの電源を入れると、スマホの方とペアリングしようとしてきますが、ペアリングの相手はラズパイです。スマホのBluetoothを切っておかないと、MESHは永遠にスマホにペアリングしようとしてくるのでラズパイとペアリングしてくれません。

アプリトップの画面で「新しいレシピ」をタップするとこの画面になります。まずはMESHブロックを追加しましょう。MESHブロックの電源を入れ、左下の「ブロック 追加」のプラスマークをタップしましょう。
(電源はMESHブロックのシリコン素材部分を長押しで入ります、もし入らない場合は充電してください)

上手く追加できると左下のブロックのところに「ボタンブロック」が表示されるので、タップしてドラッグして配置しましょう。下記画面のようになるはずです。

次にカスタムブロックを追加します。先ほどWeb画面でJavaScriptのコードを登録したりしたものです。上画面に映っていますが「カスタム 追加」のプラスマークをタップすると追加画面へ行けます。そうすると以下のように先ほど登録したカスタムブロックが表示されるので、タップして、「追加」ボタンをタップします。

無事追加できたと思うので、先ほど「ボタンブロック」を配置したのと同じ要領でカスタムブロックを配置し、ボタンブロックの端とカスタムブロックの端を下記のようにつなげます。配置済みのボタンブロックからカスタムブロックまでをドラッグすれば線でつなぐことができます。

補足

配置したカスタムブロックをタップするとこのような画面になります。ここでプロパティの値をいじれるんですね。Pythonのサーバ側プログラムを変更すれば、同じカスタムブロックでここのPathを変えれば動作を変えられるというわけです。

動作確認

以上で設定は終わったので、MESHのボタンを押してみましょう。Slackに投稿がされれば成功です。

まとめ

以上でMESHのボタンを押したらSlackで通知する(ラズパイ経由で)が完成しました。
手順は結構多いですが、お気づきの通り書いたソースコードは僅かです。そもそもラズパイのインストールができないといけないみたいなハードルはありますが、それさえ超えてしまっていれば割とサクッとできてしまいます。
MESHはボタン以外にもLED、人感センサー、動きセンサー、温度湿度センサー、明るさセンサー、GPIOと様々なブロックがあります。強みとして、(GPIOを除いて)電子工作が全くできなくてもIoTの自作ができてしまうというところにあります。電子工作ってなるとどうしても多少電気電子の知識が必要になってくるので、普通にソフトウェアエンジニアをしてきた人からすると若干ハードルが高かったりするんですよね。しかしMESHタグなら電子工作の知識がほぼ不要で、ソフトウェアでほとんどのことがなぎ倒せるのでオススメです。
ちなみに物理的に何かしたいけど電子工作の知識がない…とかであれば、Ejectコマンドっていう大変便利なものがあるのでそれを使ってみるといいかもしれません(参考:EjectコマンドをRaspberry Piで遊ぼう ~CD-ROMドライブでかんたん工作~)。