SwitchBot温湿度計を絶対湿度ロガーにする

#1. はじめに

SwitchBot温湿度計は安価で手軽に温湿度の記録ができる非常に便利なデバイスだ。

https://www.switchbot.jp/products/switchbot-meter

しかし、1つだけ難点がある。絶対湿度の表示と記録ができないのだ。絶対湿度をウォッチする重要性は松尾設計室の松尾和也氏の記事をはじめ、いろいろなところで指摘されている。

https://www.nikkei.com/article/DGXMZO91029780X20C15A8000000/

最近では「みはりん坊ダブル」を使って絶対湿度の確認ができるということで人気が出ているようだ。ただ、残念なことにSwitchBotと違って表示されるだけでログをとることができない。（みはりん坊の表示をカメラで撮影して画像解析して数値をとる、というようなことをすれログが取れるかもしれないが…）

https://www.amazon.co.jp/A-D-%E3%81%BF%E3%81%AF%E3%82%8A%E3%82%93%E5%9D%8A%E3%83%80%E3%83%96%E3%83%AB-AD-5687/dp/B00BUFERYO?th=1

絶対湿度の計算自体はSwitchBotの温湿度計で測定した室温と相対湿度が分かればこのようなアプリやHPから簡単に計算できる。一応、計算式はこんな感じ（ただし単位はみはりん坊に合わせてg/m<sup>3</sup>）。VHが絶対湿度(g/m<sup>3</sup>)、RHが相対湿度(%)、tが室温（°C）。しかしこれではやはりログが取れないし少々面倒くさい。

```math
VH=\frac{RH}{100}\cdot\frac{217\times6.1078\times10^{\frac{7.5t}{t+237.3}}}{t+273.15}
```



https://apps.apple.com/jp/app/%E5%BF%AB%E9%81%A9%E3%82%92%E8%A8%88%E7%AE%97/id605648449

https://www.2x6satoru.com/article/ab-humidity.html

https://komoriss.com/relative-humidity-volumetric-humidity/



前回、Google apps scriptを使ってSwitchBot温湿度計のデータをGoogleスプレッドシートに記録できることができるようになっている。そこで、この結果をGoogleデータポータルに表示してSwitchBot温湿度計を絶対湿度のロガーにしてきたい。（SwitchBot温湿度計のログをCSVファイルで取り出してExcelで計算すれば「絶対湿度のログ」にできるじゃないか！という突っ込みはなしでお願いしたい。）

https://qiita.com/TMUS_SH/items/9197c2c78faab5fd6164


#2. 利用デバイス・事前準備
##2.1 利用デバイス
* SwitchBot温湿度計
* SwitchBot Hub mini
* Googleアカウント

##2.2 事前の準備
* 温湿度計の設定（アプリとの接続）を終わらせる
* クラウドサービスをオンにしてSwitchBot Hub miniと連携をさせておく
* プロフィール→設定→アプリバージョンを10回タップ（開発者向けオプション有効化）
* 開発者向けオプションからトークンを取得

https://note.com/klayer123/n/nb14086840351

※こちらを参考にさせていただいた

* デバイスID（MACアドレス）の取得
 * SwitchBotのアプリから温湿度計を選択
 * 右上の歯車マークから「設定」を開き「・・・」からMACアドレスを確認
 * 「AA:AA:AA:AA:AA:AA」の形式になっているのでコロン以外の12桁の英数字をメモする
 * 記録したい全ての温湿度計に対してこの操作を繰り返す

<img width="150" alt="E9jmqIyUcAgpFzb.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/00d204b5-abed-9b7f-00d5-b3fa01b3beed.jpeg">　<img width="150" alt="E9jmp5uVUAIo5-3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/1350b15e-dead-ba5b-3ca7-80a7c2a13ccd.jpeg">　<img width="150" alt="E9jmpu6UYAYW9Js.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/9948c759-8321-ddf7-60a6-3efca18af4e7.jpeg">


#3. GoogleAppsScriptのコード

* Googleスプレッドシートで新しいスプレッドシートを作成する
* SwitchBot温湿度計の数だけシートを作成しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/17dbec64-7a5f-8eb2-dc20-a6b515b8eac8.png)

* 各シートの1行目にヘッダーをつけておく
 * データポータルでの表示に備えてシートごとにヘッダーを変えておく

