no-image

SESAME3 に対応した Web API の使い方

いつの間にかしれっと Web API が SESAME3 に対応していたので、実際に使ってみる手順を記録します。

※しばらく随時修正しています

ドキュメント

SESAME3 の UUID 確認

公式アプリで操作したい鍵を設定画面を開いて確認します。

API キーの取得

ダッシュボードにログインします。
ログインの仕方はアプリ版と同じで、メールで認証番号が届いて、それを入力するだけです。

file

file

file

file

「API_KEY」を開くと確認できます。
「CLIENT_KEY」は今のところ使いません。

SESAME3 の状態取得

Firefox の拡張機能 RESTer で動作確認します。

file

成功すると200でJSONが返ってきます。
パラメータが間違っていたりすると502 Bad Gatewayになります。

  • batteryPercentage: 電池残量
  • batteryVoltage: 電池電圧
  • position: サムターン角度
  • CHSesame2Status: 状態
  • timestamp: 更新された時刻(1970-01-01 00:00:00:000からの経過ms)

SESAME3 の履歴取得

Firefox の拡張機能 RESTer で動作確認します。

file

成功すると200でJSONが返ってきます。
パラメータが間違っていたりすると502 Bad Gatewayになります。

SESAME3 の解錠・施錠操作

secret key の取得

公式アプリから鍵のシェアを行って表示されるQRコードを読み取ります。

iPhone の場合は「ショートカット」アプリで新規ショートカットを作成し、「書類」の「QR/バーコードをスキャン」と「Quick Lookで表示」を追加し、「QR/バーコード」を「テキストとして」にしておくとQRコードの中身をテキストのまま得られます。

URLは次のような形式になっていると思います。

ssm://UI?t=sk&sk=AXXXXXXXX省略)XXXXXXXXXXX&l=0&n=%%%%%%%%%%

この sk= の値をコピーしておいて、Base64 decode した文字列の1-17文字が secret key になります。
1-17文字といってもindexでの[1:17](JavaScriptだとslice(1, 17))なので、実際は2文字目から17文字目までですね。

Pythonが使える環境であれば、次のようにして対話モードでサクッと変換できます。

$ python
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> b64 = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # skの値(sk=の後から&前まで)
>>> import base64
>>> base64.b64decode(b64)[1:17].hex()
'abcdef0123456789hogehoge'

動作確認

CMACの生成が手間だったのでPythonで行っています。
pipでpycryptodome, requestsをインストールしておきます。

$ pip install pycryptodome, requests
import datetime, base64, requests, json
from Crypto.Hash import CMAC
from Crypto.Cipher import AES

uuid = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
secret_key = '0123456789abcdef0123456789abcdef'
api_key = 'XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx'

# 鍵の操作(toggle/lock/unlock)
cmd = 82    # 88/82/83 = toggle/lock/unlock

# 履歴に残す内容
history = 'Locked (Web API)' # 半角21文字/全角不明
history = base64.b64encode(history.encode()).decode()

# HTTP header
headers = { 'x-api-key': api_key }

# signの生成
cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES)
message = int(datetime.datetime.now().timestamp()).to_bytes(4, 'little', signed=False)[1:4]
cmac.update(message)
sign = cmac.hexdigest()

# 鍵の操作
url = f'https://app.candyhouse.co/api/sesame2/{uuid}/cmd'

body = {
    'cmd': cmd,
    'history': history,
    'sign': sign
}
res = requests.post(url, json.dumps(body), headers=headers)
print(res.status_code, res.text)

参考