外部ライター ワンフットシーバス 田中正吾です。
今回はenebularのFlowでも使われているNode-REDの知見の記事です。

先日、空間をデジタルでつなげる会社日本ピー・アイ株式会社 中畑さん、ウフル 花村さん、私の3人でディスカッションし技術調査していたオープンソースな照明のインターフェースDALI – Digital Addressable Lighting Interface についてNode-REDで連携するナレッジを社内にて共有してまいりました。
DALIとは
デジタルでアドレス設定可能な照明のインターフェースです。中畑さんが昨年書かれたNode.js,Electron,UnityからDALIで照明制御した記事から引用させていただくと、
DALIとはDigital Addressable Lighting Interfaceの略で、そのまま訳すと「デジタルでアドレス設定可能な照明のインターフェース」ということになりますが、すごく簡単に説明すると、照明に特化した仕様がオープンな制御のプロトコルのことです。
と、なります。
ひとまず、DALI機器と照明器具の接続ができると、人間の五感のなかでも大きな割合を占めている「視覚」に対して、デジタル側からいろいろとアプローチができるというものです。
是非やってみたくなる!ということで、中畑様、ウフル 花村様、私で意見交換を進めておりました。
初心者向け資料
以下の資料では、ざっくりと、DALI機器と照明器具の接続などを解説しています。
DALIとNode-REDでの連携は相乗効果になる
さて、今回はDALIとNode-REDでの連携です。DALIについて「いろいろとデジタル側から自在に照明が操れる」というイメージを持っていただければ十分です。
Node.js,Electron,UnityからDALIで照明制御した記事に書かれているように、Node.jsで動くということはenebularのFlowでも使われているNode-REDでも動くということです。
Node-REDはハードウェアデバイス/APIやオンラインサービスといった、さまざまなNode(プラグイン/モジュール)をビジュアルワークスペースに配置して、手軽にデジタルの処理が行える力があります。
このNode-REDが「いろいろとデジタル側から自在に照明が操れる」DALIと連携すれば、DALIは照明の素敵な演出を、Node-REDはデジタル側の素敵な処理を担当して、相乗効果が生み出せます。
いざやってみる

さて、当日はシーン設定を済ませてやってみました。Node-REDで実際にDALI照明と連携した動画です。
イエロー・ブルー・ピンク・他が白になるというボタンを押すとNode-REDで明かりが変わるフローが作れていますね!
実際のNode-REDの仕組み
実際のNode-REDの仕組みです。

イエロー・ブルー・ピンク・他が白になるというinjectノードで命令IDが飛ばされ、シーン判定で命令IDを元にDALI用の命令を作成し、DALIのゲートウェイに対してはTCP通信で アドレス,シーンID で送れば動画のようにシーンに合わせて明かりが変わります。
イエロー・ブルー・ピンク・他が白になるというinjectノード

イエロー・ブルー・ピンク・他が白になるというinjectノードはシンプルに「id1」「id2」「id3」「id4」といった文字列を送っています。

シーン判定の仕組み

シーン判定で命令IDを元にDALI用の命令をFunctionノードで作成します。

実際のソースです。
// DALIに送るシーン命令のリスト
// parseIntを利用して16進法で設定しDALIには10進法で伝える仕組みにしている。
// (10進法と16進法の調整は今後の課題)
//
// 例:全体(FF)にシーン1(11)を送る場合は、#255,17となる
var assign = {
"id1":"#" + parseInt("FF", 16) + "," + parseInt("11", 16), // DALIに送るシーン命令は #255,17
"id2":"#" + parseInt("FF", 16) + "," + parseInt("12", 16), // DALIに送るシーン命令は #255,18
"id3":"#" + parseInt("FF", 16) + "," + parseInt("13", 16), // DALIに送るシーン命令は #255,19
"id4":"#" + parseInt("FF", 16) + "," + parseInt("10", 16) // DALIに送るシーン命令は #255,16
};
// injectノードから命令IDがきたら変数に持つ
var cardID = msg.payload;
// 命令IDと一致するものをDALIへのシーン命令としてアサイン
if(assign.hasOwnProperty(cardID)){
msg.payload = assign[cardID];
}
return msg;
DALIにTCP通信で アドレス,シーンID で送るTCPノード

TCPノードはDALIにTCP通信で アドレス,シーンID で送ります。

