コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Switch Botのカスタムコネクタを作成する①


スポンサードリンク

はじめに

調べてみたら私のブログでカスタムコネクタに関しての記事書いていなかったので備忘録も兼て纏めてみました。

今回作成するもの

今回作成するカスタムコネクタはSwitch Botのコネクタです。

Switch Bot便利ですよね。

私はエアコン、電気、テレビのオンオフをSwirch BotとAlexaを連動させて音声での操作をしています。
電源ぐらい自分でつければ?と最初は思われるかもしれませんが、使ってみると何かしながら声で操作をできるので結構便利ですよ。

またこの時期ですと、外からもうすぐ家につくな?というタイミングで冷房をつけたりと結構重宝しています。

さて、このSwitch Botですが連携可能な製品が色々出ていまして例えばこいつ。

これを使えば温度と湿度も取れます。
おうちの状態これで色々管理・分析できるようになりそうですね。
時代はIoTですよ!w

そしてこのSwitch BotですがAPIが公開されています!

github.com

英語ですが、そこは頑張って読み解くことにしましょう。

事前準備

Switch Botや各製品を購入したばかりで、まだセットアップを行っていない。
という場合はまずはセットアップから初めて、通常の操作で想定の動作が行えていることを確認してください。

先ほど紹介したSwitch BotGitHubの「Getting Started」が事前準備にあたります。

  1. Switch Botのアプリをスマートフォンにダウンロード
    SwitchBot - Google Play のアプリ
    ‎「SwitchBot」をApp Storeで
  2. Switch Botのアカウントを登録し、ログイン
  3. アプリ内でトークンを生成
    1. プロフィール > 設定
    2. アプリバージョンを10回タップして開発者向けオプションを表示
    3. 開発者向けオプションをタップ
    4. トークンを取得をタップ

ここで取得したTokenを用いてAPIを叩きます。

カスタムコネクタを作成する

APIのテストを行う

作成方法はいくつかあるのですが、この記事ではPostmanから作成する方法を紹介します。

理由はいきなりカスタムコネクタの作成から入ってしまうと、APIの投げ方が誤っているのか、それともカスタムコネクタの作成方法に誤りがあるのか?が判別できないからですね。

Postman持ってないよーって方はこちらからダウンロードしてください。
無料です。

www.postman.com

Postman自体の詳しい使い方はこの記事では省きます。
有名なソフトなので調べればたくさん紹介している記事がでてきますよー

バイスの一覧を取得する

We will stop adding support for new products on v1.0 as we release v1.1.

Hence, we strongly recommend all SwitchBot users to migrate to the new API version because we have improved the authentication method. This will make the communication between your server and the SwitchBot server more secure.

と記載があり、新しいAPIであるv1.1の利用を強く勧められているのでv1.1を今回は利用することにします。

なおv1.1を利用するにはそれなりの知識が必要になります。
結構苦戦しました(1敗)

ただv1.1で行った方が通信がセキュアに行われますし、v1.0では行えなかったSwitchBotのロック制御ができるようになるらしいので、できればv1.1を使った方がいいと思いますよ。

さて、v1.0とv1.1の認証方法の違いですが、v1.0はTokenだけで認証を行っていましたが、v1.1ではTokenとSecret Keyで認証を行うようになりました。

先ほど開発者モードでTokenを取得した際、2つのTokenが表示されていたかと思います。(されてなかった人はアプリのバージョンが古いのでアップデートをおすすめします。)

これによりセキュアな認証が行えるようになったのですが、ここが躓くポイントですかね。

ドキュメントにはご丁寧にサンプルが記載されています。

import time
import hashlib
import hmac
import base64

# open token
token = '' # copy and paste from the SwitchBot app V6.14 or later
# secret key
secret = '' # copy and paste from the SwitchBot app V6.14 or later
nonce = ''
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())
print ('Authorization: {}'.format(token))
print ('t: {}'.format(t))
print ('sign: {}'.format(str(sign, 'utf-8')))
print ('nonce: {}'.format(nonce))

上記はPython 3系です。
Python 2系もサンプルがありますので、必要な方はドキュメントをご参照ください。

コードわからない方向けに解説すると、13桁のタイムスタンプを生成し、TokenとSecret Key、先ほどの13桁のタイムスタンプ、さらに改ざんチェック用の文字列をもとに署名を生成しています。

ここで生成された13桁のタイムスタンプと署名がv1.1では必須になってきます。

ここですね。

signtがv1.1だと必須だと書かれているかと思います。

書いてないけど、nonceも必要なんじゃないかな?

ということで、Headerに必要なのは以下5つの要素ですね。

以下コピペ用

Content-Type:application/json; charset=utf8
Authorization:{{Token}}
sign:{{sign}}  
t:{{t}}  
nonce:{{nonce}}  

Bulk Editで編集モードを変えてこれ貼り付ければOKです。

私の場合、Host DomainやらToken、Secret Keyは環境編集に入れています。

