TouchDesignerとobnizをWebsocket連携してLチカしてみた

こんにちは。まつしたと申します。

TouchDesignerについては[TouchDesigner Study Weekend](https://tdsw.co/)(以下TDSW)で初心者コースとarduinoコースを受講しただけの超絶初心者ですが、無謀にもAdvent Calendarに参戦しました！
普段は[野良ハックチーム](https://qiita.com/yskmjp/items/cedbfd3f3980c42a8771)という名前でIoT界隈でデモなどをしているので、IoT開発ボードとTouchDesignerの連携の話です。

## obnizとは
IoTの開発ボードには様々な種類があり、新しいものも次々に発売されていますが、今回は[obniz](https://obniz.io/)と連携してみます。他のボードと比べて以下のような特徴がありTouchDesignerユーザにも親和性が高いと思います。

- Javascript/Node.jsでプログラムが書ける
- obniz-idによるデバイス指定で配線不要でプログラムが書き込める
- ボードに付属のディスプレイ、ボタンで初期設定ができる

## WebsocketでLチカ
ではさっそくTouchDesignerとobnizを連携させましょう。IoTの基本、LEDを光らせてみます。
方法はいくつかありますが今回はWebsocketを使います。obnizにはWebsocket APIとREST APIが用意されていてJSONで操作することができます。
https://obniz.io/spec/api
TouchDesingerにもDATにWebSocketオペレータがあるので、これを連携していきます。

## obniz側の準備
クラウドに用意されているAPIと、全てのobnizに割り振られているobniz-idを使えばプログラム不要です。超便利ですね。

obniz本体にはLEDを直接挿します。(抵抗入りのLEDを使っています)
アノード(足が長い方)を0、カソード(足が短い方)を1に挿しています。

![obniz.JPG](https://qiita-image-store.s3.amazonaws.com/0/149785/2531d0ff-8b02-d004-ba5d-c96166ff254a.jpeg)

## TouchDesinger側の準備
### DAT WebSocket
WebSocketオペレータを用意し「Network Address」にobnizのWebsocket APIを入れます。ただしAPIはリダイレクトされるようで、リダイレクト先を指定しないとうまく動きませんでした。この辺りは[enebularでobnizをLチカしてみた](https://speakerdeck.com/hmaruyama/20181122?slide=13)を参考にさせてもらいました。

Websocket API: wss://obniz.io/obniz/{obniz_id}/ws/1
リダイレクト先1: wss://1.ws.obniz.io/obniz/{obniz_id}/ws/1
リダイレクト先2: wss://2.ws.obniz.io/obniz/{obniz_id}/ws/1
{obniz-id}には自分のIDを入れます

<img width="428" alt="スクリーンショット 2018-12-03 17.57.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/149785/1e8f3d7f-6c22-d918-72d8-eef86100c15c.png">

接続成功するとWebSocketのtableに以下のようなAPIからの応答メッセージが表示されます。
```
[{"ws":{"ready":true,"obniz":{"firmware":"1.0.12"}}}]
```

<img width="670" alt="スクリーンショット 2018-12-03 17.55.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/149785/52ea2cc3-a596-bc23-5992-91798bb1045d.png">

(2022/08/20 追記)
最新でリダイレクト先を確認したところ8ws.obniz.ioでした。
今後も変更される可能性があるので、うまく接続できない場合は本来のWebsocket APIである「wss://obniz.io/obniz/{obniz_id}/ws/1」を「Network Address」に設定してください。
上記画面のように「redirect」として最新のリダイレクト先が表示されますので、そのアドレスを「Network Address」に書き換えて再接続してみてください。

### DAT CHOP Execute
CHOP Executeで値が1の場合にLEDを光らせる、0の場合には消すというプログラムを書きます。
obnizの準備でLED配線として0番にアノード、1番にカソードを挿したので、光らせる時にはio0にTrue、io1にFalseをioをコントロールするJSONとして送ります。これで電流が流れてLEDが光ります。消す時にはio0、io1ともにFalseとして電流が流れないようにします。

``` python
import json

def onValueChange(channel, sampleIndex, val, prev):
	if val == 1:
	    op('websocket1').sendText(json.dumps([{"io0":True, "io1":False}]))
	elif val == 0:
	    op('websocket1').sendText(json.dumps([{"io0":False, "io1":False}]))
	return
```

次にCHOP Null を用意して、CHOP ExecuteのCHOP欄にnull1を指定すると、Nullオペレータに入ってきた1か0を判定してLチカするようになります。

<img width="1160" alt="スクリーンショット 2018-12-03 18.09.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/149785/a8c3fa0b-5852-9a27-4b58-6345233d7290.png">

WebSocketの使い方は以下の記事を参考にしました。
[TouchDesignerとNode-REDをWebSocketで連携するメモ]
(https://www.1ft-seabass.jp/memo/2017/07/21/touchdesigner-nodered-websocket-meetup/)

## ボタン連携
まずはTouchDesigner上のボタンを押すとLEDが光るようにしてみましょう。
COMP Buttonオペレータを用意しNullと接続します。

ボタンを押すとLEDがついたり消えたりしました！

![obniz_test.GIF](https://qiita-image-store.s3.amazonaws.com/0/149785/522ca2eb-0b4f-1728-99c1-0f35d99f16f0.gif)

## 音楽と同期
次は音楽に同期してLEDを光らせます。
音楽と同期して3Dの箱が大きくなる部分は初心者用ワークショップで作ったものです。
Audio File InからTriggerで音が大きくなった瞬間を取り出して先ほどのNullに接続しています。

![obniz_LED.GIF](https://qiita-image-store.s3.amazonaws.com/0/149785/0728b1cd-cce4-e3bf-0ec2-8594f27d8f3b.gif)

箱が大きくなるのと同期してLEDが光るようになりました！

## おまけ TouchDesignerのデモTips
### 手元のデバイスを画面表示する方法
Lチカについてデモをする機会が[TouchDesigner Study Weekend vol.12](https://tdsw012.peatix.com/?lang=ja)でありました。
プレゼンをしながらカメラ映像を共有をする方法は色々とありますが、開発画面を見せながらobnizのLチカを見せたく、Video Stream Inオペレータを使ってrtspで映像を配信して同一画面上に出すという方法を取りました。
映像ソースにはiPhoneをrtspサーバにして映像配信できる[LiveReporter](http://kzkysdjpn.mydns.jp/livereporter/index.html?LANG=jp)というアプリを使っています。

デモの時の映像はこちらです。（デモは3分あたりから）
https://www.youtube.com/watch?v=3XBNCjJLUA4

デモは微妙にうまくいっていませんが(笑) 画面左上にVideoStreamInを使って手元のobnizを表示しました。今見ると画面が小さくて見辛いので、今後は大きく映すなど工夫したいと思います。

明日はTDSW主催の@narumin256の記事ですね。楽しみです！