hostにはDALIゲートウェイのIPアドレスを指定し、ポートは 8421 を指定します。このあたりはNode.js,Electron,UnityからDALIで照明制御した記事のNode.jsのコードを大変参考にさせていただきました。ありがとうございます。
動かしてみる
DALIネットワークが構築された場で、こちらNode-REDをinjectノードで動かすと、シーン命令が送られます。

するとカラーが次々に命令どおりに変わっていきます。

イエロー

ピンク

ブルー
遅延も少なくふわっとキレイに変わります!
実際のフロー
フローはこちらです。
[{"id":"67326ba1.ca50d4","type":"function","z":"33cb87bd.a36038","name":"シーン判定","func":"// DALIに送るシーン命令のリスト\n// parseIntを利用して16進法で設定しDALIには10進法で伝える仕組みにしている。\n// (10進法と16進法の調整は今後の課題)\n//\n// 例:全体(FF)にシーン1(11)を送る場合は、#255,17となる\nvar assign = {\n \"id1\":\"#\" + parseInt(\"FF\", 16) + \",\" + parseInt(\"11\", 16), // DALIに送るシーン命令は #255,17\n \"id2\":\"#\" + parseInt(\"FF\", 16) + \",\" + parseInt(\"12\", 16), // DALIに送るシーン命令は #255,18\n \"id3\":\"#\" + parseInt(\"FF\", 16) + \",\" + parseInt(\"13\", 16), // DALIに送るシーン命令は #255,19\n \"id4\":\"#\" + parseInt(\"FF\", 16) + \",\" + parseInt(\"10\", 16) // DALIに送るシーン命令は #255,16\n};\n// injectノードから命令IDがきたら変数に持つ\nvar cardID = msg.payload;\n// 命令IDと一致するものをDALIへのシーン命令としてアサイン\nif(assign.hasOwnProperty(cardID)){\n msg.payload = assign[cardID];\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":601,"y":295,"wires":[["7f364a7b.95f864","32813a0d.a592f6"]]},{"id":"7f364a7b.95f864","type":"tcp out","z":"33cb87bd.a36038","host":"192.168.0.252","port":"8421","beserver":"client","base64":false,"end":false,"name":"DALI","x":832.9286193847656,"y":489.5714111328125,"wires":[]},{"id":"946caafc.57b9a8","type":"inject","z":"33cb87bd.a36038","name":"イエロー","topic":"","payload":"id1","payloadType":"str","repeat":"","crontab":"","once":false,"x":409.6428527832031,"y":209.14288330078125,"wires":[["67326ba1.ca50d4"]]},{"id":"32813a0d.a592f6","type":"debug","z":"33cb87bd.a36038","name":"","active":true,"console":"false","complete":"false","x":839.6428527832031,"y":223.85712432861328,"wires":[]},{"id":"da1fee4c.a0ca5","type":"inject","z":"33cb87bd.a36038","name":"ブルー","topic":"","payload":"id3","payloadType":"str","repeat":"","crontab":"","once":false,"x":395.9999694824219,"y":321,"wires":[["67326ba1.ca50d4"]]},{"id":"459f2f.201ef0d","type":"inject","z":"33cb87bd.a36038","name":"ピンク","topic":"","payload":"id2","payloadType":"str","repeat":"","crontab":"","once":false,"x":391.9999694824219,"y":404,"wires":[["67326ba1.ca50d4"]]},{"id":"f7769a52.aefe98","type":"inject","z":"33cb87bd.a36038","name":"他が白になる","topic":"","payload":"id4","payloadType":"str","repeat":"","crontab":"","once":false,"x":410.9999694824219,"y":491,"wires":[["67326ba1.ca50d4"]]}]
まとめ
DALIは、今回のようなテープLEDだけでなく、もっと光量のある大きな照明も動かすことができます。たとえば移動できるDALI照明があるとして、配置や雰囲気に応じて光を作り出すために、Node-REDで簡単にフローが作ることが可能です。
また、現在ローカルネットワーク内で動くDALI APIを、enebular+Milkcocoaでグローバルネットワークで動くように拡張して、近隣の建物同士や、日本と海外の拠点といったレベルで遠隔操作でできるようなものもできそうですね。
DALI照明との連携について、また進捗あればお知らせします!