ここから新規環境を適当な名前で作成して、以下を入れてください。

signtは適当でいいですよ。
スクリプトで書き換えるので。

バイス一覧を取得するには、

GET /v1.1/devices

で行うらしいので、Host Domainの

https://api.switch-bot.com

と組み合わせて

GET {{url}}/v1.1/devices

と設定します。

さて、tsignを生成するためのスクリプトを書いていきます。

Postmanではスクリプトは「Pre-request Script」に書いていきます。

ただ、ここJavaScriptで書かないといけないので、Pythonのコードをちょっと改修しないといけません。

...

と思って一生懸命書いたのにさ!記事書いている今更新したらREADME更新されてJSのコードも載ってるじゃん!!時間返して!

まぁ悲しいので備忘録がてらここに私の作成した無様なJSも載せておきます。

String.prototype.format = function(){
    let formatted = this;
    for(let arg in arguments){
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};

var token = pm.environment.get("Token");
var secret = pm.environment.get("SecretKey");
var nonce = pm.environment.get("nonce");
var t = Date.now();
var string_to_sign = '{0}{1}{2}'.format(token, t, nonce);

string_to_sign = encodeURIComponent(string_to_sign);

var sign = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(string_to_sign, secret));

pm.environment.set("t", t);
pm.environment.set("sign", sign)

サンプルがこちら

const token = "yourToken";
const secret = "yourSecret";
const t = Date.now();
const nonce = "requestID";
const data = token + t + nonce;
const signTerm = crypto.createHmac('sha256', secret)
    .update(Buffer.from(data, 'utf-8'))
    .digest();
const sign = signTerm.toString("base64");
console.log(sign);

const body = JSON.stringify({
    "command": "turnOn",
    "parameter": "default",
    "commandType": "command"
});
const deviceId = "MAC";
const options = {
    hostname: 'api.switch-bot.com',
    port: 443,
    path: `/v1.1/devices/${deviceId}/commands`,
    method: 'POST',
    headers: {
        "Authorization": token,
        "sign": sign,
        "nonce": nonce,
        "t": t,
        'Content-Type': 'application/json',
        'Content-Length': body.length,
    },
};

const req = https.request(options, res => {
    console.log(`statusCode: ${res.statusCode}`);
    res.on('data', d => {
        process.stdout.write(d);
    });
});

req.on('error', error => {
    console.error(error);
});

req.write(body);
req.end();

ただこれ動くのかな?
適当に書き換えてみたけど、Postmanでは動かなかったですね。

そこまで検証しようとは思えないので、追走するどなたかお任せします。

これを実行すると以下のような結果が得られるはずです。

{
    "statusCode": 100,
    "body": {
        "deviceList": [
            {
                "deviceId": "500291B269BE",
                "deviceName": "Living Room Humidifier",
                "deviceType": "Humidifier",
                "enableCloudService": true,
                "hubDeviceId": "000000000000"
            }
        ],
        "infraredRemoteList": [
            {
                "deviceId": "02-202008110034-13",
                "deviceName": "Living Room TV",
                "remoteType": "TV",
                "hubDeviceId": "FA7310762361"
            }
        ]
    },
    "message": "success"
}

上の結果はドキュメントにあったサンプルなので私のではないです。

ここで結果の違った方は、どこか設定間違えている可能性があるので見直してみてください。

バイスを操作する

バイスを操作するには以下APIを投げるようです。

POST /v1.1/devices/{deviceId}/commands

GETではなくPOSTなのでお待ちがいなく。

deviceIdには先ほどデバイスの一覧で取得したデバイスのIDをいれます。

操作するコマンドはBodyに記載します。

例えば電気を消すコマンドは

{
    "command": "turnOff",
    "parameter": "default",
    "commandType": "command"
}

こんな感じ。

コマンドは製品ごとに異なってくるので、詳しいコマンドはドキュメント確認してください。

JSONファイルのエクスポート

PostmanでのAPIのテストが一通り済んだら、作成したAPIたちをコレクションにいれ、エクスポートしてあげます。

これを用いてカスタムコネクタを作成します。

Postmanからカスタムコネクタを作成する

Dataverse > カスタムコネクタ より、カスタムコネクタの新規作成 > Postmanコレクションからインポートします
を選択します。

コネクタの名前はわかりやすい名前を設定し、インポートするファイルは先ほどエクスポートしたファイルを用います。

ここから色々設定していけばできるはずですが、コード書きなおさないといけないのでいったんここまで。

続きは別で。

おわりに

PostmanのScriptそのままカスタムコネクタにもってこれたら楽なんですけどね。

あと私事ですが、この記事を書いているときに大型の台風がきていまして非常に体が怠い。
低気圧に敗北しました。

なので、一旦ここまでで区切ることにしました。すみません。。。

これだとカスタムコネクタの説明じゃなくってSwitch Botのv1.1のAPIをPostmanで使ってみた説明ですね。。。


スポンサードリンク