前回のモルモットスマートホームに、スプレッドシートを追加しました。部屋の温度がどう推移しているか、グラフで分かります。スプレッドシートはサーバー化してobnizから直接温度データを受信できます。
スプレッドシートの出力結果
先にスプレッドシートの出力結果を掲載します。
10分間隔で、スプレッドシートに日時、温度、湿度が記入されていきます。(プログラムのミスで、最初は1秒間隔で記入されています。)
ただ、よく見ると記入されていない時間もあります。
15時台は3回しか記入がなく、半分は失敗しているようです。13時台のように6回全部記入されることもあります。
これは、obnizとスプレッドシート間の問題ではなく、温度を計測しているμPRISMセンサーとobnizのBLE通信が不安定なことが原因のようです。
温度を確実に記録したい場合、obnizに温度センサーを直接つないでください。
温度管理の全体図
前回までの構成に、スプレッドシートを追加しました。
- μPRISMセンサーで温度を測りobnizに飛ばす。
- obnizで温度を判定し、IFTTTに指示を送る。と、同時にスプレッドシートに温度を書き込む。
- IFTTTからMerossスマートプラグを操作して、ホットカーペットの電源を切り替える。
スプレッドシートをサーバーに
温度データをスプレッドシートに書き込む方法は、obniz公式ブログにあります。IFTTTを介してスプレッドシートに書き込むのが、手軽な方法だと思います。
しかし、IFTTTは2020年9月から、無料で作れるアプレットの数が3つに制限されてしまいました。
ならばIFTTTを介さず、直接obnizからスプレッドシートに書き込めるようにしましょう。
スプレッドシートを簡易サーバーにします。
スプレッドシートのGAS
Google Spreadsheet を簡易 Webサーバーとして動かして、手軽にWebHookを受け取る方法を参考にしました。
私はPOSTでJSONを送るとき、CORS(クロスドメインエラー)に悩まされ、あきらめてkey=valueの形式で、データ送受信をすることにしました。
下記が、GASに記載したコードです。
1 2 3 4 5 6 7 8 9 10 11 |
function doPost(e) { let ss = SpreadsheetApp.getActive(), sheet = ss.getActiveSheet(), data = [new Date()], contents = e.postData.contents.split("&"); for(let i=0;contents[i];i++) { let kv = contents[i].split('='); data[i+1]=kv[1]; } sheet.appendRow(data); } |
Postデータを受け取ったら、シートの最後の行にデータを追加していきます。
obnizのコード
温度、あと湿度のデータをPostしているobnizのコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<html> <head> <meta charset="utf-8"> <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script> <script src="https://unpkg.com/obniz@3.11.0/obniz.js" crossorigin="anonymous"></script> </head> <body> <script> const obniz = new Obniz("obniz-ID"); const ifttt_secret_key = "IFTTT-ID"; let isWrit = false; obniz.onconnect = async () => { await obniz.ble.initWait(); const U_PRISM = Obniz.getPartsClass("uPRISM"); obniz.ble.scan.onfind = async (peripheral) => { if (U_PRISM.isDevice(peripheral)) { console.log("μPRISM発見"); const device = new U_PRISM(peripheral); device.ondisconnect = (reason) => { console.log(reason) } await device.connectWait(); console.log("μPRISM接続完了"); device.onNotify = async (r) => { if(!isWrit){ const temp = r.temperature.toFixed(1); const humid = r.humidity.toFixed(1); isWrit = true; postData = (url, data) => { fetch( url, { method: "POST", mode: "no-cors", body: data } ) .then(() => console.log(url + "にPOST成功")) .catch(error => console.log(error)); }; if(r.temperature < 18){ await postData('https://maker.ifttt.com/trigger/run_meross/with/key/' + ifttt_secret_key, ""); }else if(r.temperature > 20){ await postData('https://maker.ifttt.com/trigger/stop_meross/with/key/' + ifttt_secret_key, ""); } await postData("スプレッドシートで発行したURL", `temp=${temp}&humid=${humid}`); await obniz.wait(1000); if (typeof done === "function") { done(); } } }; await device.startNotifyWait(); } }; await obniz.ble.scan.startWait(); } </script> </body> </html> |
Postしているデータはtemp=${temp}&humid=${humid}
の部分です。
tempが温度、humidが湿度。時刻はスプレッドシート側で記述されます。
このコードを、obnizのサーバーレスイベントで10分おきに実行しています。
送信ログ
obnizのサーバーレスイベント画面で、実行ログを見られます。
スプレッドシートに向けてPostした後にエラーが出ていますが・・・、不都合がなかったのでこのまま運用します。
スプレッドシートでグラフ化
スプレッドシートのA~C列(時間、温度、湿度)を全選択します。
メニューから挿入>グラフを選択すれば、常に更新されていくグラフとなります。
モルモットの温度管理が可視化されました。