1枚目のシート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/8faf2a63-3a3f-2923-5456-3227327a7056.png)

2枚目のシート（ヘッダーに1枚目シートとは異なる数字を振っておく）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/61ed4fc9-d288-c296-f96e-97512b1ac406.png)

* ツールからスクリプトエディタを開き以下のコードを記載する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/6fe174a6-49d2-53b3-9aaf-0a1207f19f9c.png)


~~~Javascript
function getJSON_SwitchBotHubMini(){

  var headers = {"Authorization" : "token"}; //header情報として取得したトークンをtokenに記載
  var options = {
    "headers" : headers,     //header情報を追加
  }

//----------1つ目のSwitchBot温湿度計の記録------------

    var url2 = "https://api.switch-bot.com/v1.0/devices/************/status";  //*に事前準備で取得したデバイスID（12桁英数字）を記載
    var data = UrlFetchApp.fetch(url2,options);                 //1つ目の温湿度計のステータスを取得
    var datajson=JSON.parse(data.getContentText());   
    var temp = datajson['body']['temperature']
    var rhumidity = datajson['body']['humidity']
    var ahumidity    =217*(6.1078*10**(7.5*temp/(temp+237.3)))/(temp+273.15)*rhumidity/100 //絶対湿度（g/m^3)を算出

  // 1つ目のシート取得
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadsheet.getSheets()[0];
    var date = new Date();
  // データ入力
    sheet.appendRow(["1つめのSwitchBot温湿度計",date,temp,rhumidity,ahumidity,1]);  //温湿度計の名前は任意でつける。もちろんデバイスIDと紐づけて
    var lastRow = sheet.getLastRow();
    var range = sheet.getRange(lastRow-1, 6); 
    range.setValue(2);  //データポータルでの表示に備えたIDの付与

//----------2つ目のSwitchBot温湿度計の記録------------

    url2 = "https://api.switch-bot.com/v1.0/devices/E1B1233EED79/status";  //*に事前準備で取得したデバイスID（12桁英数字）を記載
    data = UrlFetchApp.fetch(url2,options);                 //2つめの温湿度計のステータスを取得
    datajson=JSON.parse(data.getContentText());   
    temp = datajson['body']['temperature']
    rhumidity = datajson['body']['humidity']
    ahumidity    =217*(6.1078*10**(7.5*temp/(temp+237.3)))/(temp+273.15)*rhumidity/100 //絶対湿度（g/m^3)を算出

  // 2枚目のシート取得
    spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    sheet = spreadsheet.getSheets()[1];
    date = new Date();
  // データ入力
    sheet.appendRow(["2つめのSwitchBot温湿度計",date,temp,rhumidity,ahumidity,1]); //温湿度計の名前は任意でつける

    var lastRow = sheet.getLastRow();
    var range = sheet.getRange(lastRow-1, 6); 
    range.setValue(2); //データポータルでの表示に備えたIDの付与

//----------3つ目のSwitchBot温湿度計の記録------------

  //温湿度計の数だけ繰り返しで記載
}
~~~

※APIの取得が1日1000件までと限られているのでデバイスリストの取得は行わず直接、温湿度計のステータスを読みに行っている。

