Pixoo64のREST APIを使ってみた①

# Pixoo64とは
Divoom社が作っているピクセルアートディスプレイのシリーズで16×16、32×32、64×64などのLEDを搭載し、ピクセルアートを表示できるガジェットになっています。
最新シリーズがPixoo64(ピクソー64)2021年12月17日発売だったようです。
前作のPixooMax(ピクソーマックス)が32×32でしたが、解像度が64×64にアップしました。
さらに接続方式がBluetoothからWiFiになり、スマホアプリがなくても、天気などの情報が更新できるように進化しました。
9月15日に楽天のSUGOROKU LIFEというDivoom社の日本正規代理店で購入しました15800円(税込み)です。
![pixoo64_1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/ba10a2e2-2a11-8179-a2ba-3f5ec13fbc7c.jpeg)
仕様はこんな感じで、26.2cm四方なので結構大きいです。
![pixoo64_2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/f11e4dbb-d962-e443-45bd-27d0cfcbbdc0.jpeg)

# セットアップ
初期設定にはDivoomのアプリ(iOS,Android)が必要です。
Divoomのアカウントを作り、Pixoo64をマイディバイスに登録、接続するWiFiのパスワードを入れて接続完了
アニメーション、アラーム、カウントダウン、スコアボードなどの機能があります。

iPad Airの縦(24.7cm)よりやや大きいです。縦でも固定できる大き目タブレット用のスタンドに何とか収まりました。
チャンネルからShiba Inu clock(柴犬時計)を選んでみました。今の天気、時計、曜日が表示されます。
![pixoo64_4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/a67715ae-80d8-9413-5d5c-d64c931589cc.jpeg)

# Pixoo64のREST API
Divoom社のFacbookページでPixoo64のREST APIの仕様のリンクがありました。
>PIXOO-64 X REST API
>Make your Pixoo-64 clock with a special function:
>LINK: http://doc.divoom-gz.com/web/#/12?page_id=89
>*Create your own clock face, and define it with the desired resource/API.
?>**This function is still in a testing progress. Please Email our developers if you have questions.
Rest API使うとスペシャル機能を作れるよということらしい。

# Pixoo64のREST APIを使ったみた
上記の仕様を見ると、基本的にPixoo64のデバイスのURLにコマンドとパラメータを指定したJSONをPOST送信すれば良いらしい。
http://<デバイスのIPアドレス>/Post
一部の機能定義の取得やDevice検索はDivoomのサーバを使います。

PowerShellでスクリプト作ってみました。
REST APIを使ったサンプルプログラム
```powershell:pixoo64ApiTest1.ps1
function SendRequest([string]$url, [String]$requestJson){
    [string]$responseJson = ""

    [Byte[]]$postData = [System.Text.Encoding]::UTF8.GetBytes($requestJson)
    $webRequest = [System.Net.WebRequest]::Create($url)
    $webRequest.Method = "Post"
    $webRequest.ContentType = "application/json;"
    $webRequest.ContentLength = $postData.Length
    if($postData.Length -gt 0)
    {
        [System.IO.Stream] $reqStream = $webRequest.GetRequestStream()
        $reqStream.Write($postData, 0, $postData.Length)
        $reqStream.Close()
    }
    $webResponse = $webRequest.GetResponse()
    if($webResponse.StatusCode -eq [System.Net.HttpStatusCode]::OK){
        $resStream = $webResponse.GetResponseStream()
        $reader = New-Object System.IO.StreamReader ($resStream, [System.Text.Encoding]::UTF8)
        $responseJson = $reader.ReadToEnd()
        $reader.Close()
        $resStream.Close()
    }
    else
    {
        throw "HttpWebResponse Status Code:" + $webResponse.StatusCode;
    }
    return $responseJson
}

#set device ip address.
$deviceIP = "";
if($deviceIP -eq "")
{
    [string]$FIND_DEVICE_URL = "https://app.divoom-gz.com/Device/ReturnSameLANDevice";
    $devResponseJson = SendRequest $FIND_DEVICE_URL ""
    $deviceData = ConvertFrom-Json $devResponseJson
    if($deviceData.DeviceList.Count -gt 0)
    {
        $deviceIP = $deviceData.DeviceList[0].DevicePrivateIP
    }
}
if($deviceIP -eq ""){
    Write-Host "pixoo device not found"
    exit
}

#Set Brightness Api
$postUrl = "http://" + $deviceIP + "/post"
$request = @{
    Command = "Channel/SetBrightness"; 
    Brightness = 100;
}
$requestJson = ConvertTo-Json $request
$responseJson = SendRequest $postUrl $requestJson
$jsonData = ConvertFrom-Json $responseJson
if($jsonData.error_code -ne 0)
{
    Write-Host "response error_code:" $jsonData.error_code
    exit
}

#Get All Setting Api
$postUrl = "http://" + $deviceIP + "/post"
$request = @{
    Command = "Channel/GetAllConf"; 
}
$requestJson = ConvertTo-Json $request
$responseJson = SendRequest $postUrl $requestJson
$jsonData = ConvertFrom-Json $responseJson
if($jsonData.error_code -ne 0)
{
    Write-Host "response error_code:" $jsonData.error_code
    exit
}
Write-Host $jsonData
```



