DALI-EthernetゲートウェイのDeeBridgeはTCP接続で対応するDALIコマンドを文字列で送れば、DALIネットワークにそのまま流してくれるので、IoT機器からDALIの照明をコントロールするのにとても使いやすい商品です。
今回は、Node-REDを中継として、外部システムから受け取った信号を対応するDALIコマンド形式に変換してゲートウェイであるDeeBridgeへ送る方法をご紹介します。
対応するDALIコマンド形式について
DALIコマンド形式は、下のようになります。

一番最初に”#”をつけ、その後に”照明器具のアドレス”、その後に”,”、最後に”コマンド”という形です。
たとえば、全部の器具を最大点灯、消灯するときは次のようになります。

というような感じです。
外部のシステムから送られるデータ(文字列)
外部のシステムから送られるデータの形式を、下記のように設定します。

さらに、
■ 器具Aを点灯させる場合
A,RECALL_MAX_LEVEL
■ 器具Aを消灯させる場合
A,OFF
■ 全ての器具を点灯させる場合
ALL,RECALL_MAX_LEVEL
■ 全ての器具を消灯させる場合
ALL,OFF
このように設定しました。
照明器具とDALIアドレス
照明器具の名前とDALIアドレスの対応表です。
DALIにはDAPとIAPという2つのアドレスがあります。
DAP : Direct Arc Power Control
IAP : Indirect Arc Power Control
簡単に説明すると、DAPはアドレスの後に明るさを数値で送りその器具を点灯させる明るさを指定するアドレス。
IAPはアドレスの後にコマンドに該当する数値を送り、あらかじめDALIにて用意された挙動を照明器具にさせるためのアドレスです。
↓ 詳細はこちらの器具を参照ください。
第6回ふたつのアドレスDAPとIAP/ゼロから始めるDALI制御

コマンドとDALIコマンド
以下はコマンドです。
こちらはコマンドになるので、上記DALIアドレスのIAPに送るものとなります。

Node-REDのフロー

Node-REDのフローはこのようにつくりました。
Injectionノードで”A,RECALL_MAX_LEVEL”という文字列を送ると、それを”01,05″に変換してTCP Outのノードにおくるようになっています。
器具番号とコマンドをDALIで理解できる形式に変更する
変換については、functionノードに以下のようなコードを書きました。
// アドレスとコマンドの宣言 var outputAddress; var outputCommand; // ',' で文字列を分解 // words = { "A","RECALL_MAX_LEVEL" } になる var words = msg.payload.split(","); // words[0]がアドレス // words[1]がコマンド // ==================== // 先頭のアドレスを変換 // ==================== outputAddress = words[0]; // アドレスリスト var addressList = { "A": "01", "B": "03", "C": "05", "D": "07", "ALL" : "255", } // アドレス設定 var address = words[0]; // アドレスと一致するものをDALIアドレスに変換 if(addressList.hasOwnProperty(address)){ outputAddress = addressList[address]; } // ==================== // コマンドをDALIコマンドに変換 // ==================== // コマンドリスト var commandList = { "RECALL_MAX_LEVEL" : "05", "OFF" : "00" }; // コマンドを設定 var command = words[1]; // 命令と一致するものをDALIへのシーン命令としてアサイン if(commandList.hasOwnProperty(command)){ outputCommand = commandList[command]; } // アドレスとコマンドを組み合わせてDALIコマンドにする msg.payload = "#"+outputAddress + "," + outputCommand; return msg;
結果

まずはなんにもついていない状態から
“A,RECALL_MAX_LEVEL”と送ると

Aの器具が点灯。
”ALL,RECALL_MAX_LEVEL”と送ると

全部の器具が点灯
“ALL,OFF”を押すと

全ての器具が消灯
ができました。
あとは、外部のシステムからデータをもらったときに、器具の名前とコマンドをもらえばDALIコマンドに変換することができそうです。
Node-REDのフロー
[{"id":"a44e8db8.dd9a5","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"ALL,RECALL_MAX_LEVEL","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":220,"wires":[["9ff1109d.1f70c"]]},{"id":"143fcde8.66c9b2","type":"tcp out","z":"65300bde.a0bb04","host":"192.168.3.10","port":"8421","beserver":"client","base64":false,"end":false,"name":"DeeBridge","x":870,"y":220,"wires":[]},{"id":"79a63ab.1a5adc4","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"ALL,OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":260,"wires":[["9ff1109d.1f70c"]]},{"id":"c8d4e19f.65a3b","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"A,RECALL_MAX_LEVEL","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":60,"wires":[["9ff1109d.1f70c"]]},{"id":"a351e349.be903","type":"debug","z":"65300bde.a0bb04","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":160,"wires":[]},{"id":"9ff1109d.1f70c","type":"function","z":"65300bde.a0bb04","name":"DALIコマンドへ変更","func":"// アドレスとコマンドの宣言\nvar outputAddress;\nvar outputCommand;\n\n// ',' で文字列を分解\n// words = { \"A\",\"RECALL_MAX_LEVEL\" } になる\n\nvar words = msg.payload.split(\",\");\n\n// words[0]がアドレス\n// words[1]がコマンド\n\n\n// ====================\n// 先頭のアドレスを変換\n// ====================\n\noutputAddress = words[0];\n\n// アドレスリスト\nvar addressList = {\n \"A\": \"01\",\n \"B\": \"03\",\n \"C\": \"05\",\n \"D\": \"07\",\n \"ALL\" : \"255\",\n}\n\n// アドレス設定\nvar address = words[0];\n\n// アドレスと一致するものをDALIアドレスに変換\nif(addressList.hasOwnProperty(address)){\n outputAddress = addressList[address];\n}\n\n// ====================\n// コマンドをDALIコマンドに変換\n// ====================\n\n\n// コマンドリスト\nvar commandList = {\n\"RECALL_MAX_LEVEL\" : \"05\",\n\"OFF\" : \"00\"\n};\n\n// コマンドを設定\nvar command = words[1];\n\n\n// 命令と一致するものをDALIへのシーン命令としてアサイン\nif(commandList.hasOwnProperty(command)){\n outputCommand = commandList[command];\n}\n\n// アドレスとコマンドを組み合わせてDALIコマンドにする\n\nmsg.payload = \"#\"+outputAddress + \",\" + outputCommand;\n\nreturn msg;","outputs":1,"noerr":0,"x":660,"y":180,"wires":[["a351e349.be903","143fcde8.66c9b2"]]},{"id":"81df2f89.fc391","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"A,OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":100,"wires":[["9ff1109d.1f70c"]]},{"id":"a76bae51.8a31e","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"B,RECALL_MAX_LEVEL","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":140,"wires":[["9ff1109d.1f70c"]]},{"id":"715bac31.3c2eb4","type":"inject","z":"65300bde.a0bb04","name":"","topic":"","payload":"B,OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":180,"wires":[["9ff1109d.1f70c"]]}]
まとめ
今後、いろんなシステムから照明が制御されることが増えてくるとおもいますが、データの受け渡しは人間が判断しやすいデータ形式にして、それをDALIコマンドに変換することで、それぞれの開発者が楽に制御のすり合わせができるようになればいいなと思います。