スマートテーブルタップを Python から制御する

(更新

How to control smart power strips by Python.

P.S. Jason Cox, the designer of TinyTuya kindly read this blog (despite written in Japanese) and commented on the error which happens when simultaneous accesses to a Tuya device were performed. Thank you very much!!

前置きに御興味ない方は、飛ばしてこちらからどうぞ。


以前から、家電製品やパソコン周辺機器などを「遠隔」からオン/オフする評価・試作をしてきました。10年ほど前は、真面目にそういうことをしようとすると数万円もするゴツい機器を購入し、Ethernet ケーブルを繋ぎ、IP アドレスを設定し、ウェブインターフェイスで複雑な設定をしなくてはいけませんでした。以下は、私が前職時代に職場(米国本社だったかな?)でよく見かけた製品です。

しかし時代は変わりました。ネットで、「スマートテーブルタップ」あるいは「スマートタップ」と検索すると、3,000〜5,000円程度で、コンパクト、かつ設定の簡単な製品が購入できるようになりました。以前は、PSE 認証を受けていない製品がほとんどでしたが、今は PSE 認証を受けた製品も普通に購入できるようになりました。例えば、こんなのです。

多くの製品は、スマートフォンにアプリをインストールすることでネットワーク設定ができ、屋外からでもスマートフォン一つで電源をオン/オフできるようになります。タイマ機能を使って、決まった時間にオン/オフしたり、今から 10分後に自動オフ、なんていうこともできます。

これはこれで素晴らしいことですが、われわれ技術屋としては、もう少し欲が出てくるものです。すなわち、

おうちサーバー、Raspberry Pi、Arduino マイコンから電源を制御できないだろうか?

そんなことは当然、世界中で考えている人がいて、こんなライブラリ TinyTuya を見つけました。

Python 言語を使って、「Tuya」というプラットフォームを利用したスマートコンセント、テーブルタップ、照明を制御しよう、というものです。

なお、IFTTT という有名なプラットフォームがあり、電源のオン/オフくらいなら Python を使わずに(いわゆる webhook だけで)可能ですが、IFTTT は利用者ポリシーの変更でしばらく混乱した時期があり、皆様に自信を持ってお勧めできない感じになっていますので、今回は利用しません。

また、TinyTuya を日本語で紹介くださっている方も多いのですが、TinyTuya、Tuya IoT Platform 共にアップデート(仕様変更)が速く、1年ほど前の情報が既に古くなっている模様です。そこで、最新の状況(2022年2月現在)を紹介させて頂きます。

Tuya ってなんだ?(しばらく前置き)

ネット量販店を探していると、実にさまざまな企業(多くは中国だと思います)がスマートコンセント、テーブルタップを製造していることが分かります。ちょうど、日本で 50年程前に、多くの企業がこぞって電卓製造に参入していた時代を連想させます。

しかしスマートコンセントの世界は、当時の電卓戦争以上に群雄割拠の状態に見えます。例えば、製品の外見は似ているのにメーカーが違ったりなど、まさに闇の世界にも感じられます。昔の真面目な日本人だったら、頭がクラクラして、付き合いの長い、近所の電器屋さんに駆け込みたくなるでしょう。(でも、おそらくそういう店で売っている製品も、ネット量販店で売っているものと同じだと思います。)

さて、閑話休題。ここで、いろんな製品を見ていると、大抵の製品が Google Home とか Amazon Alexa に対応していることをうたっていますが、それは無視して、その他のスマートフォンアプリを探します。そうすると、独自のアプリが必要な製品もありますが、多くの製品が  Smart Life あるいは Tuya Smart というアプリで操作するようになっていることが分かるはずです。私も未だに闇の中をさまよっているのですが、私の理解では、この分野の製品は

  • Smart Life アプリを使うもの
  • そうでなく、独自アプリを使うもの

と、大きく 2つに分けて考えれば良さそうです。

Smart Life というアプリの不思議な点は、ネットで購入できる多くのメーカーの製品が Smart Life に対応していることです。そして、Smart Life は国際標準化機関、あるいはいずこの国が決めた標準というものではなく、どうやら、あるメーカーが決めた規格が業界標準になって、それを多くの機器メーカーがライセンス形式で採用しているような感じです。

かつて日本では、多くの大手家電メーカーが、好き勝手にいろんな情報家電を売り出して、メーカー間のアプリの互換性などなく、他の機器と連携することなどできず、サードパーティやアマチュア工作家が連携アプリや連携機器を勝手に作ることもできませんでした。それだけならともかく、数年もたてばメーカーは純正アプリをサポートをしなくなり、新しい製品に買い換えてください、、、といった苦々しい状況でした。

そう、カーナビも同じではないでしょうか。購入直後はいろんなサービス(渋滞情報、モバイル通信)を利用できましたが、すぐに仕様が古くなり、最新の携帯電話やスマートフォンと連携利用できなくなったことを思い出します。(私のクルマのカーナビは現在、スマホを貼り付ける「板」に成り果てています。)

日本の多くのメーカーが業界標準の規格に追従しながらも切磋琢磨し、アプリや仕様を長期的にメンテナンスし、あるアプリメーカーが撤退すれば別のメーカーが取って代わり、、、という世の中にならなかったのは、残念なところです。

またまた脱線しました。すみません。

この分野、つまり、スマートフォンアプリからクラウド経由で家電を制御するという分野では、Tuya というリーディングカンパニーが大きな働きを果たしているようです。私は最初、大したクラウド、フレームワークではないんだろう。きっと、こんな製品やアプリは、2〜3年もしたらサポートされなくなり、使えなくなるんだろう、と思っていたのですが、予想に反して、どんどん底辺も垣根も広がっているようです。

後で説明しますが、Tuya の IoT プラットフォームは非常に大規模な設計になっていて、そのウェブコンソールは、Amazon AWS や Google Cloud に匹敵するほど複雑なものです。複雑なのは嬉しいことではありませんが、これだけしっかりした設計であれば、セキュリティもある程度考えているでしょうし、2〜3年で世の中からなくなってしまうものではないと思われます。仮に Tuya 社が撤退するとしても、別の企業がプラットフォームを引き継いでいくのではないでしょうか。

また余談ですが、Smart Life のモバイルアプリは非常にしっかりした設計になっています。私は以前から、仕事の都合でスマートコンセントを使っていましたが、今回、家庭の中で家族と利用することを思いつきました。家族とアカウント(メールアドレス)を共有する必要があるのでしょうか?

いや、そんなことはありませんでした。アプリでは、ユーザー、家族、部屋、機器といった概念が明確に定義されていて、例えばユーザーである私は、複数の家族(実際の家族と仕事用の利用)、リビングとキッチン、観賞魚水槽用のテーブルタップ、部屋の照明など、実に細かく制御できるようになっているのです。ユーザーを管理者に設定したり、管理を他人に委譲できたり。。。いやはや、Tuya 社の技術力、恐るべしです。

参考: 今までに購入した Tuya 対応機器(2023/7/18加筆)

参考までに、今までに購入した Tuya 対応機器をリストアップしておきます。既に入手不可能(メーカーが市場から撤退?)な機器が多いです。

  • Aitmexcn 社のもの: 2017年12月に Amazon.co.jp で購入。既に入手不可能の模様。中性極(アース)のピンが立っていて、日本国内でちょっと使いにくかった。現在も使用中。
  • Htwon 社のもの: 2019年6月に Amazon.co.jp で購入。メーカー自体は海外で販売しているようだが、日本では入手困難の模様。中性極がなく日本国内でも使いやすかった。PSE 認証もあったはず。現在も使用中。
  • TOP-FLEX スマートプラグ: 2022年1月に Amazon.co.jp で購入。現在も入手可。
  • Gosund 社 WP6: 2023年7月に Amazon.co.jp で購入。使用電力量を測定できるのが売りです。こちらに、Python で電力データを読み出す記事を書かせて頂きました。

(ようやく)Tuya Cloud でアカウントを作ってみよう

前置きが長くなりましたが、Tuya Cloud で登録すれば、Python からスマートコンセントを制御できるようになります。

Clould のリソースを大量に利用するようなアプリケーションでは有償(かなり高価。どうも、零細企業は相手にしていない模様)になりますが、テスト的な利用では 1〜数ヶ月間といった期間で無償利用できます。さらに、Cloud を介さずに機器を制御するのであれば(つまり、LAN のみを利用する)、完全に無償で利用できそうです。

詳しくはこちら: Registering a Cloud Project on iot.tuya.com is not free anymore · Issue #15 · jasonacox/tinytuya

最初に

まず最初に、既に Smart Life に対応したスマートコンセント等をお持ちで、スマートフォンに Smart Life をインストール、セットアップ済みだと仮定して話を進めます。ここで、Smart Life で登録するメールアドレスとパスワードは、以下で説明する Tuya Cloud 登録用のメールアドレスとパスワードとは異なるという点に注意してください。

もう一点、Smart Life 登録時に、電話番号の国番号のような設定でが日本(+81)になっていることを確認しておきます。これは重要で、Smart Life の設定が、どの国(地域)にあるデータセンタに登録されるかを決めるものなのです。日本(+81)の場合は、Western America Data Center(米国西海岸のデータセンタ)が利用されます。

アプリストアで探すと、似たようなアプリがたくさん出てきて混乱します。以下が正しいアプリのはずです。

さてその後ですが、TinyTuya の作者の方が、(以下の)私のものよりもずっと詳しく説明なさっていますので、(英語ですが)最初に一読しておくと良いでしょう。

ユーザー登録

ウェブブラウザから、こちらのサイトを開きます。以下のような画面が出ますので、Sign Up というテキストをクリックしましょう。

注意: どうも、Tuya のコンソール画面は頻繁に仕様変更があるそうです。以下の説明は、2022年2月現在です。この通りにならなかったらゴメンなさい。末尾の問い合わせフォームでお問い合わせ頂ければ、お手伝いできるかも知れません。

以下のような画面が出ますので、メールアドレス、パスワード、(もう一度)パスワード、組織名(省略可)、国名を選択します。Agree to… にチェックして、Next をクリックします。上にも書きましたが、これは Smart Life アプリで登録したメールアドレスやパスワードとは無関係です。混乱を避けるため、異なるパスワードを利用したほうが良いでしょう。

以下の画面に移ったら、メールで来る確認コードを入力します。

もう一度ログイン画面が開きますので、メールアドレスとパスワードでログインしましょう。

次のようなコンソール画面が開きます。

Continue というボタンをクリックします。そしてその後、しばらく Next ボタンを繰り返しクリックしていきましょう。最後に Done ボタンで終わります。もちろん、途中で表示される説明を読んでおくほうがベターでしょう。

すると、次のような画面が開きます。

そしたら、(皆さんが企業の担当者で、既に Tuya を大々的に導入することを決めている場合を除いて)左の Individual Developer を選択することになるでしょう。Set Now をクリックします。

なお、以下の Start Manual Review を始めると、かなり細かいことを聞かれますので、上の画面で、とりあえず Skip this step. を選んでも良いでしょう。もし下の画面が出てしまったら、慌てずその画面を閉じれば OK です。元のコンソール画面は依然として表示されているはずです。

次のような画面が開きます。

ここで最初に、上に表示されている Current Country/Region を確認しましょう。間違っている場合は Modify をクリックします。(Basic Information というところで、国名右の Modify というところをクリックし、正しい国名を選び、OK します。)

プロジェクトの登録

続いて、プロジェクトを登録します。コンソール画面の左から、Cloud というアイコンをクリックします。

また「Next」が出てきます。もちろん読んでも良いですし、Skip を押してもいいでしょう。すると、次のような画面になります。

右上の、Create Cloud Project をクリックします。次のような画面が出ます。

例えば、

  • Project Name: Cat Feeder(ネコの御飯あげ器)
  • Description: ネコの御飯タイマ制御
  • Industry: Smart Home
  • Development Method: Smart Home
  • Data Center: Western America Data Center(← ここ大事)

と入力して、Create します。上でも説明しましたが、Smart Life アプリを日本の国番号(+81)で登録した場合は、Western America Data Center を選びます。

Create を押すと、次のような画面が表示されます。

これはこのままで良いので、Authorize をクリックします。新しく作成されたプロジェクト Cat Feeder が開きます。

ここで、後で TinyTuya を使うときに必要になるので、

  • Access ID/Client ID
  • Access Secret/Client Secret

をメモしておきます。Secret のほうは、右にある「目」アイコンをクリックしないと見えません。なお、当然ですがこれは秘密情報(特に Secret のほう)なので、他人に見られないようにします。

続いて、このプロジェクト Cat Feeder と、皆さんの Smart Life アカウントをリンク(結び付け)します。ここが重要なポイントです。

上のほうに Overview, Authorization, Service API というタブが並んでいますが、その中から Devices を選択します。

続いて、Link Tuya App Account というタブをクリックします。私はここで間違えて、いきなり青い背景の Add Device というボタンを押してしまい 1時間ほどハマりました。

Link Tuya Account というタブを選ぶと次のようになるので、ここで初めて Add App Account をクリックします。

すると、以下のような QR コードが表示されます。

ここで、スマートフォンの Smart Life アプリを開きます。スマートフォンの画面右下に「プロフィール」(英語版 OS だと「Me」)と表示されているので、それをタップします。すると、画面の右上付近に次のようなアイコンが表示されますので、それをタップします。

そして、スマートフォンのカメラで、パソコンの画面上の QR コードをスキャンします。なお、ピントとブレにけっこうシビアなので、しっかりカメラを固定してスキャンしましょう。

無事に登録が終わると、コンソール画面が次のように変わります。

App Account の下には、リンクした Smart Life アプリの登録メールアドレスが表示されます。右には UID(なんでしょう?)、App Name(智能生活 = Smart Life?)、デバイス数(皆さんは 1かも知れません)、Cat Feeder などが表示されます。これで、無事にスマートコンセントをクラウド、あるいはローカルの Python から制御できるようになりました!

まずはクラウドからテスト

さっそく、クラウドのコンソール画面からテストしてみましょう。コンソール画面で、Link Tuya App Account というタブの左の方にある、All Devices をクリックして選択します。

すると、先ほど登録したデバイスの名前(「リビングのテーブルタップその1」など)が左に表示され、続いて Device ID、Product(「普通单灯智能插座-欧规」、「4插口带USB智能排插」など)Online Status は Online になっているでしょうか?  一番右には Debug Device という表示が出ると思います。Debug Device をクリックしてみましょう。

すると、次のような画面が開きます。

そうしたら、上の Device Debugging というタブをクリックしましょう。次のような画面に変わります。

このテーブルタップは 4連のものなのですが(他の 1つは USB 電源)、上の表示はいま、スイッチ 1 とスイッチ 2 がオンになっている状態です。ここで switch_3 の右のスライドスイッチを右にスライドして、画面下の Send Instruction をクリックしてみましょう。無事に電源は入りましたでしょうか?

ようやく Python!

お待たせしました。ようやく、Python の話に入れます。

まず最初に、(TinyTuya の作者の方の指示に従い)Tuya のコンソール画面で Service API という画面を開きます。そのためには、画面左端の Cloud アイコンをクリックし、自分のプロジェクト(Cat Feeder など)をクリックし、画面上の方にあるタブから Servic API を選びます。次のような画面になります。

今回は、Tuya Cloud サービス登録直後なので、無事に IoT Core、Authorization、Smart Home Scene Linkage の 3つの API(ともう一つ、TinyTuya では使わなそうな Data Dashboard Service)が表示されています。もし、これが表示されていない場合は、青地に白の Go to Authorize ボタンをクリックして、上記 3つの API を subscribe します。

実は、この API のセットが Tuya の収益源の一つになっているようで、これを商用で実用的に使おうとするとお金が必要になってきます。いずれも、テスト利用ではほとんど無償のようですが、IoT Core だけは 1ヶ月毎に無償更新が必要のようで、ちょっと面倒です。(他は 1年更新?)

ただし、後述しますが(冒頭でも簡単に触れました)、Tuya Cloud を経由せずに LAN から機器を制御する場合には、これらの API は必要ないのではないか、と思っています。つまり、新しいプロジェクトを登録したりする際だけ、これらの API の subscribe(サブスクリプション)が必要なのではないか、と私は甘く考えています。

さて、Python です。皆様が Python の基本を御存知と仮定します。分からないことがある場合には、お気軽に末尾の問い合わせフォームからお問い合わせください。

まず、TinyTuya をインストールします。もちろん、tinytuya の GitHub サイトが本家ですので、そちらもよくお読みください。

bash$ python3 -m pip install tinytuya

次にウィザードを実行します。

bash$ python3 -m tinytuya wizard

すると、Enter API Key from tuya.com と表示されますので、上のほうで記録した Access ID/Client ID を入力してリターンキーを押します。続いて、Enter API Secret from tuya.com と表示されますので、今度は Access Secret/Client Secret を入力します。(繰り返しになりますが、これらは他人に見られないようにしてください。)

次が Device ID の入力です。Tuya Cloud 画面左端の Cloud アイコンをクリックし、自分のプロジェクト(Cat Feeder など)をクリックし、画面上の方にあるタブから Devices を選びます。そうすると、デバイス名の右に Device ID が表示されるので、それをコピーして Python の画面のほうで Enter any Device ID currently registered in Tuya App (used to pull full list) に続いて入力(コピペ)します。リターンキーを押します。

続いて Enter Your Region (Options: cn, us, us-e, eu, eu-w, or in) と表示されます。繰り返してますように、日本の国コードで登録すると Western America Data Center に登録されていますので、us と入力してリータンキーを押します。

さて、どうでしょう。少し待つと、次のような表示が出ててきます。

>> Configuration Data Saved to tinytuya.json
{
    "apiDeviceID": "xxxxxxxxxxxxxxxxxxxx",
    "apiKey": "xxxxxxxxxxxxxxxxxxxx",
    "apiSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "apiRegion": "us"
}


Device Listing

[
    {
        "name": "Cat Feeder",
        "id": "xxxxxxxxxxxxxxxxxxxx",
        "key": "xxxxxxxxxxxxxxxx"
    }
]

>> Saving list to devices.json
    1 registered devices saved

>> Saving raw TuyaPlatform response to tuya-raw.json

続いて Poll local devices? と聞いてきますので、y と入力してリターンキーを押します。すると、実際のデバイス(「リビングのテーブルタップその1」など)名に続き、次のような表示が出るでしょう。(これは、4連テーブルタップの例。)

Scanning local network for Tuya devices (retry 28 times)...
    1 local devices discovered

Polling local devices...
    [リビングのテーブルタップその1] - 192.168.0.100 - On - DPS: {'4': False, '13': 0, '1': True, '5': False, '2': False, '9': 0, '11': 0, '3': False, '10': 0, '12': 0}

>> Saving device snapshot data to snapshot.json

Done.

無事に Python から認識されました。192.168.0.100 というのは、IP アドレスの例です。なぜこれが必要かというと、TinyTuya では(Tuya フレームワークでは)、Tiny Cloud を経由せずに(つまり、外部のリソースを使うこと無く)LAN 経由でデバイスを制御することもできるからなのですね。

簡単なアプリを動かしてみよう

ローカルアクセス編

TinyTuya の GitHub を見ると、サンプルコードがいくつかあります。簡単そうなのを動かしてみましょう。ここでは、Tuya Cloud を使わず、ローカルに IP アドレス指定で動かす例を見てみます。

import tinytuya

d = tinytuya.OutletDevice('デバイスID', '192.168.0.100', 'ローカルキー')
d.set_version(3.3)
data = d.status() 
print('set_status() result %r' % data)

ここで、デバイス ID というのは、上の例(下に再掲)の id で出力された 16進数表記を文字列で、ローカルキーというのは、key で出力された、同じく 16進数表記の文字列です。(ここではいずれも、xxx… で伏せ字にしています。)

        "name": "Cat Feeder",
        "id": "xxxxxxxxxxxxxxxxxxxx",
        "key": "xxxxxxxxxxxxxxxx"

上の Python コードを実行すると、次のような表示が得られます。

set_status() result {'dps': {'1': True, '3': False, '11': 0, '4': False, '10': 0, '13': 0, '9': 0, '5': False, '12': 0, '2': True}, 'devId': '76231231e868e75e11c2'}

この意味(読み方)は、TinyTuya の GitHub README の下の方にあります。こちらを参考にしてください。

最後に、スイッチを一つオンにしてみましょう。Python で次のように書きます。上の方は、さきほどと同じです。

import tinytuya

d = tinytuya.OutletDevice('デバイスID', '192.168.0.100', 'ローカルキー')
d.set_version(3.3)

d.turn_on(switch=2)  # ここで、スイッチの 2番をオンにしている。

簡単ですね!

Tuya Cloud 経由編

可能であれば、上記で書いたローカルアクセスのほうが、セキュリティや費用の点で安心だと思うのですが、ファイアーウォールの外からデバイスを制御したい場合もあるかも知れません。その場合には、TinyTuya GitHub README の、こちらを参考にしてみてください。

余談

よく分かっていないのですが、Tuya デバイスに対するローカルアクセスは、スマートフォンの Smart Life 実行中はエラーになることが多いようです。Tuya Cloud 経由なら問題ないように見えます。

後記(2022/2/3): TinyTuya 作者の Jason Cox さんが、親切にもこの日本語の拙ブログを読んでくださり、この同時アクセスに対するエラーについてコメントをくださいました。ありがとうございます!!  以下にリンクを張らせて頂きます。

終わりに

これで無事に、スマートコンセント、スマートテーブルタップを、おうちサーバー、Raspberry Pi などから制御できるようになりました。もし、マイコンから制御したい場合は、一度 MQTT などでリクエストを飛ばして、Raspberry Pi などから API リクエストを送るのが簡単なのではないでしょうか?  あるいはもしかすると、TinyTuya のソースコードを読めば、マイコン(ESP32 など)から直接デバイスを制御する方法が分かるかも知れません。

追記(2023/7/23): 新しいデバイスを購入したら?

新しいデバイスを購入したら、まずはスマホの Tuya Smart Life アプリで、そのデバイスをペアリングします。続いて、tinytuya.json や devices.json のあるディレクトリで、python -m tinytuya wizard を再実行します。そうすることにより、local_key というものがファイルに追加され、そのデバイスを TinyTuya から利用できるようになります。

今日はここまで!

お問い合わせはお気軽に!

お問い合わせを頂いた後、継続して営業活動をしたり、ニュースレター等をお送りしたりすることはございません。
御返答は 24時間以内(営業時間中)とさせて頂いております。必ず返信致しますが、時々アドレス誤りと思われる返信エラーがございます。返答が届かない場合、大変お手数ではございますが別のメールアドレスで督促頂けますと幸いです。