BOSEサウンドプロセッサーEX-1280CのGainをNode-REDから操作する方法 その2

前回の記事でEX-1280CをNode-REDから操作する方法についてご紹介しました。

BOSEサウンドプロセッサーEX-1280CのGainをNode-REDから操作する方法 その1

今回は、Gainノードの名前や音量、Muteなどを動的に変更できるようなフローとレスポンスの解析機能を追加しました。

Node-REDのフロー

[{"id":"e4fcfcfb12591339","type":"tcp request","z":"3ef7ef2110606386","name":"EX-1280C:10055","server":"192.168.10.41","port":"10055","out":"time","ret":"string","splitc":"100","newline":"","trim":false,"tls":"","x":570,"y":220,"wires":[["27c5ee5236859656"]]},{"id":"27c5ee5236859656","type":"function","z":"3ef7ef2110606386","name":"レスポンス解析","func":"let str = msg.payload.toString();\n\n// 正規表現で3つの部分をキャプチャ\n//   1. \"\"の間の文字列\n//   2. > の後の数字\n//   3. = の後の数値または文字(負号、小数点、アルファベットを許可)\nlet match = str.match(/\"([^\"]+)\"\\>(\\d+)=([-\\d.FO]+);/i);\n\nif (match) {\n    msg.target = match[1];              // \"\"の間の文字列\n    msg.index  = parseInt(match[2]);    // > の後の数字\n\n    // 値が数値か文字かを判定\n    if (!isNaN(match[3])) {\n        msg.value = parseFloat(match[3]);   // 数値なら数値として\n    } else {\n        msg.value = match[3];               // 文字ならそのまま\n    }\n} else {\n    msg.target = null;\n    msg.index  = null;\n    msg.value  = null;\n}\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":280,"wires":[["936e6ec6ddacd2ba"]]},{"id":"a4f10efeb52fea1f","type":"debug","z":"3ef7ef2110606386","name":"debug 15","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":860,"y":420,"wires":[]},{"id":"829ab22d7ac21470","type":"function","z":"3ef7ef2110606386","name":"SA操作","func":"// 変数を定義\nlet cmd = \"SA\";                  // コマンド\n//let target = \"BGM_CD_VOL\";       // ターゲット名\nlet target = msg.target;\nlet index = msg.index;                  // インデックス1\nlet value  = msg.payload;                  // 設定値\n\n// コマンド文字列を組み立て\nlet str = `${cmd}\"${target}\">${index}=${value}\\r`;\n\n// Bufferに変換(ASCII)\nmsg.payload = Buffer.from(str, 'ascii');\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":160,"wires":[["e4fcfcfb12591339"]]},{"id":"05e6923a425afa96","type":"inject","z":"3ef7ef2110606386","name":"音量 10","props":[{"p":"payload"},{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"1","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":130,"y":100,"wires":[["829ab22d7ac21470"]]},{"id":"4bf4031f835c63c0","type":"inject","z":"3ef7ef2110606386","name":"音量 1","props":[{"p":"payload"},{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"1","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":130,"y":140,"wires":[["829ab22d7ac21470"]]},{"id":"504b7a8bd79f687a","type":"function","z":"3ef7ef2110606386","name":"GA STATUS取得","func":"// 変数を定義\nlet cmd = \"GA\";                  // コマンド\nlet target = msg.target; // ターゲット名\nlet index = msg.index;                  // インデックス1\n\n// コマンド文字列を組み立て\nlet str = `${cmd}\"${target}\">${index}\\r`;\n\n// Bufferに変換(ASCII)\nmsg.payload = Buffer.from(str, 'ascii');\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":320,"wires":[["e4fcfcfb12591339"]]},{"id":"b666fe379bfb65bd","type":"inject","z":"3ef7ef2110606386","name":"GA  (Value)","props":[{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"1","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":320,"wires":[["504b7a8bd79f687a"]]},{"id":"936e6ec6ddacd2ba","type":"switch","z":"3ef7ef2110606386","name":"","property":"target","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":770,"y":360,"wires":[["a4f10efeb52fea1f"]]},{"id":"1c34eefbe45a482b","type":"inject","z":"3ef7ef2110606386","name":"Mute ON","props":[{"p":"payload"},{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"2","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"O","payloadType":"str","x":140,"y":180,"wires":[["829ab22d7ac21470"]]},{"id":"49ec38876be0da79","type":"inject","z":"3ef7ef2110606386","name":"Mute OFF","props":[{"p":"payload"},{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"2","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"F","payloadType":"str","x":140,"y":220,"wires":[["829ab22d7ac21470"]]},{"id":"713e624dc13046db","type":"inject","z":"3ef7ef2110606386","name":"GA(Mute)","props":[{"p":"target","v":"BGM_CD_VOL","vt":"str"},{"p":"index","v":"2","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":360,"wires":[["504b7a8bd79f687a"]]}]

フローの解説

音量をコントロールするInjectノードには、

payload : 音量の値

target : 制御するGainノードのLabel名

index : 1だと音量 / 2だとMuteの操作

となっています。

こちらがMuteのノードです。

SA操作ノードで、TCPに送信するデータ形式を作成しています。

GainノードのStatusを取得するにはGAコマンドを使います。Injectノードでは対象のLabelをTarget、音量にするかMuteにするかをindexで設定しています。

SAコマンドで送信した後はレスポンスがないので、GAコマンドをおくったときのレスポンスの解析です。

音量の取得結果。

Muteの取得結果

まとめ

以上、Node-REDからBOSEサウンドプロセッサーEX-1280Cを制御する方法をご紹介しました。