Mackerel に部屋の温湿度を記録する

Mackerel に部屋の温湿度を記録する
Photo by Ilse Orsel / Unsplash

Amazon プライムデーだぜ!ということで SwitchBot の温湿度計を買いました。

https://www.amazon.co.jp/gp/product/B07L4QNZVF

とりあえず仕事部屋に置いているのですが、いい感じです。寝室用にも欲しい。買い足そうかな…。

ただ置くだけでも温湿度が見れて便利なのですが、スマートホーム的な観点でメトリクスをとっていきたい。一年を通した記録を見ることで除湿・加湿器を買う際のスペックの参考にもなりそうですし、体調との関連性とかも見れたら面白そう。特に妻は頭痛持ちなので何か法則とか見出せたら役立ちそう (おそらく気圧が主な影響ぽいですが)。

構成

主な構成は以下です。

図だと以下。

EventBridge Scheduler で定期的に Lambda 関数を実行し、Lambda 関数で SwitchBot の API を呼び出し、取得した結果を Mackerel に送信する流れです。

今回、言語は JavaScript を使用しています。

デプロイは AWS SAM で行っています。

SwitchBot API について

去年 v1.1 が公開されていました。

【API】新バージョンAPI v1.1を公開しました - SwitchBot Magazine | スマートホームで暮らしをシンプルに
目次新バージョンについてSwitchBotAPIについて手引き:現在取得済みのデバイス一覧:注意事項詳細はこちらGitHub上で新バージョンAPI v1.1を公開!APIによるロックの解施錠を操作可能になりました。 ht […]

大きな変更として、今までは Authorization ヘッダーにトークンを指定するだけで API の認証を行っていましたが、v1.1 からはトークンとシークレット、タイムスタンプとナンス (使い捨ての値) を使用して一意の署名を作成する方法になりました。

署名の作成方法はいくつかの言語毎にサンプルコードが公開されておりほぼそのまま使えます。

GitHub - OpenWonderLabs/SwitchBotAPI: SwitchBot Open API Documents
SwitchBot Open API Documents. Contribute to OpenWonderLabs/SwitchBotAPI development by creating an account on GitHub.

まず curl コマンドで検証してみます。Python のサンプルコードを使用して署名を作成します。リクエストに必要な各情報が出力されます。

$ python3 sigh.py
Authorization: xxxx
t: 1111111111111
sign: yyyy
nonce: zzzz

これを使って curl コマンドでリクエストを送信します。デバイスの一覧を取得してみます。

$ curl \
-H "Authorization: xxxx" \
-H "sign: yyyy" \
-H "t: 1111111111111" \
-H "nonce: zzzz" \
https://api.switch-bot.com/v1.1/devices

上のコマンドでデバイスの一覧が取得でき、各デバイスのデバイス ID が取得できます。デバイス個別の情報はこのデバイス ID を使用して取得できます。

$ curl \
-H "Authorization: xxxx" \
-H "sign: yyyy" \
-H "t: 1111111111111" \
-H "nonce: zzzz" \
https://api.switch-bot.com/v1.1/devices/<デバイス ID>/status

今回の場合、温湿度計から情報を取得したいです。各デバイスの持つ情報は以下にまとめられています。

GitHub - OpenWonderLabs/SwitchBotAPI: SwitchBot Open API Documents
SwitchBot Open API Documents. Contribute to OpenWonderLabs/SwitchBotAPI development by creating an account on GitHub.

温湿度計の場合、以下ですね

GitHub - OpenWonderLabs/SwitchBotAPI: SwitchBot Open API Documents
SwitchBot Open API Documents. Contribute to OpenWonderLabs/SwitchBotAPI development by creating an account on GitHub.

temperature が温度、humidity が湿度です。

署名の取得はこんな感じで書いてます。ほぼサンプルの通りです。ナンスに UUID を使用してます。

const signToSwichbot = async (token, secret) => {
  const t = Date.now();
  const nonce = crypto.randomUUID();
  const data = token + t + nonce;
  const signTerm = crypto
    .createHmac("sha256", secret)
    .update(Buffer.from(data, "utf-8"))
    .digest();
  const sign = signTerm.toString("base64");
  return { sign: sign, t: t, nonce: nonce };
};

温湿度情報の取得はこんな感じ。

const getTempHum = async (switchbot_endpoint, switch_bot_token, sign) => {
  const res = await axios.get(switchbot_endpoint, {
    headers: {
      Authorization: switch_bot_token,
      sign: sign.sign,
      t: sign.t,
      nonce: sign.nonce,
    },
  });
  return res.data.body;
};

実装の雑な部分は許して…。

Mackerel サービスメトリックについて

自分の場合、こんな感じでサービスメトリックを使用してスマートホームのメトリクスを集約しています。SmartHome というサービスの配下に、スマートホーム関連の各メトリックを集約しています。

回線速度を Mackerel x Greengrass x Raspberry Pi で監視する
最近気持ちが忙しくてブログ更新久しぶりな気がする。。タイトルの通りネットワーク回線の速度を監視し始めたのでメモ。 モチベーション SNS の方で呟いてましたが引越しすることになりました。 引っ越すからベッド分解した´д` ; — †深淵の覚醒者† (@lorentzca) July 5, 2020 我々インターネットで生活している者たちにとって引越しで一番気になるのは回線の速度ですよね。次のおうちでも光回線が通っているのはもちろん確認済みなのですが、速度や安定性が気になるところです。 そこで回線速度を監視し、引越し後どれくらいの違いが出るか確認することにしました。結果は…

今回、メトリック名の設計は以下のようにしてみます。

  • homeoffice.temphum.temperature: 仕事部屋の温度
  • homeoffice.temphum.humidity: 仕事部屋の湿度
  • homeoffice.temphum.battery: 仕事部屋の温湿度計のバッテリー残量

Mackerel へ送信するコードはこんな感じ。

const sendTempHumToMackerel = async (
  temp_hum,
  mackerel_endpoint,
  mackerel_api_key
) => {
  const date = new Date();
  const sec = Math.floor(date.getTime() / 1000);
  const res = await axios.post(
    mackerel_endpoint,
    [
      {
        name: "homeoffice.temphum.temperature",
        time: sec,
        value: Number(temp_hum.temperature),
      },
      {
        name: "homeoffice.temphum.humidity",
        time: sec,
        value: Number(temp_hum.humidity),
      },
      {
        name: "homeoffice.temphum.battery",
        time: sec,
        value: Number(temp_hum.battery),
      },
    ],
    {
      headers: { "X-Api-Key": mackerel_api_key },
    }
  );
  console.log(res);
};

作成されたグラフ

順調に記録されていっていますね。🎉

温度 27 度、湿度 54%

バッテリーと湿度についてはパーセント表記にしたいですが、メトリックの単位はサービスメトリック単位で設定可能で、メトリック名個別の単位では設定できないので、とりあえず整数として設定してます。まあわかるとは思いますが、メモの部分に単位の説明書いておこうかな。

感想

全体を通して特に特別なことはしておらず、公式のサンプル等ほぼそのままで出来ました。今後は寝室等にも設置して、bedroom.temphum.* といった形で記録していければと思います。その際は今回作成した関数を使用し、コードもちょっと整理していい感じに使いまわせるようにしていければ!

しかしスマートデバイス、めっちゃ手軽になりましたね。Raspberry Pi で何かする気分にならないくらい… (良い感じの使い道考えないと…)。