pythonでsmartlife電源を操作 (脱IFTTT)

#IFTTTついに有料化

2020/11/1より有料化された模様です。いままで、webhookで利用してきましたが、動いてくれません。仕方がないので、代替案の開拓です。
調べると、pythonで制御できるらしいので、トライしてみました。

ばりばり使っていたわけではなく、電源のON/OFFだけできればよかったので、わざわざ有料化サービスを受けるのもなぁ、というのが動機です。


#おおまかな流れ

基本、tinytuyaが使えれば、pythonからの制御は可能。ただし、tinytuyaで制御するためには、Device ID (=virtual ID), IP Addr, local keyが必要。そのため、tuyapower (Python3) および tuya-cli (node) が必要。前段が多くて、面倒。

- tuyapowerで、IP Addr, virtual idを入手
- tuyacliで、local keyを入手 (iot.tuya.comへの登録が必要)
- tinytuyaで、対象スイッチを制御

ほとんどが、tinytuyaのgithubなどに書かれているままです。単なる日本語化ともいう。

#ツールのインストール
## tinytuya / tuyapower / tuya-cli

```
# Install required libraries
$ sudo apt-get install python-crypto python-pip		# for RPi, Linux
$ python3 -m pip install pycryptodome    # or pycrypto, pyaes or Crypto
$ python3 -m pip install tinytuya        # or pytuya
$ python3 -m pip install tuyapower       # this tuyapower module
$ npm i @tuyapi/cli -g
```

tuya-cliだけ、npmです。

#必要なパラメータを入手する
## Device ID, IP address

```
$ python3 -m tuyapower
TuyaPower (Tuya compatible smart plug scanner) [0.0.25] tinytuya [1.0.3]

Scanning on UDP ports 6666 and 6667 for devices (15 retries)...

FOUND Device [Valid payload]: 192.168.x.xx
    ID = 02xx11xxbcxxc2xxffxx, product = xxSUxxTWxx8ExxTw, Version = 3.1
    Stats: on=False [Timeout polling device]
FOUND Device [Valid payload]: 192.168.x.xx
    ID = 02xx77xxbcxxc2xx99xx, product = xxSUxxTWxx8ExxTw, Version = 3.1
    Stats: on=False [Timeout polling device]
FOUND Device [Valid payload]: 192.168.x.xx
    ID = 03xx01xxdcxx22xxccxx, product = xx0VxxFcxxBTxxWt, Version = 3.1
    Stats: on=True, W=0.1, mA=0.0, V=0.0 [OK]
                    
Scan Complete!  Found 3 devices.

```

うちには、3台のsmartlife機器があるので、3つ表示されます。
大事なのは、IDとIP Address。このIDをtuya-cliのvirtual IDで入力します。

##local key
### Tuya API key / Tuya secret

iot.tuya.comから、cloud Developmentに移動し、Tuya APIとTuya secretを入手します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/0871dde9-8f70-05f3-9492-02d07ad84327.png)

Access ID =  Tuya API key
Access Secret = Tuya secret

## local key

tuya-cli wizard を実行して、入手。jsonフォーマットのkey項が対象。

```
$ tuya-cli wizard
? The API key from tuya.com: nnxxxxxxxxxxxxxxxxur
? The API secret from tuya.com 53xxxxxxxxxxxxxxxxxxxxxxxxxxxxa3
? Provide a 'virtual ID' of a device currently registered in the app: 03xxxxxxxxxxxxxxxx08
[
  {
    name: 'ノートA',
    id: 'XXXXXXXXXXXXXXXXXXXX',
    key: 'YYYYYYYYYYYYYYYY'
  },
  {
    name: 'ノートB',
    id: 'XXXXXXXXXXXXXXXXXXXX',
    key: 'YYYYYYYYYYYYYYYY'
  },
  {
    name: 'ノートC',
    id: 'XXXXXXXXXXXXXXXXXXXX',
    key: 'YYYYYYYYYYYYYYYY'
  }
]
```

#サンプルコード

まんま、パクリです。上記で苦労して入手した情報を利用します。

DEVICE_ID_HERE: Device ID, Virtual ID (tuyapower/tuya-cliで入手)
IP_ADDRESS_HERE: IP address (tuyapowerで入手)
LOCAL_KEY_HERE: key (tuya-cliで入手)

```
import tinytuya

d = tinytuya.OutletDevice('DEVICE_ID_HERE', 'IP_ADDRESS_HERE', 'LOCAL_KEY_HERE')
d.set_version(3.3)
data = d.status()  # NOTE this does NOT require a valid key vor version 3.1

# Show status of first controlled switch on device
print('Dictionary %r' % data)
print('State (bool, true is ON) %r' % data['dps']['1'])  

# Toggle switch state
switch_state = data['dps']['1']
data = d.set_status(not switch_state)

data = d.status()
print('State (bool, true is ON) %r' % data['dps']['1'])  

```

状態を入手する(data = d.status())だけなら、local keyは不要。d.set_statusを呼び出すとき、正しいlocal keyが設定されていないと、エラーが返ってきます。正しく設定できると、次のように動きます。set_status(not switch_status)通過後、通電状態がFalseからTrueへ変化しています。

```
$ python3 sample.py 
Dictionary {'devId': '02XXXXXXXXXXXXXXXXeb', 'dps': {'1': False, '2': 0}}
State (bool, true is ON) False
State (bool, true is ON) True
```

なお、meross系は、また別の方法で制御します。もっと簡単にpythonから制御できます。

おしまい