概要
スマートプラグ Tapo P110M を Python(python-kasa)から制御して自作 PDU(電源タップ)を作ろうとしたとき、Discover.discover() が何も返さず「デバイスが見つかりませんでした」で止まりました。原因はライブラリではなく Tapo アプリ側の設定で、デバッグログには encrypt_type='TPAP' と Unsupported device が出ていました。その解決手順と、discover が不安定なときのリトライ処理をまとめます。
つまずいたポイント
同じ Wi-Fi に P110M が 2 台つながっていて Tapo アプリからは普通に操作できるのに、次のコードが空の結果を返しました。
import asyncio, os
from dotenv import load_dotenv
from kasa import Discover
load_dotenv()
async def main():
devices = await Discover.discover(
target="192.168.1.255", # 自分のLANのブロードキャストアドレス
username=os.environ["TAPO_EMAIL"], # TP-Linkアカウントのメール
password=os.environ["TAPO_PASSWORD"],
discovery_timeout=8,
)
print(devices) # {} …見つからない
asyncio.run(main())
python-kasa のデバッグログを見ると、デバイスからの応答自体はあるものの encrypt_type='TPAP' の暗号化方式で「Unsupported device」と判定されていました。
P110M のファームウェア 1.4.1 以降は、Tapo アプリ側で明示的に許可しない限り、サードパーティ製ツールからのローカル API 制御をブロックする 仕様に変わっています。python-kasa のバージョンを上げても、この設定を変えないと discover できません。
解決: Tapoアプリで「サードパーティ連携」をONにする
- Tapo アプリ → 右下の「私」タブ
- 「サービス」欄の「音声アシスタント」(バージョンによっては「Tapoラボ」)を開く
- 一覧の下の「サードパーティ連携」のトグルを ON
- P110M 1台ごとに個別に 設定が必要
「音声アシスタント」のすぐ上にある「Tapo と Kasa を連携」は別機能(旧 Kasa ブランドのアカウント統合)なので触りません。ライブラリ名 python-kasa と紛らわしいですが無関係です。
2 台とも ON にしてから再実行すると、{ip: SmartDevice} が返るようになりました。この出力に MAC アドレスも含まれるので、デバイス管理のキーとして控えておくと便利です。
discoverが1回で成功しないことがある
運用していると、discover が 1 回目は一部/全部のデバイスを取りこぼし、リトライで揃うことがありました(モバイルルーターのブロードキャスト遅延を疑っています)。単純なリトライで実用上は十分でした。
async def discover_with_retry(target_names, retries=3, delay_sec=3):
for attempt in range(1, retries + 1):
devices = await discover_known_devices(target_names)
if len(devices) == len(target_names):
return devices
print(f"検出に一部失敗(試行 {attempt}/{retries})。再試行します...")
await disconnect_all(devices)
await asyncio.sleep(delay_sec)
raise RuntimeError("デバイスの検出に失敗しました。ネットワークを確認してください。")
完全なソースコードと手順はブログにまとめています
python-kasa と PyP110 の選定理由、.env での認証情報管理、デバイスを IP ではなく MAC アドレスで管理する方針、個別 ON/OFF・一括 ON/OFF の実装、「サードパーティ連携」を有効にすることのセキュリティ上の考え方まで、以下の記事に書いています。