* 「トリガー」で定期実行の設定を行う
 * イベントのソースを「時間主導型」
 * 時間ベースのトリガーのタイプを「分ごとのタイマー」
 * 時間の間隔を1分、5分、10分、15分、30分から選択

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/08e6d5ba-d150-a299-d09e-b9a240eacfbe.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/58613b9b-8eba-0789-5e28-f4eaea6ed5f6.png">　
※タイマーの間隔は5分か10分を推奨（特にSwitchBot温湿度計の数が多い場合）
　詳細は[前回の記事の結果](https://qiita.com/TMUS_SH/items/9197c2c78faab5fd6164#4-%E7%B5%90%E6%9E%9C)を参照ください。　

以上で室温、相対湿度、絶対湿度がGoogleスプレッドシートに指定時間間隔ごとに記録されるようになる。

#4. Googleデータポータルでの表示
##4.1 ダッシュボードの作成とデータの連携
* Googleアカウントにログインした状態でデータポータルを開く

https://datastudio.google.com/

* 「空のレポート」から新しいダッシュボードを作成
* 「データに接続」から「Googleスプレッドシート」を選び、先ほど作ったスプレッドシートを選択 → その後ダッシュボードにデータを表示したいワークシートを選択 → 「追加」を押す

##4.2 スコアカードによる最新の温湿度の表示
* 「グラフを追加」から「スコアカード」を選択
* 「指標」から表示したい項目を選択
* 「指標」の左側の鉛筆マークから集計方法を「平均値」にする

<img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/39811faa-1a27-ae85-a091-b45d01365fc3.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/f42768de-5310-2f4c-f8e8-6552c93bbf10.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/bcd9a1cf-e39d-e621-25f1-9962e8ad36b3.png">


* 「フィルターを追加」から「項目を選択」で「ID〇」（〇は[ここ](#3.-GoogleAppsScriptのコード)でシートごとに割り振った番号）を選び、「条件を選択」を「次に等しい (=)」として条件に「1」を入力する

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/e7bd678a-49f7-81b2-845a-4b9787adb4f1.png"> 

* フィルターを保存すればGoogleスプレッドシートに記録されたものの中で最新の値がスコアカードに表示されるようになる
* 以上の操作を「温度」「相対湿度」「絶対湿度」に対して実行し、スコアカードを並べる

##4.3 時系列グラフによるログの表示
* 「グラフを追加」から「時系列グラフ」を選択
* ディメンションから「Date」のタイプを「日付、時、分」に変更
* 「指標」から表示したい項目を選択して集計方法を「平均値」にする
* 「デフォルトの日付範囲」から「詳細設定」を選び開始日に数字を入力する
 * 数字が1であれば前日と今日の2日分、2であれば前々日からの3日分のログが表示できる
* 「スタイル」→ 「全般」から「欠損データ」を「線形補間」にしておく

<img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/ad67632a-3908-78f7-b1c6-124dfd5a6246.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/34479104-3a87-9e3d-c9ea-6fe7c6e86d83.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/9ed33d82-8af9-8cd8-434a-8f1f8059edab.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/89b551b5-4510-8c78-a23c-6c056c82d1be.png">

* 以上の操作を「温度」「相対湿度」「絶対湿度」に対して実行し、時系列グラフを並べる


##4.4 ダッシュボードの公開、共有
* 自分自身のみで閲覧する場合
 * 「共有」から「レポートへのリンクを取得」としてリンクをコピーし、スマホなどのブラウザから閲覧する

<img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/9051cdfd-c766-5ae9-94b8-3becadffd225.png">

* 家族などで共有する場合
 * 「共有設定を変更」から「アクセスを管理する」に移動し「リンクを知っている全員が表示できます」を選択
 * リンクをコピーして閲覧してほしい人に共有する

<img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/efcc1da2-e3ef-d1a2-d27c-e068935c3fde.png"> → <img width="150" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/1f6cff80-f125-ee1f-6b1a-83e82ae7906d.png">

* 共有されたリンクをブラウザのお気に入りに登録して飛べばめでたく絶対湿度ロガーが完成しているはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1637818/8c83c559-4b1c-dc2f-c350-1ea83c52a9a9.png)



#5 終わりに
これでSwitchBot温湿度計が絶対湿度ロガーとして機能するようになった。1個2000円程度の温湿度計で「温度」、「相対湿度」、「絶対湿度」のログが取れるというのは結構ありがたい。難点としてはGoogleスプレッドシート側の更新頻度が5分ごと（設定に寄る）、データポータルの更新頻度は15分ごと程度なので、「完全にリアルタイムの温湿度か？」と言われると少し前の温湿度を表示していることにはなる。しかし、そもそもSwitchBot温湿度計はBLE経由でも2分ごと、SwitchBot Hub mini経由であればおよそ30分毎にしか温湿度の値が更新されない。この点を考慮すると、それなりに近い段階での温湿度をログの取得も含めて実行できる、というだけで十分な気もする。

どうしてもリアルタイムに近いデータを取得したい場合はRaspberry Piを使うなどしてBluetooth Low Energy（BLE）でデータを取得してもらいたい。これはかなり色々な方の記事が出ているので参考になると思う。

https://qiita.com/warpzone/items/11ec9bef21f5b965bce3

https://qiita.com/tosshie/items/0b6a93a8e351cd801321

https://qiita.com/shiguma_wq/items/e2bce6f0c7495c03f704