SwitchBotプラグミニの消費電力を1分ごとに記録するアプリを作った——公式APIでわかったこと・わからなかったこと

この記事でわかること

SwitchBotプラグミニは、コンセントに挟むだけで家電の消費電力が見えるようになる便利なデバイスです。ただ、見えるのと「データとして残る」のは別の話でした。アプリから取り出せるのは1日単位の値で、「エアコンが何時に動き出して、何時ごろ落ち着いたのか」は取り出せません。

公式APIも履歴は持っておらず、返してくれるのは「いまの値」だけ。それなら、1分ごとに自分で聞いて貯めればいい——そうやって作ったのがからくりメーターという自作アプリです。サーバーは1台も立てず、Cloudflareの無料枠だけで動いています。

この記事は、それを作りながら実機2台(冷蔵庫とエアコン)を相手に確かめたことの記録です。公式ドキュメントの説明と実際の値が食い違っていた話から、「値がしばらく更新されない」という知らないと戸惑う仕様の正体まで。

  • 作ったもの(構成と、無料枠でどこが先に詰まるか)
  • 「毎分きっかり」に記録するためのちょっとした工夫
  • APIが返す3つの数字が、実際には何を表していたのか
  • 値が凍って見える挙動の正体と、その付き合い方

プラグミニというデバイス自体の紹介はSwitchBotプラグミニの記事にまとめているので、そちらもあわせてどうぞ。

なぜ作ったのか

きっかけは、冷蔵庫とエアコンにプラグミニを付けて、消費電力を眺めていたときの物足りなさです。

  • 取り出せるデータは、アプリの書き出しなら1日単位、公式API(v1.1)なら「いまの状態」だけ。あいだの粒度がない
  • 1日1点では、エアコンが立ち上がるときの大きな山も、冷蔵庫が数十分おきに動いている様子も、まるごと平らにならされてしまう

過去のデータが取れないなら、いまの値を貯め続ければ、明日には過去のデータになります。理屈はそれだけです。

作ったもの:からくりメーター

役割使ったもの
定期実行Cloudflare Workers の Cron Triggers(毎分)
データ取得SwitchBot API v1.1
保存Cloudflare D1(SQLite)
表示同じWorkerがダッシュボードも配信
保護Cloudflare Access(自分だけがログインできる)

やっていることは単純で、1分に1回プラグミニに「いま何ワット?」と聞いて、答えをデータベースに1行書き足すだけ。あとはそれをグラフにして眺めます。直近1時間は1分ごと、24時間は1時間平均、30日は1日平均、と3段階で切り替えられるようにしました。

からくりメーターのダッシュボード画面(直近24時間・1時間平均)。冷蔵庫とエアコンの消費電力の折れ線グラフが縦に並ぶ

無料枠の見積もりはこうです。

  • SwitchBot API:1日10,000回まで(公式ドキュメント・2026年8月時点)。計測中の2台を毎分で2,880回。増やすとしても6台(8,640回)までは安全圏で、7台だと10,080回で上限を超える
  • D1の書き込み:無料枠は1日10万行。2台で1日2,880行なので、こちらはかなり余裕

……と、ここまでは事前の計算どおりでした。実際に効いてきたのは、まったく別のところです。

実装でつまずいたところ

「毎分」を分の頭にそろえる

毎分動かすように設定しても、処理が実際に走る時刻は00秒ちょうどではありません。数秒遅れることもあります。そこで素直に「処理した瞬間の時刻」を記録してしまうと、12:00:03、12:01:07、12:02:58……と刻みがガタガタになって、1分ごとに並べて見比べるのが難しくなります。

Workersの定期実行では、起きた実時刻ではなく起きる予定だった時刻を受け取れます(controller.scheduledTime)。予定時刻は必ず分の頭なので、これを秒以下で切り落として記録します。処理が何秒遅れていようが、記録は12:00:00、12:01:00ときれいに並びます。

ついでにもうひとつ。テーブルの主キーを「時刻+デバイスID」の組にしておきました。定期実行はごくまれに二重に起動することがありますが、同じ予定時刻なら主キーも同じになるので、2回目は黙って無視されます。時刻をそろえる工夫が、そのまま重複対策にもなっているわけです。

先に効いてくるのは、書き込みではなく「読み取り行数」

D1の無料枠は、書き込みが1日10万行に対して、読み取りは1日500万行Cloudflare公式の料金ページ・2026年8月時点)。数字だけ見れば読み取りのほうが50倍余裕がありそうですが、詰まるのはこちらでした。