簡単に解説すると
```powershell
function SendRequest([string]$url, [String]$requestJson){
    [string]$responseJson = ""

    [Byte[]]$postData = [System.Text.Encoding]::UTF8.GetBytes($requestJson)
    $webRequest = [System.Net.WebRequest]::Create($url)
    $webRequest.Method = "Post"
    $webRequest.ContentType = "application/json;"
    $webRequest.ContentLength = $postData.Length
    if($postData.Length -gt 0)
    {
        [System.IO.Stream] $reqStream = $webRequest.GetRequestStream()
        $reqStream.Write($postData, 0, $postData.Length)
        $reqStream.Close()
    }
    $webResponse = $webRequest.GetResponse()
    if($webResponse.StatusCode -eq [System.Net.HttpStatusCode]::OK){
        $resStream = $webResponse.GetResponseStream()
        $reader = New-Object System.IO.StreamReader ($resStream, [System.Text.Encoding]::UTF8)
        $responseJson = $reader.ReadToEnd()
        $reader.Close()
        $resStream.Close()
    }
    else
    {
        throw "HttpWebResponse Status Code:" + $webResponse.StatusCode;
    }
    return $responseJson
}
```
SendRequest関数は指定したURLにJson文字列をPOSTする関数です。
.NetのWebRequestクラスを使っています。
コンテンツタイプは"application/json"を設定する。
Postデータのコンテンツのサイズを設定して書き込み。
リクエストを送信しレスポンスを受け取る。
レスポンスのHTTPステータスコードがOKならば、JSON文字列を返す。
OKではないなら例外です。


```powershell
#set device ip address.
$deviceIP = "";
if($deviceIP -eq "")
{
    [string]$FIND_DEVICE_URL = "https://app.divoom-gz.com/Device/ReturnSameLANDevice";
    $devResponseJson = SendRequest $FIND_DEVICE_URL ""
    $deviceData = ConvertFrom-Json $devResponseJson
    if($deviceData.DeviceList.Count -gt 0)
    {
        $deviceIP = $deviceData.DeviceList[0].DevicePrivateIP
    }
}
if($deviceIP -eq ""){
    Write-Host "pixoo device not found"
    exit
}
```
Pixoo64のデバイスのIPアドレスを取得します。
Find deviceのRest APIが使えます。LAN内のIPがわかっている場合は毎回問い合わせる必要もないので固定値入れてください。
特にパラメータもないので、グローバルのIPとDivoomのPixoo64のデバイス情報がサーバーに登録されているのかな？
上記のSendRequest関数で結果を取得し、ConvertFrom-JsonでJson文字列をオブジェクトに変換します。
デバイスが見つかった場合、DeviceListに検出された個数分の情報が格納されています。
先頭のデバイスのプライベートIPアドレスを取得します。


```powershell
#Set Brightness Api
$postUrl = "http://" + $deviceIP + "/post"
$request = @{
    Command = "Channel/SetBrightness"; 
    Brightness = 100;
}
$requestJson = ConvertTo-Json $request
$responseJson = SendRequest $postUrl $requestJson
$jsonData = ConvertFrom-Json $responseJson
if($jsonData.error_code -ne 0)
{
    Write-Host "response error_code:" $jsonData.error_code
    exit
}
```
Set Brightness Apiを呼び出してみます。
先ほど取得したデバイスのIPアドレスをURLに指定します。
コマンドとして"Channel/SetBrightness"
明るさのパラメータBrightnessに100(最大)を設定します。
レスポンスのエラーコードが0(正常終了)であることを確認しています。


```powershell
#Get All Setting Api
$postUrl = "http://" + $deviceIP + "/post"
$request = @{
    Command = "Channel/GetAllConf"; 
}
$requestJson = ConvertTo-Json $request
$responseJson = SendRequest $postUrl $requestJson
$jsonData = ConvertFrom-Json $responseJson
if($jsonData.error_code -ne 0)
{
    Write-Host "response error_code:" $jsonData.error_code
    exit
}
Write-Host $jsonData
```
Get All Setting Apiを呼び出してみます。
コマンドとして"Channel/GetAllConf"
呼び出した結果のJson文字列をConvertFrom-Jsonでオブジェクトに変換します。

取得結果は以下のようになりBrightnessが100に設定されました。
```json
{error_code=0; Brightness=100; RotationFlag=0; ClockTime=10; GalleryTime=10; SingleGalleyTime=10; PowerOnChannelId=0; GalleryShowTimeFlag=0; CurClockId=168; Time24Flag=1; TemperatureMode=0; GyrateAngle=0; MirrorFlag=0; LightSwitch=1}
```

こんな感じで簡単にREST APIが使えるって良いね。
次回もう少し詳しくAIP見ていきます。