📝 はじめに
この記事で書くこと
- SwitchBot Plug Mini を使った電力監視システムの全体設計
- FastAPI / Supabase / Flutter Web の技術スタック選定理由
- システムアーキテクチャとデータフローの解説
対象読者
- IoT × Web開発に興味がある方
- SwitchBot APIを活用したアプリを作りたい方
- Python / Dart での開発経験がある中級者
前提
- Docker / Docker Compose の基本知識
- REST API の基本概念
🎯 背景・動機
なぜ電力監視アプリを作ったのか
きっかけ
電気代の高騰が続く中、「どの機器がどれだけ電力を消費しているのか」を把握したいと思いました。
SwitchBot公式アプリの課題
- 複数デバイスの電力をまとめて可視化しにくい
- 長期間のデータを保存・分析できない
- カスタマイズが難しい
解決策
以前に書いた記事
SwitchBotプラグミニ 消費電力定期取得 (準備編) #Python - Qiita
SwitchBotプラグミニ 消費電力定期取得 (実践編) #Python - Qiita
をベースに、自分専用の電力監視ダッシュボードを作ることにしました。
実現したい機能
| 機能 | 説明 |
|---|---|
| リアルタイム監視 | 現在の電力消費をリアルタイム表示 |
| データ蓄積 | 5分間隔でデータを自動収集・保存 |
| 可視化 | 時系列グラフで消費パターンを分析 |
| 複数デバイス対応 | サーバー、ディスプレイなど複数機器を一元管理 |
🛠️ 手順/解説
システムアーキテクチャ
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ SwitchBot │ │ SwitchBot │ │ │
│ Plug Mini │────▶│ Cloud API │────▶│ FastAPI │
│ (デバイス) │ │ (外部API) │ │ Backend │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Flutter Web │◀────│ Supabase │◀────│ 5分間隔で │
│ Frontend │ │ (PostgreSQL) │ │ データ収集 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
なぜこの構成を選んだか
バックエンド: FastAPI
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="SwitchBot Power Monitor API", version="1.0.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
選定理由
-
非同期処理:
async/awaitによる効率的なI/O処理 - 自動ドキュメント: Swagger UI が自動生成される
- 学習コスト: Flask経験があれば習得が容易
フロントエンド: Flutter Web
# pubspec.yaml
dependencies:
flutter:
sdk: flutter
fl_chart: ^0.68.0 # グラフ表示
http: ^1.1.0 # HTTP通信
選定理由
- クロスプラットフォーム: 将来的にiOS/Androidも同一コードで
- Material Design: 美しいUIが標準で使える
- fl_chart: 高品質なグラフライブラリ
データベース: Supabase
選定理由
- PostgreSQLベース: SQLの知識がそのまま使える
- 無料枠: 小規模プロジェクトなら無料で運用可能
- 集計関数: AVG, MAX, MINが使えて時系列分析に便利
プロジェクト構成
switchbot-power-monitor/
├── backend/ # Pythonバックエンド
│ ├── main.py # FastAPIアプリケーション
│ ├── switchbot_client.py # SwitchBot API クライアント
│ ├── supabase_client.py # Supabase クライアント
│ └── config.py # 設定管理
│
├── frontend/ # Flutterフロントエンド
│ ├── lib/
│ │ ├── main.dart # メインアプリ
│ │ ├── chart_page.dart # グラフ表示
│ │ └── supabase_service.dart # API通信
│ └── pubspec.yaml
│
├── docker-compose.yml # コンテナ構成
└── .env.example # 環境変数テンプレート
環境変数の設定
# .env
SWITCHBOT_API_TOKEN=your_token_here
SWITCHBOT_API_SECRET=your_secret_here
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_KEY=your_anon_key_here
セキュリティ注意
-
.envは.gitignoreに追加 - 本番環境では環境変数として設定
4. 実行結果 & コツ
Docker Composeで起動
docker-compose up -d
APIエンドポイント一覧
| メソッド | パス | 説明 |
|---|---|---|
| GET | / |
API状態確認 |
| GET | /health |
詳細ヘルスチェック |
| GET | /devices |
デバイス一覧取得 |
| GET | /data/latest |
最新データ取得 |
| POST | /data/collect |
手動データ収集 |
つまずきポイントと回避策
つまずき1: CORS エラーでフロントエンドからアクセスできない
解決策: FastAPI に CORS ミドルウェアを追加
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 開発時は全許可、本番は制限
)
つまずき2: Dev Container 内から localhost にアクセスできない
解決策: ホストを 0.0.0.0 にバインド
uvicorn.run(app, host="0.0.0.0", port=8000)
📝 まとめ
学んだこと
アーキテクチャ設計の重要性
- 各コンポーネントの責務を明確に分離することで、開発・デバッグが容易になる
- SwitchBot API → FastAPI → Supabase → Flutter の4層構成は拡張性が高い
技術選定のポイント
- 将来の拡張を見据えた選定(Flutter でモバイル対応)
- 開発効率と学習コストのバランス