ダッシュボードの「30日を1日平均で見る」ビューは、30日ぶんの生データ——2台なら約86,400行——を読んで平均を計算します。画面を1回描くだけで約8万6千行。当初これを1分ごとに自動更新していたので、タブを開きっぱなしにしていると1日あたり1億行を超える計算でした。上限の20倍以上です。

対策は簡単で、自動更新をやめました。いまはタブに戻ってきたときと、更新ボタンを押したときだけ読み直します。データは1分刻みで貯まり続けるので、見たいときに最新が出れば何も困りません。

もうひとつの伏兵がストレージでした。無料枠はアカウント全体で5GBある一方、1つのデータベースあたりは500MBD1の上限ページ・2026年8月時点)。索引まで含めると実効で1行130バイト前後、2台でも年140MB近くになる計算なので、「何十年でも貯め放題」とはいきません。数年に一度、古いデータを1時間平均に圧縮する日が来ます。

APIが返す3つの数字は、何を表していたのか

プラグミニの状態を取得すると、電圧(V)とあわせて、電力まわりで3つの値が返ってきます。この3つの意味をはっきりさせるのに、いちばん時間を使いました。

フィールドドキュメントの記述実機で確かめた意味
weight1日に消費した電力(W)いまこの瞬間の消費電力(W)
electricCurrent現在の電流(mA)皮相電流(mA)。電圧を掛けても消費電力にならない
electricityOfDayその日に使われた時間(分)記述どおり。電力量ではない

weight は「1日の」ではなく「いまの」消費電力

公式ドキュメントの説明は “the power consumed in a day, measured in Watts”(Plug Mini (JP) のデバイス仕様・2026年8月時点)。素直に読めば「1日に消費した電力」ですが、単位がW(ワット)なのが引っかかりました。1日ぶんの積み上げなら、単位はWh(ワットアワー)でなければ計算が合いません。

実機で確かめると答えははっきりしていて、冷蔵庫の値はコンプレッサーが回り出すと上がり、止まると下がります。数十秒単位で上下する。1日の積算値がこんな動き方をするはずがありません。weightいまこの瞬間に何ワット使っているかを返しています。ドキュメントの表現に引きずられると、グラフの意味をまるごと読み違えるところでした。

electricCurrent は皮相電流——電圧×電流は消費電力にならない

電圧と電流が両方取れるなら掛け算すれば電力になる——と思ったら、weight と一致しません。しかも機器によってズレ方が違いました。

これは交流の教科書どおりの話で、「電圧×電流」(皮相電力)と「実際に消費される電力」(有効電力)は一致せず、その比を力率と呼びます。weight を「電圧×電流」で割ってみると、冷蔵庫は約0.6〜0.66、エアコンは約0.94でした(冷蔵庫は動作点によって少し変わります)。モーターを回す冷蔵庫の力率が低く、最近のインバータ式エアコンが1に近いのは、まさに機器の特性そのものです。数字が理屈どおりに出てくると、ちょっと嬉しくなります。

というわけで electricCurrent は皮相電流であって、電力の計算には使えません。使うべきは weight 一本です。

electricityOfDay は電力量ではない——だから作る意味があった

名前だけ見ると「その日の電力量」に見えますが、これはその日プラグに電気が流れていた時間(分)でした。ドキュメントにもそう書いてあるので、誤解していたのはこちらです。

つまり、このAPIからは電力量(kWh)が直接は取れません。電気代に換算したければ、ワット数の時系列を自分で積分するしかない。1分ごとに記録するアプリを作る理由が、ここで腑に落ちました。記録しない限り、計算のしようがないのです。

いちばんの発見:値は「大きく変わったとき」しか届かない

しばらく動かしていて、気になることが出てきました。

エアコンが安定運転に入ると、消費電力の値が何十分も1ワットたりとも動かないのです。冷蔵庫はコンプレッサーの入り切りに合わせてきちんと上下しているのに、エアコンの折れ線だけが定規で引いたように水平になる。

決定的だったのは、SwitchBotアプリを開いて、プラグミニの現在の消費電力が出る画面を表示したときでした。その瞬間から、APIで取れる値も動き出したのです。アプリを閉じてしばらくすると、また凍る。

1分ごとビューのグラフ。エアコンの消費電力は280.1ワットの水平線のまま変化せず、同じ時間帯の冷蔵庫は0ワットと60ワットのあいだを行き来している

