6
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SESAME3をWEB API経由で操作する

Posted at

いろいろあって会社オフィスの1FにSESAME3を導入しました。

SESAME3+スマホの組み合わせでも十分便利だけど、やっぱりWEB API使いたい!
というわけで始めました。
(1Fだけはスマホで開けてね、って言っても社内から反発ありそうだし…)

さほど難解なところもないので、公式ページを見ながら進めれば大丈夫です。
(載せたコードもほぼ公式そのままです)

導入環境

WEB APIに必要な情報(SESAME3)

  • API Key(APIキー)
  • Secret Key(秘密鍵)
  • UUID

API Key

まずCandyHOUSEダッシュボードにアクセスして、API Keyを入手しましょう。
以下画面にメールアドレスを入力すると、4桁の認証コードがメールで届きます。
1.jpg
届いた認証コードを入力してログインします。
2.jpg
ログイン後に表示される「API Key」の中の文字列をコピーしておきましょう。
(Client IDはいまのところ使い道がわからないです…)
3.jpg

Secret Key

秘密鍵の確認はちょっと面倒です。(もっと良い方法あれば教えてほしい)
SESAMEの専用アプリ「セサミ、ひらけごま!」を利用します。

「セサミ」などでストア検索するとアプリが2つ出てきますが、SESAME3では「セサミ、ひらけごま!」を使います。
もうひとつの「SESAME セサミ」は旧バージョンのSESAMEで利用するようです。
※リンクはiPhoneアプリです。Android版はこちら

アプリを起動して、SESAME3を登録したあとにメニュー画面から鍵のシェアをおこなうとQRコードが表示されます。
5.jpg
スマホ間で鍵を共有するときに利用するQRコードですが、これをスマホのQRコードリーダなどで読み取ると
ssm://UI?t=sk&sk=xxxxxxxxxxxxxxxxxxxxx&l=0&n=xxxxxxxxxxx
のような文字列が取得できるので、ここからskの部分を抜き取ります。(秘密鍵)
パースをかけたりして抜き出すかたもいるようですが、自分は目視で抜き取りました。

分解するとこんな感じ

t=sk
sk=xxxxxxxxxxxxxxxxxxxxx
l=0
n=xxxxxxxxxxx

のちほどこのskをCMACで暗号化して利用しますので、文字列をコピーしておきましょう。
(これをそのままGithubに乗せてるっぽいの見かけるけど大丈夫なんかな…?)

UUID

UUIDもSecret Keyと同じく専用アプリのメニュー内から確認できます。
メニューの一番下に表示されます。
4.jpg
こちらもUUID部分の文字列をコピーしておきましょう。

WEB API動作

URL : https://app.candyhouse.co/api/sesame2/

SESAME3のステータスを取得する

先程ダッシュボードで取得したAPI Keyをヘッダー(x-api-key)に入れて、GETすると現在のステータスが確認できます。
URL末尾のUUIDには、アプリで取得した自分のSESAME3のUUIDを入れます。

% curl -H "x-api-key":"[myapikey]" https://app.candyhouse.co/api/sesame2/[UUID]
{"batteryPercentage":100,"batteryVoltage":6.0316715542522,"position":-121,"CHSesame2Status":"locked","timestamp":1628937684,"wm2State":true}%

バッテリー情報、サムターンのポジション、施錠状態などが確認できます。
(施錠・解錠ログを取得するAPIもありますが、今回は割愛)

解錠・施錠

公式ページを参照するとBODYcmdhistorysignをつけてPOSTすれば良いとのこと。

公式ページから抜粋
POST: "https://app.candyhouse.co/api/sesame2/${sesame_id}/cmd"
BODY: {
        cmd: cmd,
        history: base64_history,
        sign: sign
}

※上の「${sesame_id}」はUUIDのこと

BODY 公式説明 備考
cmd 開閉コマンドコード toggle:88、lock:82、unlock:83
history 履歴 操作ログを見たときに表示される名前
sign 署名 秘密鍵をAES-CMACで暗号化した署名
toggleって何に使うんですかね…

Pythonからアクセス

以下、Python3での動作です。
pysesame3というSESAME3専用ライブラリもありますが、今回は利用していません。

ライブラリ

今回使用するライブラリをインポートします。
事前にpipでインストールしておきましょう。

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

パラメータ(APIキー、秘密鍵、UUID)

先程取得した各種パラメータを使います。

# 各種パラメータ
uuid = 'my-uuid'
secret_key = 'my-secret_key'
api_key = 'my-api_key'

BODY

まずは開閉のコマンドcmdに値を入れます。
今回はlock:82で施錠します。

# cmd
cmd = 82

続いてhistoryは自分でわかりやすい名前をつければ良いだけなので、「WEB API」としました。
複数ノードからAPIを叩く場合には、判別できるように名前を区別したほうがよいかもしれません。
base64でエンコードしてからbodyに入れます

# history
history = 'WEB API'
base64_history = base64.b64encode(bytes(history, 'utf-8')).decode()

署名部分は秘密鍵をCMACを利用して暗号化します。
タイムスタンプを追加してから、HEXのダイジェスト値を作ります。

# sign
cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES)
ts = int(datetime.datetime.now().timestamp())
message = ts.to_bytes(4, byteorder='little')
message = message.hex()[2:8]
cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES)
cmac.update(bytes.fromhex(message))
sign = cmac.hexdigest()

あとはAPIリクエストをセットして完了です。

# API
url = f'https://app.candyhouse.co/api/sesame2/{uuid}/cmd'
body = {
    'cmd': cmd,
    'history': base64_history,
    'sign': sign
}
res = requests.post(url, json.dumps(body), headers=headers)

コード全体

実際の運用では、クラスオブジェクトにしてレスポンスの確認やエラー処理などを追加していますが、単体の動作確認だけであればこのコードだけでも十分です。

import datetime, base64, requests, json
from Crypto.Hash import CMAC
from Crypto.Cipher import AES

# 各種パラメータ
uuid = 'my-uuid'
secret_key = 'my-secret_key'
api_key = 'my-api_key'

# ヘッダーの設定
headers = {'x-api-key': api_key}

# cmd
cmd = 82 # 施錠する場合は「82」、解錠する場合は「83」

# history
history = 'WEB API' # とりあえず「WEB API」と名付ける
base64_history = base64.b64encode(bytes(history, 'utf-8')).decode()

# sign
cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES)
ts = int(datetime.datetime.now().timestamp())
message = ts.to_bytes(4, byteorder='little')
message = message.hex()[2:8]
cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES)
cmac.update(bytes.fromhex(message))
sign = cmac.hexdigest()

# API
url = f'https://app.candyhouse.co/api/sesame2/{uuid}/cmd'
body = {
    'cmd': cmd,
    'history': base64_history,
    'sign': sign
}
res = requests.post(url, json.dumps(body), headers=headers)

注意すること

詳細は公開されていないようですが、WEB API利用数に制限があるようです。
正確な数字はわかりませんが、1アカウントにつき900-1000回くらいのようです。1日放置したら制限は解除されていました。

CANDYHOUSE様に問い合わせたところ、WEB APIの有料化が予定されていて、その後有料ユーザは利用制限が解除されるそうです。
現時点でWEB API利用は無料です。(2021年8月時点)

利用頻度が高い場合は注意です。締め出されたり閉じ込められたりします…。

6
14
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
6
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?