LoginSignup
7
8

More than 1 year has passed since last update.

Switchbot API V1.1のアクセスに必要なヘッダーを作る方法を調べました

Last updated at Posted at 2022-10-09

事の始まり

Switchbotのデータを読み込んだり、操作するために必要なことを調べていたら、Switchbot APIを利用するのが良さそうだと言うことで、【SwitchBot】基本的な API の使い方と言う記事に辿り着きました。とりあえず試してみようと思ったのですが、なぜかエラーが発生。コピペだけで済ましているので、エラーの本質的な理由が分かりませんでした。

何が悪かったのか、結論

簡単に書くと、参考記事の時とAPIのバージョンが変わっていました。バージョンが変わっていようと、今でも古いv1.0は残っているので、とりあえず動作しないかと色々原因を追求したところ、v1.0のAPIでは新しいデバイス(当方の環境ではSwitchbotキーパッドタッチが該当)の情報を返すことができないと言うのが理由でした。新しめのデバイスを利用するには否が応でもv1.1に対応する必要がありました。

動作確認環境

  • Linux(Raspberry Pi) or macos
  • Python3(ちょっと修正すればPython2でも動くはずです)

Switchbot API V1.1について

Swithbot APIの最初の方の記述を見ると、結構最近にAPIの仕様が変わったようです。以前のバージョンではtoken(APIキー)だけで利用でしたのですが、V1.1では

  • token
  • secret(Switchbot App V6.14以降で取得可)
  • t(13桁のタイムスタンプ)
  • sign(特定のアルゴリズムで作成した文字列)
  • nonce (利用するプログラムで生成したUUIDキー)

これらが必須の情報だそうです。

上記APIのページにはPython(2or3)とjavascriptでの作成サンプルがありましたので、これをまんま利用しました。

#!/usr/bin/env python3
# coding: utf-8

''' Create Switchbot sign header '''

import time
import hashlib
import hmac
import base64
import json
import uuid

def gensign(token, secret):
    '''
    Generate Switchbot API v1.1 sign header
    Args:
        token: string  :copy and paste from the SwitchBot app V6.14 or later
        secret: string :copy and paste from the SwitchBot app V6.14 or later
    Returns:
         Switchbot API v1.1 sign header
    '''

    nonce = str(uuid.uuid4())
    t = int(round(time.time() * 1000))
    string_to_sign = '{}{}{}'.format(token, t, nonce)
    
    string_to_sign = bytes(string_to_sign, 'utf-8')
    secret = bytes(secret, 'utf-8')
    
    sign = base64.b64encode(hmac.new(secret, msg=string_to_sign, digestmod=hashlib.sha256).digest())
    
    header={}
    header["Authorization"] = token
    header["sign"] = str(sign, 'utf-8')
    header["t"] = str(t)
    header["nonce"] = nonce

    return header

(https://gist.github.com/iCarrot0605/472dd85f887985a67b9f956070cf9864)

コードの難しいことは分かりませんが、「token、t、nonce」を繋ぎ合わせた文字列をsecretを使って署名?することでsignは出来上がります。
 nonceはuuid.uuid4()を使ってみました。元々のサンプルにあるように何も指定しなくても動作します。

tokenとsecretはSwitchbot App(V6.14以降)で、「プロフィール」>「設定」へと進み、「アプリバージョン」のフィールドを10回タップすると表示される「開発者向けオプション」から取得することができます。

APIを利用してみる

サンプルコードは【SwitchBot】基本的な API の使い方にあるコードを少し修正しました。上に書いたコード(switchbot_sign.py)と同じディレクトリに以下のコードを置きます。

#!/usr/bin/env python3
# coding: utf-8

import requests
import json
import switchbot_sign

token = '' # copy and paste from the SwitchBot app V6.14 or later
secret = '' # copy and paste from the SwitchBot app V6.14 or later

header = switchbot_sign.gensign(token, secret)
# Get all device information in your switchbot hub
response = requests.get("https://api.switch-bot.com/v1.1/devices", headers=header)
devices  = json.loads(response.text)

# Get switchbot bot "deviceId" in all device information
bots_id  = [device["deviceId"] for device in devices['body']['deviceList'] if "Bot" == device["deviceType"]]


# Get all switchbot bot power state and output on your display
for bot_id in bots_id:
    response = requests.get("https://api.switch-bot.com/v1.1/devices/" + bot_id + "/status", headers=header)
    bot      = json.loads(response.text)
    power    = bot['body']['power']
    
    print("bot id (" + bot_id + ") power : " + power)

あとは

python3 (保存したスクリプト名)

実行結果

bot id (XXXXXXXX) power : off

となるはずです。

APIの利用について

1日に利用できる回数が10000回です。上記のサンプルスクリプトでは2回APIを利用しています。よっぽどのことがないと使い切ることはないと思いますが。

まとめ

まとめというよりは初めてのQiitaでの記事作成にMarkdown記法の勉強から始まりました。ちゃんとした体裁になっているかも良く分かりませんが、誰かの参考になれば幸いです。

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8