Device Portal APIでHoloLensの情報や操作をNode-REDダッシュボードで行うメモ

HoloLensの情報や操作を可能になるDevice Portal APIをNode-REDダッシュボードで行うメモです。

やりたいこと

Device Portalのページはとても便利ですが、たくさんの操作や情報取得ができるため「バッテリー残量を見たい」「画面キャプチャの指令を出したい」といったちょっとした利用には重厚な場合があります。

Node-REDでのDevice Portal APIの叩く練習をしつつ、あわよくばNode-REDでUIが手軽に作れるNode-REDダッシュボードで簡易UIがつくれないかやってみます。


※クリックすると拡大します
※この図表にはアイコン素材を無料でダウンロードできるサイト ICOOON MONOさんの素材を使いました。ありがとうございます。

準備

image

まず、HoloLens 用 Device Portal – UWP app developer | Microsoft Docsを参考にして、HoloLens Device Portalに使えるように、もろもろ設定しておきましょう。また、HoloLensの今回のIPアドレスも控えておきます。

また、Node-REDダッシュボードはnode-red/node-red-dashboard: A dashboard UI for Node-REDを参考にインストール下さい。

Node-REDダッシュボードの楽しさについては以下のスライドが分かりやすいです。

GET取得でバッテリー残量を表示

GET取得でダッシュボードにバッテリー残量を表示をしてみましょう。

Device portal API referenceをみると、/api/power/battery (GET) で取得可能です。

image

このようなフローを作り設定をしていきます。

image

changeノードの設定

changeノードは以下のように設定します。

image

HoloLensのIPに加えてHTTPSでDevice portal API referenceで確認した、/api/power/battery のURLを作り、以降のhttp requestノードの送り先に設定するためにmsg.urlに値をSetします。

image

http requestノードの設定

http requestノードの設定は以下のとおりです。まず、Device Portalにリクエストするときは以下の設定が必要です。

Windows Device Portal の概要 – UWP app developer | Microsoft Docs

CSRF に対する保護とスクリプト

CSRF 攻撃に対する保護のために、すべての非 GET 要求に一意のトークンが必要です。 このトークン、X-CSRF-Token 要求ヘッダーは、セッション Cookie、CSRF-Token から派生します。 Device Portal の Web UI では、CSRF-Token Cookie が、各要求の X-CSRF-Token にコピーされます。

image

  • Enable secure (SSL/TLS) connection
    • チェックする
  • Use basic authentication
    • チェックする
    • Username / Password にはDevice PortalにログインできるIDとパスワードを入力

Enable secure (SSL/TLS) connectionに付随するTLS Configrationは以下のように設定します。

image

  • Certificate・Private Key・CA Certificate
    • 設定せず
  • Verify server certificate
    • チェックしない(デフォルトがチェックされているので外す)

もしも、

"Error: unable to verify the first certificate"

image

といったエラーが出る場合は、だいたいは上記の認証まわりが原因ですので、根気よく設定を確認して修正しましょう。

グラフ用調整のfunctionノードの設定

image

グラフ用調整のfunctionノードの設定は以下のとおりです。

image

以後のNode-REDダッシュボードに分かりやすくデータを送るために丸め処理など調整しています。

msg.payload = Math.floor( msg.payload.RemainingCapacity / msg.payload.MaximumCapacity * 100 );
return msg;

このようなスクリプトです。

ダッシュボードパーツの設定

ダッシュボードパーツの設定は以下のとおりです。

image

テキストを表示するダッシュボードパーツの設定です。

image

ゲージを表示するダッシュボードパーツの設定です。

image

うまく設定ができると以下のように表示されます!

image

POST取得の静止画キャプチャAPIに指示をするボタンをつくる

POST取得の静止画キャプチャAPIに指示をするボタンをダッシュボードに作ってみましょう。

image

このようなフローを設定していきます。

ダッシュボードのボタンパーツの設定

image

ボタンを表示するダッシュボードパーツの設定です。
image

特にこちらの設定はボタンの名付けのみ。Take Photo!! と名前をつけています。

changeノードの設定

image

changeノードは以下の通り。

image

まず、msg.urlには静止画キャプチャするURLを設定します。HoloLensのIPに加えてHTTPSでDevice portal API referenceで確認した静止画キャプチャのURLを設定します。

また、msg.payloadに押されたボタンのIDが来てしまうとPOST送信時のパラメータを付与してエラーになってしまうので、明示的に空文字を設定しています。ちなみに、静止画キャプチャで必要なパラメータはURLのほうに「holo=true&pv=true」の設定が入っていますのでご安心下さい。

http requestノード(GETのときと少し変わる)

image

http requestノードは以下のように設定します。まずバッテリー消費を取得するGET取得と同じように入力しておきます。TLS Configurationは先ほどのバッテリー消費を取得するGET取得と同じものを使えるのでプルダウンから選択します。

image

違いはUsernameのところです。

Windows Device Portal の概要 – UWP app developer | Microsoft Docs

