TP-LINK TAPO P100/P105/P110をESP32から直接制御する

TP-LinkからHS105より低価格なTapo P105が発売されたのを知り、HS105同様に制御できるのかと試しに購入してみたが全く動かない。

Tapo系にはカメラもあるからセキュリティはより厳しくしてあるのかな?なーんて思っていたら最近になってリバースエンジニアリングしてプログラムを作ってしまった猛者が現れた。

どうやらTP-Linkの製品はリバースエンジニアリングされる運命にあるようだ。(笑)

Reverse engineering TP-Link TAPO
GitHub – fishbigger/TapoP100

試してみるとP105ではエラーで動作しなかったが、リクエストパラメタにP105のMACアドレスを設定したterminalUUIDパラメタを追加することで動作することが確認できた。ということで元のPythonのプログラムを参考にESP32に移殖しようと思ったのだが公開鍵暗号や共通鍵暗号などを使っていてそれをどう対応するかで暫し悩んでしまったが調べてみたらESP32に含まれているmbedtlsライブラリが使えそうだとわかる。その他、base64やcJSONなど実装に必要なライブラリは全てESP32に含まれていた。でも、JSONをC言語関数でゴリゴリ書く気にはならなかったのでより簡単に記述できそうなArduino_JSON(cJSONのC++ラッパーライブラリ)のみ別途インストールして使ってみた。バージョンが0.1.0で[BETA]版らしいが今のところ問題なく使えている。

しかし、久しぶりにハマりまくった。試験するとエラーレスポンスばかりで全く動かない。クッキーの内容が不正なことが原因だったがP105が返すエラーコードの意味がわからず、あーでもないこーでもないと手当たり次第に検証した結果、何日もかかってしまった。mbedtlsも公開鍵暗号(RSA)も共通鍵暗号(AES)も初めてだらけだったので単純なところよりも知らないほうにばかり目が行ってしまったのが敗因かもしれない。

あとP105の処理能力が低くて反応が鈍い?ためなのか連続制御すると時々HTTPエラーが発生してしまう。リトライ処理を追加し解決できたようだ。

ちなみにTapoアプリでデバイス登録した状態でないと動作しないことに注意しよう。

【概要】

hostnameにIPアドレス、usernameとpasswordにTapoアプリに登録したメールアドレスとパスワードを指定する。

空実装。

HTTPエラーコードを取得する。

TAPOデバイスのエラーコードを取得する。

mbedtls-apiのエラーコードを取得する。

base64エンコードされている文字列をデコードする。デバイス情報のnicknameとssidをデコードするさいに使う。

info引数に電力モニター情報をJSON文字列形式で格納する。戻り値は処理結果。trueは成功、falseは失敗。

info引数にデバイス情報をJSON文字列形式で格納する。戻り値は処理結果。trueは成功、falseは失敗。

デバイスをオン/オフ制御する。戻り値は処理結果。trueは成功、falseは失敗。

【対応ファームウェア】
P110M: 1.1.0 Build 231009 Rel.155719 以前
P105: 1.4.1 Build 20231103 Rel. 36519 以前

【修正】
2024-01-08
上記ファームウェア(Build 231009)以降に対応したものは下記を見るべし。
TP-LINK Tapo P110M のKlapプロトコル対応版 (ESP32)

2023-12-12
P110Mの最新ファームウェア(Build 231009)以降では通信プロトコルが変更されため1003エラーが発生します。動作中のP110Mをお持ちの方はTAPOアプリの自動更新をオフに設定することを推奨します。

2023-09-16
間違ってlinux/windows用のコードを掲載してしまっていたので正しいコードに変更。<(_ _)>

2023-09-15
いつからかはわからないがP105が動作しなくなっていたので修正。ついでにP110Mの電力モニター機能(getEnrgyUsage)に対応。

【サンプル・スケッチ】

【ライブラリ】

【参照ライブラリ】
Arduino_JSON

【関連投稿】
TP-LINK WiFiスマートプラグをESP32(Arduino)から制御する
TP-LINK WiFiスマートプラグをLinux/Windowsから直接制御する
TP-LINK TAPO P100/P105をESP32から直接制御する
TP-LINK TAPO P100/P105をLinux/Windowsから直接制御する