🔌

PowerShellからSwitchBotのAPIを叩く

2023/09/26に公開

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 からデバイスの制御をするときに必要です.

デバイス一覧取得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
}

参考サイト

https://github.com/OpenWonderLabs/SwitchBotAPI
https://blog.switchbot.jp/announcement/api-v1-1
https://learn.microsoft.com/ja-jp/powershell/scripting/samples/creating-.net-and-com-objects--new-object-?view=powershell-5.1
https://learn.microsoft.com/ja-jp/powershell/scripting/samples/using-static-classes-and-methods?view=powershell-5.1

Discussion