“auto-” というユーザー名を使用します。 クライアントはユーザー名の前に “auto-” を追加することによって、CSRF に対する保護を迂回できます。 このユーザー名は、ブラウザーから Device Portal にログインするために使用しないでください。サービスが CSRF 攻撃を受ける可能性があります。 例: Device Portal のユーザー名が “admin” である場合、CSRF に対する保護を迂回するために curl -u auto-admin:password を使用します。

に説明されてるように非 GET 要求には普段アクセスしているID/PASSのIDにauto-を付ける必要があります。先ほどと同様にUsernameのところにauto-をつけます。

設定が終わってダッシュボードで表示すると

image

TAKE PHOTO !! ボタンをクリックするとHoloLensから写真が撮影されます!

image

こんなかんじです。レスポンスもかなりよいです。

今回のフローJSONデータ

フローJSONデータも置いておきます。

[{"id":"3092dc29.dd77b4","type":"http request","z":"eb234315.dc4b1","name":"GET","method":"GET","ret":"txt","url":"","tls":"49d6016a.ababa","x":550,"y":240,"wires":[["52480134.16332"]]},{"id":"db7b4c9e.5db0a","type":"debug","z":"eb234315.dc4b1","name":"","active":false,"console":"false","complete":"false","x":890,"y":160,"wires":[]},{"id":"2fbb3b0a.a87654","type":"change","z":"eb234315.dc4b1","name":"/api/power/battery","rules":[{"t":"set","p":"url","pt":"msg","to":"https://192.168.XX.XX/api/power/battery","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":240,"wires":[["3092dc29.dd77b4"]]},{"id":"f73fc4af.c60138","type":"inject","z":"eb234315.dc4b1","name":"","topic":"","payload":"","payloadType":"date","repeat":"30","crontab":"","once":false,"x":210,"y":240,"wires":[["2fbb3b0a.a87654"]]},{"id":"7ebb3a22.deb724","type":"ui_text","z":"eb234315.dc4b1","group":"9b69df15.a13d6","order":0,"width":0,"height":0,"name":"","label":"battery : ","format":"{{msg.payload}}","layout":"row-spread","x":1080,"y":260,"wires":[]},{"id":"52480134.16332","type":"json","z":"eb234315.dc4b1","name":"","x":670,"y":240,"wires":[["db7b4c9e.5db0a","4fe18933.a437b8"]]},{"id":"4bf39a9b.417094","type":"ui_gauge","z":"eb234315.dc4b1","name":"","group":"9b69df15.a13d6","order":0,"width":0,"height":0,"gtype":"donut","title":"Gauge","label":"%","format":"{{msg.payload}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":1070,"y":320,"wires":[]},{"id":"4fe18933.a437b8","type":"function","z":"eb234315.dc4b1","name":"グラフ用値調整","func":"msg.payload = Math.floor( msg.payload.RemainingCapacity / msg.payload.MaximumCapacity * 100 );\nreturn msg;","outputs":1,"noerr":0,"x":900,"y":320,"wires":[["4bf39a9b.417094","7ebb3a22.deb724"]]},{"id":"4cb1d8d6.3ecbc8","type":"debug","z":"eb234315.dc4b1","name":"","active":true,"console":"false","complete":"false","x":850,"y":520,"wires":[]},{"id":"c394ebd9.791d98","type":"change","z":"eb234315.dc4b1","name":"/api/holographic/mrc/photo","rules":[{"t":"set","p":"url","pt":"msg","to":"https://192.168.XX.XX/api/holographic/mrc/photo?holo=true&pv=true","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":520,"wires":[["c4b2a008.1ca99"]]},{"id":"c4b2a008.1ca99","type":"http request","z":"eb234315.dc4b1","name":"POST","method":"POST","ret":"txt","url":"","tls":"49d6016a.ababa","x":690,"y":520,"wires":[["4cb1d8d6.3ecbc8"]]},{"id":"dfab5bc8.610ad8","type":"ui_button","z":"eb234315.dc4b1","name":"","group":"9b69df15.a13d6","order":0,"width":0,"height":0,"label":"Take Photo !!","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"test","x":250,"y":520,"wires":[["c394ebd9.791d98"]]},{"id":"49d6016a.ababa","type":"tls-config","z":"","name":"","cert":"","key":"","ca":"","verifyservercert":false},{"id":"9b69df15.a13d6","type":"ui_group","z":"","name":"HoloLens","tab":"22e6423b.dbaa6e","disp":true,"width":"6"},{"id":"22e6423b.dbaa6e","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

HoloLensのIPは192.168.XX.XXにしてあります。これは自分のHoloLensのIPに合わせて使いましょう。Enable secure (SSL/TLS) connection、Use basic authenticationの部分はNode-REDの仕様上、引き継げないので本記事に従って設定し直して下さい。

おわりに

今回のダッシュボード、スマホでもいい具合に最適化され、操作も可能でした。これはいろいろと使えそうです。

image

実は最初にうまくいったときにはどちらかというと結構おもしろネタなのかなー?と思っていましたが、作ってみてよくよく考えると、うまく定期タイマーで写真を撮影したり、キャプチャした画像を別途Raspberry Piで配信したりと、案外いろいろな使い方ができる可能性を感じました。

それでは、よきHoloLens x Node-RED x ダッシュボード Lifeを!