ESP32とPythonダッシュボードで作る家庭用電力モニター!CTセンサー×Webグラフで消費電力を見える化する方法
「毎月の電気代が高い気がするけど、どの家電が電力を食ってるのかわからない…」
そんな悩みを持っている方、意外と多いんじゃないでしょうか。スマートメーターを契約会社に頼んで見せてもらうのも一手ですが、自分でリアルタイムに消費電力を見える化できたらもっと面白いですよね。
今回は ESP32 + CTセンサー(電流センサー)+ Pythonダッシュボード を組み合わせて、自宅のコンセントを流れる電流をリアルタイム計測し、ブラウザ上のグラフに表示する家庭用電力モニターを作ります。IoT × 電子工作 × Pythonの3つが合体した実践的なプロジェクトです!
✅ 対象読者:ESP32やArduinoの基本操作ができる初〜中級者(Pythonも多少書ける方)
✅ 難易度:★★★☆☆(電気工事の資格は不要!コンセントを直接改造しません)
仕組みの全体像をざっくりつかもう

まず全体のデータの流れをイメージしてください。
- CTセンサー(クランプ型)をコンセントのコードに挟む → 電流値をアナログ信号で出力
- ESP32がそのアナログ信号をADC(アナログ→デジタル変換)で読み取り、実効値(RMS)を計算
- ESP32が計算した電流値を Wi-Fi経由でHTTPリクエスト としてPythonサーバーに送信
- Python(Flask + Dash)がデータを受け取り、ブラウザ上のリアルタイムグラフに描画
コンセントの配線を直接いじらないので、電気工事士の資格は不要です。CTセンサーはケーブルの外側からクランプ(挟む)だけでOKなので、安全に電流計測できますよ。
必要な部品と環境
部品はすべて2,000〜3,000円程度で揃います。
- ESP32開発ボード(WROOM-32系で可)
- SCT-013-030(30A対応クランプ型CTセンサー)※ 出力タイプは「電圧出力(0〜1V)」を推奨
- バイアス抵抗(10kΩ × 2)とバイパスコンデンサ(10µF)
- PCまたはRaspberry Pi(Pythonサーバー用)
- Python 3.x(Flask・Dash・plotlyをインストール)
ソフトウェア側のインストールはこのコマンドでOKです。
pip install flask dash plotly pandas
STEP 1:ESP32のファームウェアを書く
CTセンサーの出力電圧をESP32のADCピン(GPIO34など)で読み取り、実効値(RMS値)を計算してWi-Fi送信します。RMS値とは交流電流の「実際の仕事量」に相当する値で、単純な最大値とは違います。
ポイントをまとめると:
- ADCを短時間に大量サンプリング(500回程度)して二乗平均の平方根を計算する
- ESP32のADCは0〜3.3Vの入力を想定。センサー出力がその範囲に収まるようバイアス回路で中点電圧(1.65V)を作る
- 計測した電流値をHTTP POSTでPythonサーバーに送る
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* serverUrl = "http://192.168.1.100:5000/data"; // PythonサーバーのIP
const int CT_PIN = 34; // ADC入力ピン
const int SAMPLES = 500; // サンプル数
const float VREF = 3.3; // ADC基準電圧
const float ADC_MAX = 4095.0;
const float CALIB = 30.0; // SCT-013-030 の定格(30A / 1V)
float calcRMS() {
long sumSq = 0;
for (int i = 0; i < SAMPLES; i++) {
int raw = analogRead(CT_PIN);
// 中点(2048)を引いてゼロクロス波形に変換
long offset = raw - 2048;
sumSq += offset * offset;
delayMicroseconds(200);
}
float rmsRaw = sqrt((float)sumSq / SAMPLES);
// ADC値 → 電圧 → 電流に変換
float voltage = rmsRaw * (VREF / ADC_MAX);
float current = voltage * CALIB;
return current;
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi接続完了!");
}
void loop() {
float current = calcRMS();
// 100V家庭用コンセントとして電力を計算(W)
float power = current * 100.0;
Serial.printf("電流: %.2f A 消費電力: %.1f W\n", current, power);
// JSON形式でPythonサーバーにPOST
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<128> doc;
doc["current"] = current;
doc["power"] = power;
String body;
serializeJson(doc, body);
int code = http.POST(body);
Serial.printf("HTTPレスポンス: %d\n", code);
http.end();
}
delay(2000); // 2秒ごとに計測・送信
}
このコードのポイントはここです:
calcRMS()でサンプリング → 二乗平均 → 平方根の順に計算しているのが実効値の本質- 電力(W)は「電流 × 電圧(100V)」で概算。より精度を上げたい場合は電圧センサーも追加します
ArduinoJsonライブラリを使うとJSONの組み立てが楽になります
STEP 2:PythonサーバーとDashダッシュボードを作る
次に、ESP32からのデータを受け取るFlaskエンドポイントと、リアルタイムグラフを表示するDashアプリを 1つのPythonファイル にまとめます。
import threading
import time
from collections import deque
from datetime import datetime
from flask import Flask, request, jsonify
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
# ---- データストア(最大200件を循環保持) ----
MAX_POINTS = 200
times = deque(maxlen=MAX_POINTS)
currents = deque(maxlen=MAX_POINTS)
powers = deque(maxlen=MAX_POINTS)
# ---- Flask(データ受信エンドポイント) ----
server = Flask(__name__)
@server.route("/data", methods=["POST"])
def receive_data():
body = request.get_json()
if not body:
return jsonify({"error": "no data"}), 400
times.append(datetime.now().strftime("%H:%M:%S"))
currents.append(body.get("current", 0))
powers.append(body.get("power", 0))
return jsonify({"status": "ok"})
# ---- Dashアプリ(リアルタイムグラフ) ----
app = dash.Dash(__name__, server=server)
app.layout = html.Div([
html.H1("🏠 家庭用電力モニター",
style={"textAlign": "center", "fontFamily": "sans-serif"}),
dcc.Graph(id="power-graph"),
dcc.Graph(id="current-graph"),
# 2秒ごとにグラフを更新
dcc.Interval(id="interval", interval=2000, n_intervals=0)
])
@app.callback(
[Output("power-graph", "figure"),
Output("current-graph", "figure")],
Input("interval", "n_intervals")
)
def update_graphs(_):
t = list(times)
p = list(powers)
c = list(currents)
power_fig = go.Figure(
go.Scatter(x=t, y=p, mode="lines+markers",
line=dict(color="#e74c3c", width=2),
name="消費電力 (W)")
)
power_fig.update_layout(
title="消費電力 (W)",
xaxis_title="時刻",
yaxis_title="W",
template="plotly_white"
)
current_fig = go.Figure(
go.Scatter(x=t, y=c, mode="lines+markers",
line=dict(color="#3498db", width=2),
name="電流 (A)")
)
current_fig.update_layout(
title="電流 (A)",
xaxis_title="時刻",
yaxis_title="A",
template="plotly_white"
)
return power_fig, current_fig
if __name__ == "__main__":
# Flaskサーバーを別スレッドで起動
flask_thread = threading.Thread(
target=lambda: server.run(host="0.0.0.0", port=5000, use_reloader=False)
)
flask_thread.daemon = True
flask_thread.start()
# Dashアプリをメインスレッドで起動
app.run(debug=False, host="0.0.0.0", port=8050)
ここが重要です:
deque(maxlen=200)を使うと古いデータが自動的に捨てられ、メモリが膨らみません- FlaskとDashを同じプロセスで動かすために スレッドで分離 しています
- ブラウザで
http://localhost:8050を開くとグラフが表示されます
STEP 3:動作確認をしておきましょう
起動の流れはこうなります。
- PCでPythonスクリプトを実行 → Flaskサーバー(ポート5000)とDashアプリ(ポート8050)が起動
- ESP32のスケッチを書き込み、シリアルモニタで「Wi-Fi接続完了!」を確認
- CTセンサーを計測したい家電のコードにクランプ(外側から挟むだけ)
- ブラウザで
http://<PythonサーバーのIP>:8050を開く - 2秒ごとにグラフが自動更新されれば成功です🎉
ESP32のシリアルモニタにこんな出力が出れば正常動作しています。
Wi-Fi接続完了!
電流: 1.23 A 消費電力: 123.0 W
HTTPレスポンス: 200
電流: 1.25 A 消費電力: 125.0 W
HTTPレスポンス: 200
精度を上げるヒント・応用アイデア
基本動作が確認できたら、こんな改善も試してみてください。
- ⚡ 電圧センサー(ZMPT101B)を追加:電圧も計測することで有効電力(W)と力率を正確に算出できます
- 💾 CSV/SQLiteに記録:Pythonサーバー側でデータを保存すれば、日別・時間帯別の消費電力グラフも作れます
- 📱 閾値アラート:消費電力が500Wを超えたらLINE Messaging APIで通知を飛ばす処理をFlask側に追加すると省エネ意識が高まります(※かつて使われていたLINE Notifyは2025年3月末にサービス終了しています)
- 🔌 複数回路の監視:CTセンサーを複数つなぐことでエアコン用・電子レンジ用など回路別に見える化できます
まとめ
今回は ESP32 + CTセンサー + Python(Flask・Dash) を組み合わせて、家庭の消費電力をリアルタイムにブラウザグラフで見える化する電力モニターを作りました。
コンセントを直接改造せずに電流計測できるCTセンサーのおかげで、安全に試せるのが嬉しいポイントです。データを蓄積していくと「夜9時以降の待機電力が意外と多い」といった発見があって、省エネへのモチベーションも上がりますよ。
ぜひ手元で試してみてください!わからない部分があればコメントで気軽に質問してくださいね 😊

こちらも読まれています
📡 Arduinoをもっと深く学ぼう!
Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





