SwitchBotAPIを使ってPythonコードにて空調を操作してみた

SwitchBotをAPI経由にてPythonを使って操作してみました。iFTTT等で使いたいオートメーションがない時には必須かもしれません。
2022.07.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

SwitchBotは環境に合わせたオートメーションがとても便利です。ただ、状況確認や手動での動作設定のインターフェイスがSwitchBotアプリ上のみに縛られる点はやや難点です。

その点の対処は取りようがないのかと思いきや、じつはAPIがあります。そしてドキュメントも整備されています。

中々気が付かないこのAPIの使い方について書いてみました。

APIのトークンを取得

このAPIの利用にはトークンの発行が必須です。ですが、APIはもちろんトークンについてもSwitchBotの公式サイトや取り扱い説明書には導線が全くありません。ではどうやって取得するのか。

GitHubのREADMEからGetting Startedに答えがあります。SwitchBotアプリをインストールしてアカウント登録を済ませることが前提となりますが、アプリ内で以下の操作を取ると隠しメニューが出現します。

アプリ内でオープントークンを作成します。a)プロフィールのプレファレンスを開き、b)アプリバージョン部分を10回タップします。デベロッパーオプションが開示されはずです。c)デベロッパーオプションを開きます。d)Get Tokenをタップします。

Generate an Open Token within the app a) Go to Profile > Preference b) Tap App Version 10 times. Developer Options will show up c) Tap Developer Options d) Tap Get Token

Before After

普通はまず気が付かないメニューですね。Open TokenについてはREADMEに同じく説明があるので目を通しておきましょう。

空調操作を送信する

実際にSwitchBotAPIを使って空調を操作してみます。APIに空調操作用UIを作成するインターフェイスはなさそうなので、事前にSwitchBotアプリ上で作成しておきます。基本的な流れは以下の通り。

  1. デバイス一覧を取得
  2. 空調操作用UIのVirtualDeviceステータスを取得
  3. ステータス内のdeviceIDを用いて空調操作を送信する

空調操作用UIのVirtualDeviceステータスは固定のため、取得した後保存しておくとAPIの利用回数を節約できます。

オープントークンの文字列はとにかく長いので、スマートフォン上でコピーした後はメモ系クラウドサービスを通してPC上に持ってくることをおすすめします。

vim switchbot.py
import requests
import json

OPEN_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
API_HOST = 'https://api.switch-bot.com'


DEBIVELIST_URL = f"{API_HOST}/v1.0/devices"

HEADERS = {
    'Authorization': OPEN_TOKEN,
    'Content-Type': 'application/json; charset=utf8'
}


def _get_request(url):
    res = requests.get(url, headers=HEADERS)
    data = res.json()
    if data['message'] == 'success':
        return res.json()
    return {}


def _post_request(url, params):
    res = requests.post(url, data=json.dumps(params), headers=HEADERS) 
    data = res.json()
    if data['message'] == 'success':
        return res.json()
    return {}


def get_device_list():
    try:
        return _get_request(DEBIVELIST_URL)["body"]
    except:
        return


def get_virtual_device_list():
    devices = get_device_list()
    return devices['infraredRemoteList']


def send_air_condition(deviceId, temperature, mode, fanspeed, power_state):
    url = f"{API_HOST}/v1.0/devices/{deviceId}/commands"
    params = {
        "command": "setAll",
        "parameter": f"{temperature},{mode},{fanspeed},{power_state}",
        "commandType": "command"
    }
    res = _post_request(url, params)
    if res['message'] == 'success':
        return res
    return {}


data = get_virtual_device_list()
for device in data:
    if device['remoteType'] == 'Air Conditioner':
        status = send_air_condition(device['deviceId'], 26, 3, 1, 'on')
        print(status)
        break

iFTTTの環境に応じた操作の都合でAir Conditionerが大量にある場合、同じ機器であればdeviceIDはどれを使っても挙動は同じです。

python switchbot.py
{'statusCode': 100, 'body': {}, 'message': 'success'}

あとがき

今回は環境による条件指定をしないリモコン操作をしてみましたが、正直アプリで操作したほうが手間はかかりません。このAPIを使うメリットとしては、iFTTT等のSwitchBotで標準対応していないSaaSにてSwitchBotに対してリクエストを送れる点です。

Raspberry Pi等が使える環境であればアイデア次第で活用方法があるため、思いつくものがあれば試してみるとよいかもしれません。