気になったので、からくりメーターとは別に、1分おきにAPIから値を取り続けて挙動を観察しました。手がかりにしたのは electricityOfDay(通電時間のカウンター)です。電源が入っていれば毎分1ずつ増えるはずの値なので、これが止まっていたら「いま受け取ったレスポンスは古い」と機械的に判定できます。

わかったことは3つです。

  • 値は数十分単位で止まる。コンプレッサーが休んで値がほとんど動かない時間帯には、あの冷蔵庫でも通電時間カウンターが一度に76分ぶんジャンプしました。それまでAPIが返し続けていたのは、70分あまり前のスナップショットだったわけです
  • 止まり方を決めるのは時計ではなく、変化の大きさ。実測では、375ワットの急変は1分で反映、33ワットの変化は7分後、0.1ワットしか動かない状態では30分近く観測しても届かない——大きく動くほど早く届きます
  • アプリでそのデバイスの画面を開いているあいだだけ、毎分更新になる。閉じると数分で元に戻ります(この確認はエアコンで実施。凍り方そのものは、購入時期もファームウェアも違う2台で同じでした)

つまりプラグミニは、測った値を律儀に毎分クラウドへ送っているのではなく、大きく変わったときだけ報告する方式でした。故障でもバグでもなく、通信を節約する合理的な設計です。公式に明文化された仕様ではないので断定は避けますが、自宅の2台でははっきり再現します。なお「どれだけ変化したら報告するのか」というしきい値そのものは、最後までわかりませんでした。

ならば取得の頻度を上げれば——とは、なりません。

  • 公式APIには「最新の値を取ってこい」に相当する操作がありません。値を読み取る口は、デバイス一覧とステータス取得の2つだけです(ほかにあるのは家電を操作する制御コマンドで、読み取りには使えません)
  • 変化を通知してくれるWebhookの仕組みはありますが、プラグミニ(JP)のイベントに入っているのは電源のオン・オフだけで、消費電力の値は含まれていませんデバイス仕様・2026年8月時点)

クラウド越しに取れる値の上限は「プラグが最後に報告した値」で、こちらから催促する手段はない。取得を速くしても、同じ値を受け取る回数が増えるだけです。これは記録間隔を1分に固定した根拠にもなりました。

(厳密には、プラグに制御コマンドを送りつければ通信が発生して値が更新される、という抜け道はあります。ただしそれは、冷蔵庫につないだプラグに「オンにしろ」と命令を送るという話です。このアプリは記録専用で家電には一切指示を出さない方針にしているので、うちでは採りません)

この仕様とどう付き合うか

わかってしまえば、付き合い方は決まります。

  • 1分ごとの折れ線は「等間隔の計測」ではなく「イベントの記録」として読む。グラフが階段状になるのは、段の一つひとつが報告の瞬間だからです
  • 大きな出来事はちゃんと残る。冷蔵庫のコンプレッサーの入り切りや、エアコンの出力の切り替わりのような数十ワット級の変化は数分以内に届きます。だから1時間平均・1日平均のグラフには十分な実体があります
  • 細かいゆらぎは潰れる。数十ワット未満の変化や短いスパイクは、次の報告までまとめて1点に丸められます。わが家の用途——見守りと、電力量のざっくり把握——には、これで必要十分です
  • 通電時間カウンターは、レスポンスの鮮度センサーになる。前回取得時と同じ値なら、その行は新しい観測ではない。記録側にこの判定を入れておけば、凍っていた区間をあとから見分けられます

まとめ

  • プラグミニの消費電力は履歴が取れないので、1分ごとに記録するアプリを自作した。Cloudflare WorkersとD1の無料枠に収まるが、収め方には一工夫いる
  • 定期実行で時刻を刻むときは「起きた時刻」ではなく起きる予定だった時刻を使う。記録がきれいに1分ごとに並び、二重起動の対策にもなる
  • 無料枠で先に効いてくるのは書き込みよりも読み取り行数。画面の自動更新をやめるだけで解決した
  • APIの weight は1日の積算ではなくいまの消費電力electricCurrent は皮相電流なので電圧を掛けても消費電力にはならない(力率のぶんずれる)。electricityOfDay は通電時間で、電力量はAPIからは取れない
  • クラウドAPIが返すのは、プラグが大きく変わったときだけ報告してくる値。等間隔の計測ではなくイベントの記録として読めば、1時間平均のグラフは信頼して読める。どれだけ変わったら報告されるのか——そのしきい値だけは、最後までわからなかった

同じことを試す人がいたら、「値は等間隔の計測ではなく、イベントとして届く」という前提だけでも持ち帰ってもらえたらうれしいです。