PowerShellからSwitchBotのAPIを叩く
PowerShell から SwitchBot の API を叩く方法のメモ
SwitchBot API のドキュメント
SwitchBot API のドキュメントは GitHub で公式に公開されています.
https://github.com/OpenWonderLabs/SwitchBotAPI
認証ヘッダの作成
SwitchBot API の使用には認証が必要です.公式ドキュメントに従って,リクエストに付加する認証ヘッダを作成します.認証に使うトークンとクライアントシークレットの取得方法は,公式ブログの【API】新バージョン API v1.1 を公開しましたの手引きに書かれています.
PowerShell では.NET Framework が使用できるので,公式ドキュメントの C#用サンプルコードを少し書き換えるだけで実装できます.New-Object 型名
でインスタンスの作成が,[型名]::プロパティ名
で静的クラスのプロパティへのアクセスが可能です.
# トークンとクライアントシークレット
$token = "<token>";
$clientSecret = "<client secret>";
# トークン + ミリ秒単位のUnix時刻 + nonce がデータになる
$unixTimeStamp = [System.DateTimeOffset]::Now.ToUnixTimeMilliseconds();
$nonce = [System.Guid]::NewGuid().ToString();
$data = $token + $unixTimeStamp + $nonce;
# データのHMACを作成する
$encoding = [Text.Encoding]::UTF8
$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256;
$hmacsha256.Key = $encoding.GetBytes($clientSecret);
$hash = $hmacsha256.ComputeHash($encoding.GetBytes($data));
# HMACをBase64エンコードして最終的な署名を得る
$sign = [System.Convert]::ToBase64String($hash);
# ヘッダとなるハッシュテーブルを作成する
$headers = @{
"Authorization" = $token
"sign" = $sign
"nonce" = $nonce
"t" = $unixTimeStamp.ToString()
}
API リクエストの送信
デバイス一覧の取得
デバイスの一覧を取得して画面に表示してみます.デバイスの一覧は/devices
に GET リクエストを行うことで取得できます.PowerShell には REST リクエストを送信する Invoke-RestMethod
コマンドレットが用意されているので,簡単にリクエストを送信できます.
$apiEndpoint = "https://api.switch-bot.com/v1.1/"
$uri = $apiEndpoint + "devices"
$response = Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
Write-Host ($response | ConvertTo-Json)
リクエストに成功すれば,以下のような出力が得られます.deviceName
には SwitchBot のアプリ上で設定した名前が,deviceType
にはデバイスの種類が表示されます.deviceId
は各デバイスに付与された ID で SwitchBot API からデバイスの制御をするときに必要です.
{
"statusCode": 100,
"body": {
"deviceList": [
"@{deviceId=<デバイスID>; deviceName=hoge; deviceType=Plug Mini (US); enableCloudService=True; hubDeviceId=}",
"@{deviceId=<デバイスID>; deviceName=fuga; deviceType=Plug Mini (US); enableCloudService=True; hubDeviceId=}"
],
"infraredRemoteList": []
},
"message": "success"
}
デバイスへのコマンド送信
デバイス ID が分かればデバイスを制御するためのコマンドを送信できます.コマンドは,/devices/<デバイスID>/commands
に POST リクエストを行うことで送信します.
以下は,PlugMini を On にするコマンドを送信する例です.リクエストの Body に設定するコマンドの内容は,ハッシュテーブルで作成したものを ConvertTo-Json
コマンドレットを使って JSON 形式の文字列に変換しています.
$apiEndpoint = "https://api.switch-bot.com/v1.1/"
$deviceId = "<制御対象のデバイスID>"
$uri = $apiEndpoint + "devices/$deviceId/commands"
$body = @{
"commandType" = "command"
"command" = "turnOn"
"parameter" = "default"
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -ContentType "application/json" -Body $body
各デバイスで使用できるコマンドの詳細は公式ドキュメントのここに書かれています.
デバイス状態の取得やシーンの実行方法などの情報も公式ドキュメントにあります.
PlugMini を On/Off するスクリプトの例
Param(
# On or Off
[Parameter(Mandatory=$true)][ValidateSet("On", "Off")][string] $state
)
$token = "<token>";
$clientSecret = "<client secret>";
$plugMiniDeviceIds = ("<device id 1>", "<device id 2>");
$apiEndpoint = "https://api.switch-bot.com/v1.1/"
# 認証ヘッダの作成
$unixTimeStamp = [System.DateTimeOffset]::Now.ToUnixTimeMilliseconds();
$nonce = [System.Guid]::NewGuid().ToString();
$data = $token + $unixTimeStamp + $nonce;
$encoding = [Text.Encoding]::UTF8
$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256;
$hmacsha256.Key = $encoding.GetBytes($clientSecret);
$hash = $hmacsha256.ComputeHash($encoding.GetBytes($data));
$sign = [System.Convert]::ToBase64String($hash);
$headers = @{
"Authorization" = $token
"sign" = $sign
"nonce" = $nonce
"t" = $unixTimeStamp.ToString()
}
# APIリクエストの送信
foreach ($deviceId in $plugMiniDeviceIds) {
Write-Host "Turning $state $deviceId..."
$uri = $apiEndpoint + "devices/$deviceId/commands"
$body = @{
"commandType" = "command"
"command" = "turn$state"
"parameter" = "default"
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -ContentType "application/json" -Body $body
}
参考サイト
Discussion