やりたいこと
MESHタグの値をGoogle Spreadsheetに記録したものをJSON形式で外部利用できるようにしつつ、URLにパラメータを付与する事で好きなデータのみ取り出したい
MESHタグで取得した値を可視化&外部で利用できる形に(JSON形式)の続きです
http://qiita.com/glory/items/ddd527fd64942d33f4ad
下記の「部屋の温度」を記録したシートから、最新の値や最高温度、最低温度、平均値をURLを叩くだけで取得できるようにするやり方を記します
Google Apps Script(GAS)
下記のコードをスクリプトエディタに記入('your_spread_sheet_id'と'sheet_name'は適切なものに置き換える)
コードはあまり綺麗ではないので、参考程度にしてください
function doGet(e) {
//受け取るパラメータを用意する
var param = e.parameter.param;
var rowData = {}; //JSONオブジェクト格納用の入れ物
var result;
var TIME = 0;
var TEMP = 1;
if (e.parameter == undefined) {
//パラメータ不良の場合はundefinedで返す
rowData.value = 'undefined';
//return ContentService.createTextOutput(result);
} else {
var id = 'your_spread_sheet_id'; //スプレッドシートのID
var sheet = SpreadsheetApp.openById(id).getSheetByName('sheet_name');
var rows = sheet.getDataRange().getValues();
var p_name = rows.splice(0, 1)[0];
var las_col = sheet.getLastColumn();
var last_row = sheet.getLastRow();
switch(param){
//全てのJOSNデータを取得
case 'all':
rowData = rows.map(function(row) {
var obj = {}
row.map(function(item,index){
obj[p_name[index]] = item;
});
return obj;
});
break;
//最新の値のみを取得
case 'latest':
for(var i = 0; i < las_col; i++){
rowData[p_name[i]] = sheet.getRange(last_row, i + 1).getValue();
}
break;
//最高値の値を取得(同じ値がある場合、時間は一番過去のものになる)
case 'max':
var val = rows[0][TEMP];
var max_row_num = 2;
for(var i = 0; i < rows.length; i++){
if(val < rows[i][TEMP]){
val = rows[i][TEMP];
max_row_num = i + 2; //spreadsheetは1から数える、1行目はプロパティネームで使用しているため2を足す
}
}
rowData[p_name[TIME]] = sheet.getRange(max_row_num, TIME + 1).getValue();
rowData[p_name[TEMP]] = sheet.getRange(max_row_num, TEMP + 1).getValue();
break;
//最低値の値を取得(同じ値がある場合、時間は一番過去のものになる)
case 'min':
var val = rows[0][TEMP];
var min_row_num = 2;
for(var i = 0; i < rows.length; i++){
if(rows[i][TEMP] < val){
val = rows[i][TEMP];
min_row_num = i + 2; //spreadsheetは1から数える、1行目はプロパティネームで使用しているため2を足す
}
}
rowData[p_name[TIME]] = sheet.getRange(min_row_num, TIME + 1).getValue();
rowData[p_name[TEMP]] = sheet.getRange(min_row_num, TEMP + 1).getValue();
break;
//平均の値を取得
case 'average':
var sum_num = 0;
for(var i = 0; i < rows.length; i++){
sum_num += rows[i][TEMP];
}
rowData.average_temp = sum_num / rows.length;
break;
//それ以外のパラメーターは'error'と返す
default:
rowData.value = 'error';
break;
}
}
result = JSON.stringify(rowData, undefined, 2);
//ログ出力と値の出力
Logger.log(result);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
結果
https://script.google.com/macros/s/your_spread_sheet_id/exec?param=latest
のようにURLの末尾に?param=latestといったようにつけると必要なデータだけが取得できる
{
"time": "January 24, 2017 at 07:47PM",
"temp": 22.7
}
{
"time": "January 24, 2017 at 03:31PM",
"temp": 24.1
}
{
"time": "January 24, 2017 at 07:20AM",
"temp": 12.1
}
{
"average_temp": 18.75272636318166
}
[
{
"time": "January 23, 2017 at 10:19AM",
"temp": 19.4
},
{
"time": "January 23, 2017 at 10:20AM",
"temp": 19.4
},
{
"time": "January 23, 2017 at 10:21AM",
"temp": 19.4
},
{
"time": "January 23, 2017 at 10:22AM",
"temp": 19.5
},
{
"time": "January 23, 2017 at 10:23AM",
"temp": 19.6
},
{
"time": "January 23, 2017 at 10:24AM",
"temp": 19.6
},
{
"time": "January 23, 2017 at 10:25AM",
"temp": 19.7
},
{
"time": "January 23, 2017 at 10:26AM",
"temp": 19.7
},
...続く
{
"value": "error"
}
注意点
一度WEB APIを公開していると「更新」ボタンを押すだけでは更新されないので、「プロジェクトバージョン」から「新規作成」を選んで更新する必要があります(これに全然気付かず、コードの内容が反映されない....何故だ...orz となっていました。笑)
2種類のURLがあり、表示されているURLは公開用、開発用は「最新のコード」で右クリックして「リンクのURLをコピーする」で取得できます(「最新のコード」をそのままクリックしても良いのですが、パラメータを付与してテスト結果の確認ができないのでコピーしてからやってました)
URLの種類 | URL |
---|---|
開発URL | https://script.google.com/macros/s/AAAAAAAAAAAAAAAA/dev |
公開URL | https://script.google.com/macros/s/BBBBBBBBBBBBBBBB/exec |
まとめ
これでMESHで簡単にログを利用したモノ・サービスのラピッドプロトタイピングができそうな気がします
ちなみに、Google Spreadsheetの定期自動書き込みは2000でストップします
2000以上になるとIFTTTからの書き込みが、ファイル名(1)といったものが新しくできて追記されていきます
(手動で一番下に○○行追加をすれば2000以上の行数になります。)