はじめに
この記事はAizu Advent Calendar 2020 21日目の記事です。今回はSony MESHタグ (以下MESH)で取得したデータをFirebase Realtime Databaseに保存しようとしたときの話です。序盤はカスタムタグの作り方から始めています。タグの識別を読みたい方はタグの識別まで読み飛ばしてください。
背景
普通であれば、IFTTTのWebhookあたりを使ってMESHで取得した情報をFirebase Realtime Databaseに保存することが出来ると思うのですが、うまくいかず困っていました。このような経緯があり、題目の通りMESHのカスタムタグを使ってデータを保存することとなりました。(最近のMESHアプリはボタンの反応が遅かったりiPad Proを使っているせいか画面比がおかしかったり不具合多めです。←これ僕だけ?)
実装のイメージ
上のようなレシピがあったとして(右側が今回作成するカスタムタグ)、人間をタグが感知したらデータベースに保存するようにしています。
結果としてデータベースには、上のようなデータが追加されていることがゴールとなります。
カスタムタグの作り方
MESH SDK上でカスタムタグを作るのですが、詳しくはリファレンスを参照してください。今回は人感タグの情報をデータベース保存するためのタグの作り方を簡単に以下に示します。(MESH SDKの登録は既に完了している前提。)
1. 新規タグ作成
2. タグ名、説明などを記入
ここを
こんな感じで書いてください。New Blockがタグ名でNew Functionが関数名になります。アイコンなども自由に設定出来ます。自分が分かるようなものであれば、なんでも大丈夫です。
3. コネクタを設定する
human_FBのタブを開いて、ConnectorのInput Conncetorを(1)にしましょう。緑色のプラスボタンで追加出来ます。これでセンサーなどの他のタグからの連結を可能にします。
4. コードを書く
CodeのExecuteの部分にソースコードを書きましょう。言語はjsです。
以下はajaxを利用してタグから取得した情報をデータベースに送信するコードです。書き慣れていないjsなので変なコードかもしれませんが、とりあえずこれで送れます。
var apiURL = "URL";
//APIを叩く際のパラメータ
//プロパティの値を渡す
var data = {
"type": "human",
"humanValue" : messageValues.stateValue
};
ajax ({
url : apiURL,
data : JSON.stringify( data ),
type : "post",
contentType : "application/json",
dataType : "json",
timeout : 5000,
success : function ( contents ) {
log("Done");
},
error : function ( request, errorMessage ) {
log("Error");
runtimeValues.outputIndex = -1;
callbackSuccess( {
resultType : "continue",
runtimeValues : runtimeValues
} );
}
});
これでカスタムタグが完成しました。最後にSaveしてください。
カスタムタグを応用したレシピ
以下が先ほどの手順で作成したカスタムタグを利用したレシピです。人感タグの他に明るさタグや温湿度タグ、GPIOタグなどの情報もデータベースに保存するレシピになっています。明るさタグや温湿度タグ、GPIOタグなどのカスタムタグは人感タグと中身は基本一緒ですが、タグからデータを取り出す処理だけそれぞれ異なります。
このレシピの問題点
このレシピはそれぞれのタグに合ったカスタムタグを用意しなければならないという問題点を抱えています。目的は、データベースにデータを保存することなのに同じ目的を持ったカスタムタグが5つもあるなんて変ですよね。そこで一つのカスタムタグに集約する方法を考えましょう。先ほどのタグを改良します。
タグの識別
タグの識別はReceiveで行います。厳密に言うと、Receiveで入力コネクタの識別を行い、入力を受け取ったコネクタの番号に応じてタグへの情報アクセスの処理を切り替えます。
コネクタを増やす
先ほどConnectorで設定したInput Conncetorを(6)にしましょう。(上のレシピの場合)Input label(Optional)の部分にラベルを設定してあげると分かりやすいでしょう。
Initializeの部分に書くコード
CodeのInitializeの部分に以下のコードを記述してください。
// 変数を定義して初期化する
return {
runtimeValues : {
// 入力receive内のindexを保存する変数
input_id : 0,
// 取得した情報を保管する変数
num : 0
}
}
Receiveの部分に識別を行うコードを書く
CodeのReceiveの部分に以下のコードを記述してください。
input_id = index;
if ( index == 1 ) { //2番目のコネクタから入力(Temperature )
num = messageValues.temperatureValue;
} else if ( index == 2 ) { //3番目のコネクタから入力(brightness)
num = messageValues.brightnessValue;
} else if ( index == 3 ) { //4番目のコネクタから入力(humidity )
num = messageValues.humidityValue;
} else if ( index == 4 ) { //5番目のコネクタから入力(human)
num = messageValues.stateValue;
} else if ( index == 5 ) { //6番目のコネクタから入力(bright2)
num = messageValues.brightnessValue;
}
Executeの部分に書くコード
CodeのExecuteの部分に以下のコードを記述してください。
var apiURL = "URL";
if (input_id == 0 ) { //1番目のコネクタから入力(GPIO)
var data = {
"type": "water_plant",
"brightnessValue" : 1
};
} else if (input_id == 1 ) { //2番目のコネクタから入力(Temperature )
var data = {
"type": "temp",
"tempValue":num
};
} else if (input_id == 2 ) { //3番目のコネクタから入力(brightness)
var data = {
"type": "bright",
"brightnessValue" : num
};
} else if (input_id == 3 ) { //4番目のコネクタから入力(humidity )
var data = {
"type": "humi",
"humiValue":num
};
} else if (input_id == 4 ) { //5番目のコネクタから入力(human)
var data = {
"type": "human",
"humanValue" : num
};
} else if (input_id == 5 ) { //6番目のコネクタから入力(bright2)
var data = {
"type": "bright_h",
"brightnessValue" : num
};
}
ajax ({
url : apiURL,
data : JSON.stringify( data ),
type : "post",
contentType : "application/json",
dataType : "json",
timeout : 5000,
success : function ( contents ) {
log("Done");
},
error : function ( request, errorMessage ) {
log("Error");
runtimeValues.outputIndex = -1;
callbackSuccess( {
resultType : "continue",
runtimeValues : runtimeValues
} );
}
});
カスタムタグを応用したレシピ改良版
こちらが上の改良を施した結果、完成したカスタムタグです。最初のレシピと比較してシンプルで無駄のない構造になっています。
まとめ
カスタムタグは大きく、Initialize,Receive,Execute,Resultに別れていますがそれぞれに処理を加えることで様々な動作を実装することが出来るようになりました。これまで、ReceiveとExecuteぐらいしか処理を書かなかった人もぜひ試してみてください。世界が広がります。