tp-link tapo スマートプラグ P105 を Pythonで制御

やりたいこと

出先から AC100V の ON/OFFをしたり、温度監視してる ラズパイ や NanoPiNEO で自動的に ON/OFF させたい。
シンプルにそれだけw

用意したもの

tp-link スマートプラグ Tapo P105
(一応、扇風機や暖房器具、電熱器など無人では危険のあるものには使うなと書いてあるけど、自己責任で小型ファンに使っちゃう…)

TP-Link WiFi スマートプラグ 遠隔操作 直差しコンセント Echo シリーズ/Google ホーム 対応 音声コントロール サーキュレーター ハブ不要 3年保証 Tapo P105 4個セット
Tapo P105 4-pack

Nano Pi NEO Ubuntu22.04(Linuxなら別にラズパイでも問題ないかと)
スマホ Android 11 Termux

tapo ライブラリをインストール

今回、2つの端末で自動制御したかったので、2つを併記。

Nano Pi NEO = Ubuntu で使いたい場合
$ python -m venv tapo_smartplug
$ cd tapo_smartplug
$ ./bin/pip install tapo
Android 11 Termux で使いたい場合
$ pkg install build-essential rust binutils
$ python -m venv tapo_smartplug
$ cd tapo_smartplug
$ getprop ro.build.version.sdk
  30                …… ここで出る数字が大事(Android の APIレベル)
$ export ANDROID_API_LEVEL=30   …… 一つ上のコマンドで表示された数字を入力
$ ./bin/pip install tapo

Tapo アプリの設定

スマホには Tapo アプリも入れておき、初期設定は済んでいる前提。(アプリからの ON/OFF 操作ができている状態を想定)
スマートプラグをコンセントに差し込んで、橙緑の LED が点滅しているのを確認したら Tapo アプリを立ち上げ、表示されるメッセージ通りに設定していけばよいのでそれほど難しくはないかな。

ただ、1か所、APIからの制御用に設定変更が必要。
Tapo アプリを開き、「サービス」メニュー内にある「音声アシスト」を開く

さらに、「サードパーティ連携」を「オン」にする。

以上で Tapo アプリの設定変更もOK。

ざっくり動作確認用のコード

基本的なコードとしては下記。
これでON/OFFできるようになる。

import sys, asyncio
from tapo import ApiClient
 
class TapoPlugController:
 
    def __init__(self):
        self.email  = "your email address"
        self.passwd = "your password"
        self.ipaddr ="plug ip address (local)"

    async def switch(self, flag):
        # APIクライアント作成
        client = ApiClient(self.email, self.passwd)
 
        # P105 (スマートプラグ) の指定
        device = await client.p100(self.ipaddr)
 
        if flag == "on":
            # ONにする
            await device.on()
            print("ONにしました")
        else:
            # OFFにする
            await device.off()
            print("OFFにしました") 
 
    def turn_on(self):
        asyncio.run(self.switch("on"))

    def turn_off(self)
        asyncio.run(self.switch("off"))

def main():
    if len(sys.argv) > 1:
        flag = sys.argv[1].lower()
 
        plug = TapoPlugController()
        asyncio.run(plug.switch(flag))
 
if __name__ == "__main__":
    main()

上記コードが tapo_plug.py というようなファイル名だったら…

$ ./bin/python tapo_plub.py on
$ ./bin/python tapo_plub.py off

で ON/OFF ができる。

とりあえず、プラグには何もつながないで、実行してみると、プラグ内部でリレーが作動するカチカチ音がするので、問題なさそうなら実際に何か繋げて見て試してみるといいかも。

尚、個人的にはこれ単体で実行することはあまりないので、ON/OFFメソッドを持たせてる。

なので、別のコードから下記みたいにインスタンス作って turn_on や turn_off を呼び出してあげれば ON/OFF できるね。

import time
from tapo_monitor import TapoPlugController
 
class FanCon:
    def __init__(self):
        self.tp = TapoPlugController()
 
    def fan_on(self):
        self.tp.turn_on()
 
    def fan_off(self):
        self.tp.turn_off()
 
 
def main():
    fc = FanCon()
    fc.fan_off()
    time.sleep(60)
    fc.fan_on()
  
if __name__ == "__main__":
  main()

IP アドレスはどうやって見つければいいのさ!?

Tapo アプリ > 調べたいプラグをタップ > 右上の◎アイコンをタップ > 端末情報

ここで IP アドレスが確認できる。

あるいは、NetEnum のような IP アドレスの検索ツールなどでMACアドレスが「58:04:4F」で始まるものを探すのもあり。
(ただ、出荷数が相当あるだろうから、MACアドレスは他にもあると思うので、あまりあてにならんね…)

この記事にコメントしてみる