目次

SwitchBot

since 2022-01-21

https://www.switch-bot.com/

https://qiita.com/itouuuuuuuuu/items/874cd992f473f30de45b

https://github.com/OpenWonderLabs/SwitchBotAPI

やりたいこと

やってみたこと

モバイルアプリで開発者モードを有効にして API トークンを取得。

環境変数 SB_API_TOKEN に API トークンを設定する。

下記で温湿度計とエアコン(赤外線制御)のデバイスIDを調べる

curl --request GET 'https://api.switch-bot.com/v1.0/devices' \
    --header "Authorization: ${SB_API_TOKEN}" \
    --header 'Content-Type: application/json; charset=utf8'

そして Python 3.9 で venv を作って pip install requests をして、下記を実行する

import requests
import os
import time
import json
import datetime
 
SB_API_TOKEN = os.environ["SB_API_TOKEN"]
METER_DEVICE_ID = "温湿度計のID"
AIRCON_DEVICE_ID = "エアコンのID"
 
SWITCH_BOT_API_URL = "https://api.switch-bot.com/v1.0"
 
SWITCH_BOT_API_HEADERS = {
    "Authorization": SB_API_TOKEN,
    "Content-Type": "application/json, charset=utf8",
}
 
 
def read_meter():
    res = requests.get(
        f"{SWITCH_BOT_API_URL}/devices/{METER_DEVICE_ID}/status",
        headers=SWITCH_BOT_API_HEADERS,
    )
    if res.status_code == 200:
        data = res.json()
        if data["statusCode"] == 100:
            humidity = data["body"]["humidity"]
            temperature = data["body"]["temperature"]
            return temperature, humidity
    raise Exception("Failed to read meter")
 
 
def turn_on_heater():
    payload = {
        "commadnType": "command",
        "command": "setAll",
        "parameter": "18,5,2,on",  # temperature, mode, fan speed, power state
    }
    res = requests.post(
        f"{SWITCH_BOT_API_URL}/devices/{AIRCON_DEVICE_ID}/commands",
        headers=SWITCH_BOT_API_HEADERS,
        data=json.dumps(payload),
    )
    if res.status_code == 200:
        data = res.json()
        if data["statusCode"] == 100:
            return
    raise Exception("Failed to turn on heater")
 
 
def turn_off_heater():
    payload = {
        "commadnType": "command",
        "command": "turnOff",
        "parameter": "default",
    }
    res = requests.post(
        f"{SWITCH_BOT_API_URL}/devices/{AIRCON_DEVICE_ID}/commands",
        headers=SWITCH_BOT_API_HEADERS,
        data=json.dumps(payload),
    )
    if res.status_code == 200:
        data = res.json()
        if data["statusCode"] == 100:
            return
    raise Exception("Failed to turn off heater")
 
 
def main():
    aircon_working = False
    while True:
        timestamp = datetime.datetime.utcnow().isoformat()
        temperature, humidity = read_meter()
        print(f"{timestamp},{temperature},{humidity},{int(aircon_working)}")
        if temperature < 16 and not aircon_working:
            print("Turning on heater")
            turn_on_heater()
            aircon_working = True
        elif temperature > 20 and aircon_working:
            print("Turning off heater")
            turn_off_heater()
            aircon_working = False
        time.sleep(30)
 
 
if __name__ == "__main__":
    main()

error 190

since 2022-02-19

エアコンを ON にする API 実行が失敗し、アプリに「内部エラー190」と表示されていた。

https://github.com/OpenWonderLabs/SwitchBotAPI

レスポンス JSON の statusCode Integer が 100 / 190 を返すという話

message を記録する必要がありそう。