Pythonで実現するSwitchBotスマートロックの施錠・開錠方法

SwitchBotスマートロックをPythonを使って操作する方法を書いていきます。
コマンド操作ってすごい。

## 実行環境
- OS:Ubuntu 22.04.4 LTS
- Python:3.10.12
## 準備するもの
- SwitchBotスマートロック(製品型番:W1601700)
- SwitchBot スマートリモコン ハブミニ (製品型番:‎W0202200)
## 前提
- SwitchBotのアプリ内に「SwitchBotスマートロック」「SwitchBot スマートリモコン ハブミニ」が接続されており、オンライン状態になっていることとします。
- アプリ操作にてスマートロックの動作が正しく行われていることとします。
## SwitchBotの各情報の取得
- APIトークン
- クライアントシークレット
- SwitchBotスマートロックのデバイスID
を取得します。

アプリを起動します。
「プロフィール」から「設定」を選択します。
「アプリバージョン」を10回タップすれば「開発者向けオプション」が出現するので、そこから「APIトークン」と「クライアントシークレット」が確認できるのでメモします。(なんか遊び心があって好きです。)
![トークン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803710/c961c2ba-2489-d07f-3a9d-648156ba8340.png)


取得した「APIトークン」と「クライアントシークレット」を使用して「SwitchBotスマートロックのデバイスID」を取得していきます。

- 必要なPythonのライブラリのインストール
```
pip install requests
```
- ファイルを作成し下記のコードを貼り付けます。
(取得したAPIトークンとクライアントシークレットに書き換えます。)
```
import requests
import time
import uuid
import hmac
import hashlib
import base64

# APIの基本設定
url = 'https://api.switch-bot.com'
token = '○○○○○○○'  # SwitchBotのAPIトークン
secret = '○○○○○○○'  # SwitchBotのクライアントシークレット

# SwitchBotに登録されているデバイスの一覧を取得する関数
def get_device_info():
    path = '/v1.1/devices'
    nonce = str(uuid.uuid4())  
    timestamp = str(int(time.time() * 1000))  
    
    string_to_sign = token + timestamp + nonce
    sign = base64.b64encode(
        hmac.new(secret.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
    )
    
    headers = {
        'Authorization': token,
        'sign': sign.decode('utf-8'),
        't': timestamp,
        'nonce': nonce
    }
    
    response = requests.get(url + path, headers=headers)
    
    print(f'Status Code: {response.status_code}')
    print(f'Response Text: {response.text}')
    
    if response.status_code == 200:
        response_json = response.json()
        print(f'Response JSON: {response_json}')
        return response_json
    else:
        print(f"Error: {response.status_code}, Message: {response.text}")
        return {}

if __name__ == "__main__":
    print("Getting Device List")
    devices = get_device_info()
    print(devices)
```

    
上記コマンドを実行すればSwitchBotに登録されているデバイスの一覧を取得することができます。
ここから「SwitchBotスマートロック」のデバイスIDをメモします。
これで必要な情報は取得できました。

## SwitchBotスマートロックの施錠・開錠
ファイルを作成し下記のコードを貼り付けます。
(取得したAPIトークン、クライアントシークレット、デバイスID、実行したいコマンドを書き換えます。)
```
import requests
import time
import uuid
import hmac
import hashlib
import base64

# APIの基本設定
url = 'https://api.switch-bot.com'
token = '○○○○○○○'  # SwitchBotのトークン
secret = '○○○○○○○'  # SwitchBotのクライアントシークレット

def control_device(deviceId, command):
    path = f'/v1.1/devices/{deviceId}/commands'
    nonce = str(uuid.uuid4())
    timestamp = str(int(time.time() * 1000))

    string_to_sign = token + timestamp + nonce
    sign = base64.b64encode(
        hmac.new(secret.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
    )

    headers = {
        'Authorization': token,
        'sign': sign.decode('utf-8'),
        't': timestamp,
        'nonce': nonce
    }
    
    body = {
        "command": command,
        "parameter": "default",
        "commandType": "command"
    }

    print(f"Headers: {headers}")
    print(f"Body: {body}")

    response = requests.post(url + path, headers=headers, json=body)
    print(f'Status Code: {response.status_code}')
    print(f'Response Text: {response.text}')
    
    if response.status_code == 200:
        response_json = response.json()
        print(f'Response JSON: {response_json}')
        return response_json
    else:
        print(f"Error: {response.status_code}, Message: {response.text}")
        return {}

if __name__ == "__main__":
    deviceId = '○○○○○○○'  # 取得したスマートロックのデバイスID
    command = '○○○○○○'  # unlockまたはlockを入力

    print(f"Sending command '{command}' to device '{deviceId}'")
    response = control_device(deviceId, command)
    print(response)
```
コマンドの実行を行えば施錠・開錠が可能になるかと思います。

## 最後に
最近(?)スマートホームとよく聞くようになった気がします。
私もチャットシステムを使用して扉の施錠・開錠を行う機会がありましたが、恥ずかしいことに当時は「SwitchBotって何⁈」という状態でした。
というわけで「実際に購入して試してみよ～」で、自宅に設置した感想としては「すでにアプリ操作で便利すぎる！」でした。
しかし興味を持った点として、チャットシステムでスマートロックを操作できることを知らなかった私が、もしもSwitchBotを自宅にすでに設置していたら・・・と考えると、おそらくアプリでしか操作できないものだと思い込んでいたと思います。
便利なものが多いですが、見えないところで多くの苦労や試行錯誤がされていると感じました。
ちなみにエアコンもスマホから操作できて快適です♪感謝です。
与えられたものを使うだけでなく、仕組みを理解できる人間になりたいですね～。
いつになることやら・・・
今回行ったことから応用(?)もできたらいいと思っています！