これまでこちらの記事のとおり、旧Tuya APIを使ってスマートプラグを自動ON/OFFさせていました。
家のインターネット回線変更に伴い、スマートプラグの再設定が必要になり、久しぶりにTuyaのサイトを訪れたら、超わかりづらくなっていて、かなりハマってしまいました。
もう少しユーザにやさしい作りにしてほしいものです・・・
Tuyaのサポートに問い合わせてやっとやり方がわかったので共有します。
Tuyaのサポートはレスポンスが早く、適切に解決に導いてもらえました。
英語でのやり取りになりますが、何か困ったらサポートに聞くのが良いと思います。
ポイントは以下:
- Tuya Smartアプリでスマホとスマートプラグを接続(Smart Lifeアプリではない)
- Tuya IoT PlatformのサイトでCloud Projectを作り、上記Tuya Smartアプリと連携
- TypeScriptの@tuya/tuya-connector-nodejsを使用(require(‘tuyapi’)ではない)
すべて無料で実施できます。
Tuyaのサイトの使い方がわからなくて困っている方の助けになると思います。
本記事ではTuya APIの他にApple Scriptによるスマートプラグの自動ON/OFFについても説明していますが、Tuya APIのことだけ知りたい方はApple Scriptの章は読み飛ばしてください。
本記事の内容は以下の動画にも収めていますので、よろしければご覧ください。
では、以降で順を追って手順を説明していきます。
実行環境
以下の環境で動作確認を行いました。
構成要素 | バージョン |
---|---|
macOS | Catalina 10.15.7 |
Node.js | v12.18.0 |
npm | 8.2.0 |
スマートプラグ | 中国製Smart Life対応 型番: XS-A16 |
スマホとスマートプラグをペアリング
スマホにTuya Smartアプリをインストールします。
私はこれまで青いアイコンのSmart Lifeアプリを使っていたのですが、QRコードのスキャンのところでうまくいきませんでした。
サポートの回答はどちらかのアプリを使用とのことでしたが、私の場合、赤いアイコンのTuya Smartアプリの方だけうまくいきました。
Tuya Smartアプリを立ち上げ、+をタップし、Add Deviceを選択します。
Socket (Wi-Fi)をタップします。
接続するWi-Fiの情報を入れ、Nextをタップします。
2.4GHzのWi-Fiを選択します。
ここで、スマートプラグの電源を入れます。
電源ボタンを長押ししてペアリングモードにします。
スマートプラグのペアリングモードは2種類あり、速い点滅と遅い点滅で区別されます。
遅い点滅になっている場合は、再度長押しして速い点滅状態にします。
下の画面になるまでNextを押し、Confirm〜にチェックを入れます。
私の場合、先に実施される速い点滅ではペアリングがうまくいかず、下の画面になるので、Switch Pairing Modeを押して遅い点滅モードに移行します。
スマートプラグの電源ボタンを長押しして、遅い点滅モードにしてペアリングを行います。
スマートプラグがWi-Fi親機になり接続するよう促されますので、Reconnectを押してWi-Fi-設定画面に移行します。
SmartLife-〜またはSL-〜のWi-Fiに接続します。
このあと、Tuya Smartの画面に戻るとペアリングが進み、正常にペアリングできると以下のようにアプリのホーム画面にデバイスが現れます。
スマートプラグのデバイスをタップして以下の画面に遷移し、スマートプラグがON/OFFできることを確認します。
これでスマホとスマートプラグのペアリングは完了です。
Cloud Projectの作成
TuyaのサイトからCloud Projectを作成します。
Create Cloud Projectを押します。
プロジェクトの情報を入力してCreateを押します。
Data Centerとして、私はWestern America Data Centerを選択しました。
以降のTypeScriptでこのData CenterとしてUSを選択することになるので覚えておきます。
下図の画面では特に何もせず、Authorizeを押します。
作成したCloud Projectをクリックします。
以下のようにOverviewが表示されます。
上記の①Access ID/Client ID、②Access Secret/Client Secretの値は、以降のTypeScriptを編集する際に必要になります。
②の方は、目のマークをクリックすることで内容を表示でき、コピーのマークを押すことでクリップボードにコピーできます。
Devicesタブ→Link Tuya App Accountタブを選択し、Add App Accountをクリックします。
QRコードが表示されるので、スマホのTuya Smartアプリ画面右上+マーク→Add Device→画面右上のスキャンマークをクリックしてQRコードを読み取ります。
これでCloud ProjectとスマホのTuya Smartアプリが連携したことになります。
一旦Overviewをクリックして再度Devices→All Devicesタブを選択すると下図のようにTuya Smartアプリでペアリングしたスマートプラグのデバイス情報が表示されるはずです。
上記③Device IDは以降のTypeScriptを作成する際に使います。
Debug Device押すと以下の画面になり、switchを切り替えてSend Instructionを押してスマートプラグにON/OFFの命令を送ります。
スマートプラグをON/OFFできれば成功です。
TypeScript作成
Develop with Node.js SDKにライブラリのインストール方法とTypeScriptのサンプル記述があり、参考にしました。
上記サイトはJavaScript IDE(開発ツール)を使用した方法を説明していますが、本記事の内容はIDEを使わず編集はテキストエディタで行えます。
TypeScriptとはJavaScriptを拡張して作られたオブジェクト指向の言語です。
TypeScriptをコンパイルしてJavaScriptを生成し、Node.jsで使用します。
Node.jsをインストールしていない場合はこちらからインストールしてください。
スクリプトのダウンロード
ここで使用するサンプルスクリプトはGitHubに置いているのでgit cloneします。
git clone https://github.com/tak6uch1/TuyAPI_SmartPlug.git
必要なライブラリをインストールします。
./install.sh
TypeScript編集
plug_on.ts
, plug_off.ts
, get_command.ts
のXXXXの部分に①Access ID/Client ID、YYYYの部分に②Access Secret/Client Secret、ZZZZの部分に③Device IDを記入します。(「Cloud Projectの作成」の章を参照)
以下はplug_on.tsの例(plug_off.tsとbody/commandsのvalueがtrueかfalseの違いのみ):
import { TuyaContext } from '@tuya/tuya-connector-nodejs'; /** * api env entrypoint * * 'https://openapi.tuyacn.com', // 亚洲 AY * 'https://openapi.tuyaus.com', // 美区 US * 'https://openapi.tuyaeu.com', // 欧洲 EU * 'https://openapi.tuyain.com', // 印度 IN */ const context = new TuyaContext({ baseUrl: 'https://openapi.tuyaus.com', accessKey: 'XXXXXXXXXXXXXXXXXXXX', secretKey: 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY', }); const main = async () => { // Define the device ID const device_id = "ZZZZZZZZZZZZZZZZZZZZ"; const commands = await context.request({ path: `/v1.0/iot-03/devices/${device_id}/commands`, method: 'POST', body: { "commands":[{"code":"switch","value":true}] } }); if(!commands.success) { new Error(); } console.log("Execution result:",commands); }; main().catch(err => { console.log(err); });
もし、Data CenterをUS以外にしていた場合はbaseUrl: 'https://openapi.tuyaus.com'
の部分をコメントにあるURLに従って書き換えます。
TypeScriptのコンパイル
TypeScriptをコンパイルします。
~/node_modules/.bin/tsc get_command.ts ~/node_modules/.bin/tsc plug_on.ts ~/node_modules/.bin/tsc plug_off.ts
実行可能コマンドの調査
それぞれのデバイス(私の場合スマートプラグ)で利用可能なコマンドを調べるために以下を実行します。
node get_command.js
以下のようにコマンドが出力されます。
Execution result: { "result": { "category": "cz", "functions": [ { "code": "switch", "desc": "switch", "name": "switch", "type": "Boolean", "values": "{}" }, { "code": "countdown_1", "desc": "countdown 1", "name": "countdown 1", "type": "Integer", "values": "{\"unit\":\"s\",\"min\":0,\"max\":86400,\"scale\":0,\"step\":1}" } ] }, "success": true, "t": xxxxxxxxxxxxx }
JSON形式のデータが出力され、functions内にある2つのブロックが利用可能なコマンドを表しています。
上記例の場合、Booleanを値として格納するswitchと、Integerを格納するcountdown_1になります。
ここでswitchがスマートプラグのON/OFFするためのコマンドなのでこれを利用して、下記plug_on.ts
(抜粋)内でswitchにtrueを格納してPOSTしています。
const commands = await context.request({ path: `/v1.0/iot-03/devices/${device_id}/commands`, method: 'POST', body: { "commands":[{"code":"switch","value":true}] } });
Node.js実行
plug_on.ts
をコンパイルしてできたplug_on.js
を実行してみます。
node plug_on.js
これでスマートプラグがONすれば成功です。
同様に以下のコマンドでOFFすることを確認します。
node plug_off.js
これでNode.jsのコマンドでスマートプラグをON/OFFできることが確認できました。
Apple Script作成
この章はMacでのみ実行可能です。
1分おきに充電状態をチェックし、50〜55%の充電度合いになるように自動的にスマートプラグをON/OFFする機能を実現します。
画面右上(メニューバー上)の虫眼鏡マーク(Sporlight Search)からScript Editor.appを検索してダブルクリックで起動します。
以下のコードをScript Editorに貼り付けます。
use AppleScript version "2.4" -- Yosemite (10.10) or later use framework "Foundation" use framework "AppKit" use scripting additions global MIN, MAX, AWAKE set MIN to 50 set MAX to 55 set AWAKE to true set aCenter to current application's NSWorkspace's sharedWorkspace()'s notificationCenter() aCenter's addObserver:me selector:"notifSleep:" |name|:"NSWorkspaceWillSleepNotification" object:(missing value) aCenter's addObserver:me selector:"notifWaked:" |name|:"NSWorkspaceDidWakeNotification" object:(missing value) on exeAPI(message) -- say "The AWAKE value is " & AWAKE if AWAKE then try -- say "Start API" do shell script "/usr/local/bin/node /Users/user/work/TuyAPI_SmartPlug/plug_" & message & ".js > /Users/user/plug.log 2>&1" -- say "Normal end" on error -- say "Error occurred" -- display dialog "Error occurred" return 1 end try end if return 0 end exeAPI on idle do shell script "/Users/user/bin/battery_info.sh >> /Users/user/battery/battery_log.csv" set per to (do shell script "pmset -g batt | grep % | sed 's/[%;]/ /' | awk '{print $3}'") as number set ret to 1 set cnt to 0 repeat while cnt < 3 and ret ≠ 0 -- say "The count is " & cnt if per ≤ MIN then set ret to my exeAPI("on") else if MAX ≤ per then set ret to my exeAPI("off") end if set cnt to cnt + 1 end repeat return 60 end idle on quit exeAPI("off") continue quit end quit on notifSleep:aNotif exeAPI("off") -- display notification "System will sleep" -- say "System will sleep" set AWAKE to false end notifSleep: on notifWaked:aNotif -- display notification "System did wake" -- say "System did wake" set AWAKE to true end notifWaked:
GitHubリポジトリにはPowerManagerTuyAPI.txt
というテキストファイルとして格納してあります。
スクリプトの解説
MIN, MAXの値を変えればお好みの充電範囲にできます。
/usr/local/bin, /Users/userなどのパスはお使いの環境に合わせて変更してください。
on idle, return 60 として60秒毎にバッテリーの充電度合いを確認し、MIN以下なら充電開始、MAX以上なら充電停止しています。
nodeコマンドは3回トライしています。
当初は、on idle部のみで充電を制御しようとしていました。
しかし、電源ON状態でシャットダウンするとそのまま充電され続けてしまうため、on quitでシャットダウン時のApplication停止を検知して充電を停止するようにしました。
その後、電源ON時にスリープモードに入った場合も充電され続けてしまうことに気づきました。
notificationCenterの記述とon notifSleep:aNotifを追加し、スリープモードに入る通知を取得して充電を止めるようにしました。
ところが、スリープモードでもスクリプトは動作しているようでMIN以下になるとon idleの機能が働いて電源がONになります。
そのまま少し経つとディープスリープモードに移行してスクリプトが停止して充電し続けます。
これを避けるために、スリープと復帰の両方の通知を検知して、現在スリープモード中かどうかを確認し、スリープモード中は電源ON/OFFを変更しないようにしました。
これで、スリープ状態に入るときに電源をOFFにし、スリープから復帰するまで電源OFFをキープするようにしました。
スクリプトの保存
Script Editor上部のツルハシの絵が付いているボタンを押すとキーワードに色が付き、見やすくなります。
File→Saveから保存します。
File FormatをApplicationにし、オプション:ハンドラの実行後に終了しない(Stay open after run handler)にチェックを入れます。
以下はPowerManagerAPI.appという名前で保存する例です。
続いて、このApple Script ApplicationをMac起動時に立ち上がるように設定します。
Appleマークからシステム環境設定(System Preferences)
→ユーザーとグループ(Users & Groups)
→ログイン項目(Login Items)
から+マークを押すと選択画面が出るので、作成したPowerManagerAPI.appを選択します。
Macを再起動して、充電度合い50〜55%をキープするように自動的にスマートプラグがON/OFFされ、
シャットダウン時やスリープモード移行時にスマートプラグがOFFになれば成功です。
追加情報
本Apple ScriptをDockに表示させたくない場合は、以下を実行すると良いです。
(以下はPowerManagerAPI.appの保存場所がDocuments/scriptsの場合の例)
$ cd Documents/scripts $ plutil -insert 'LSUIElement' -bool true PowerManagerAPI.app/Contents/Info.plist
インターネットにつながらない場所では、1分おきにコマンドに失敗したというポップアップが出てしまいますが、Editを押してScript Editorを立ち上げておくと出なくなります。
このページのblife.shは、バッテリーに関する情報をまとめて表示してくれるので便利です。
$ blife.sh [2019-06-15 00:08:05] Your MacBook's Battery status is Charge Remaining 2127(mAh) State of Charge 50% Cycle Count 21 Cycle Count Remaining 979 Full Charge Capacity 4175(mAh) State of Health 96.8%
まとめ
新しくなったTuya API(Node.js)を利用してTypeScriptからスマートプラグをON/OFFすることができました。
ポイントは以下:
- Tuya Smartアプリでスマホとスマートプラグを接続(Smart Lifeアプリではない)
- Tuya IoT PlatformのサイトでCloud Projectを作り、上記Tuya Smartアプリと連携
- TypeScriptの@tuya/tuya-connector-nodejsを使用(require(‘tuyapi’)ではない)
また、Apple Scriptで定期的にバッテリの充電度合いをチェックして自動的にスマートプラグをON/OFFすることで充電度合いを狙った範囲内に収めることで、バッテリを長持ちさせる機能の実現もできました。
Tuya APIの使い方がわからず困っている方のお役に立てれば幸いです。
私が使用したものと同じではありませんが、Smart Life対応ですので同様にお使いいただけます。
TypeScriptの書籍紹介です。
安心のオライリー、初心者から上級者まで満足のいく充実した内容で、これがあれば不足はないと思います。
プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発
参考文献
- Develop with Node.js SDK(https://developer.tuya.com/en/docs/iot/device-control-best-practice-nodejs?id=Kaunfr776vomb)
- Get the instruction set of the device(https://developer.tuya.com/en/docs/cloud/3ac29198c9?id=Kag2ybepz3arq#title-0-API%20address)