I needed to control a 4X4 Matrix switcher for an installation from Node-RED so that I can bring the control of all hardware into one interface.
IR was an option, as inspired by this thread
However I found a simple (very simple) 4X4 4K HDMI switcher that has an RS232 port.
(it also comes with "rack ears" which is a bonus)
https://cpc.farnell.com/pro-signal/psg3450/4x4-4kx2k-60hz-matrix-switch/dp/AV29284
The commands were pretty simple, so I embarked on building a Flow
The RS232 <> USB dongle I have works with my Windows machine, but not the Linux machine that I want to deploy on site, so I'll have to find another dongle.
However, I do have a couple of LAN <> RS232 adapters, the flow I have created has provision for both solutions.
LAN Adapter is a USR-TCP232-306
With this flow I can ==
- Control each output independently.
- Select one input for ALL outputs
- Group outputs (defined in the admin, not on the fly)
[
{
"id": "23541210a65ebc7a",
"type": "tab",
"label": "4x4 Matrix",
"disabled": false,
"info": "ProSignal PSG 3450\n\n9600 bps\n\nOutput 1 Use input 1 - PS11R\nOutput 1 Use input 2 - PS12R\nOutput 1 Use input 3 - PS13R\nOutput 1 Use input 4 - PS14R\n\n\nOutput 2 Use input 1 - PS21R\nOutput 2 Use input 2 - PS22R\nOutput 2 Use input 3 - PS23R\nOutput 2 Use input 4 - PS24R\n\n\nOutput 3 Use input 1 - PS31R\nOutput 3 Use input 2 - PS32R\nOutput 3 Use input 3 - PS33R\nOutput 3 Use input 4 - PS34R\n\n\nOutput 4 Use input 1 - PS41R\nOutput 4 Use input 2 - PS42R\nOutput 4 Use input 3 - PS43R\nOutput 4 Use input 4 - PS44R\n\nQuery state - PA?R\n\nResponse\n\n[OriginalCommand] OK+xxxx\n\nWhere each number represents the selected input for that output",
"env": []
},
{
"id": "6f8f505add0bccce",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "RS232 / RS422 LAN adapter port 1259",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "msg",
"x": 590,
"y": 820,
"wires": []
},
{
"id": "96a896b9ba9edefb",
"type": "inject",
"z": "23541210a65ebc7a",
"name": "Query Settings",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "PA?R",
"payloadType": "str",
"x": 1060,
"y": 300,
"wires": [
[
"fe36322ca4b78102"
]
]
},
{
"id": "5f449a6202d566f5",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix Output 1",
"label": "OutPut 1",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": false,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "1",
"topicType": "str",
"className": "",
"x": 1100,
"y": 620,
"wires": [
[
"948becdfc39aca47"
]
]
},
{
"id": "97119f568f4e2c26",
"type": "function",
"z": "23541210a65ebc7a",
"name": "Set Matrix Output",
"func": "var Output = msg.topic;\nvar Input = msg.payload;\n\nif (Output == \"ALL\"){\n msg.payload=\"PA\"+Input+\"R\";\n}\n\nelse {\n \n msg.payload=\"PS\"+Output+Input+\"R\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1570,
"y": 620,
"wires": [
[
"7c980fea90163334",
"ad062a02ba7595e7",
"2b07c409543b5ee3"
]
]
},
{
"id": "7c980fea90163334",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "Set 4X4 Matrix outputs",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "msg",
"x": 1840,
"y": 620,
"wires": []
},
{
"id": "2c3a86643c3b2c52",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix Output 2",
"label": "OutPut 2",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": false,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "2",
"topicType": "str",
"className": "",
"x": 1100,
"y": 680,
"wires": [
[
"948becdfc39aca47"
]
]
},
{
"id": "a8b9057920ceb4b8",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix Output 3",
"label": "OutPut 3",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": false,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "3",
"topicType": "str",
"className": "",
"x": 1100,
"y": 740,
"wires": [
[
"948becdfc39aca47"
]
]
},
{
"id": "246dbe771eb0064a",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix Output 4",
"label": "OutPut 4",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": false,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "4",
"topicType": "str",
"className": "",
"x": 1100,
"y": 800,
"wires": [
[
"948becdfc39aca47"
]
]
},
{
"id": "39c655441c925e58",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix All Outputs",
"label": "ALL Outputs",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": false,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "ALL",
"topicType": "str",
"className": "",
"x": 1100,
"y": 860,
"wires": [
[
"948becdfc39aca47"
]
]
},
{
"id": "fe36322ca4b78102",
"type": "ui_button",
"z": "23541210a65ebc7a",
"name": "Query 4X4 Matrix",
"group": "036dd1c88da526c7",
"order": 5,
"width": 0,
"height": 0,
"passthru": true,
"label": "Query Output states",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "PA?R",
"payloadType": "str",
"topic": "query",
"topicType": "str",
"x": 1270,
"y": 300,
"wires": [
[
"ad062a02ba7595e7",
"105a054c60692e4a",
"2b07c409543b5ee3"
]
]
},
{
"id": "ad062a02ba7595e7",
"type": "tcp request",
"z": "23541210a65ebc7a",
"name": "Query 4X4 Matrix",
"server": "192.168.178.80",
"port": "1259",
"out": "time",
"ret": "string",
"splitc": "500",
"newline": "",
"trim": false,
"tls": "",
"x": 1730,
"y": 460,
"wires": [
[
"2155d466070d8262"
]
]
},
{
"id": "105a054c60692e4a",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "Query 4X4 Matrix outputs",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "msg",
"x": 1630,
"y": 300,
"wires": []
},
{
"id": "948becdfc39aca47",
"type": "delay",
"z": "23541210a65ebc7a",
"name": "",
"pauseType": "delay",
"timeout": "100",
"timeoutUnits": "milliseconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 1350,
"y": 620,
"wires": [
[
"97119f568f4e2c26",
"237ad28b7c87e310"
]
]
},
{
"id": "36477d0b5af6fa87",
"type": "ui_dropdown",
"z": "23541210a65ebc7a",
"name": "4X4 Matrix Output 1&2",
"label": "OutPuts 1&2",
"tooltip": "",
"place": "Select option",
"group": "036dd1c88da526c7",
"order": 0,
"width": 0,
"height": 0,
"passthru": true,
"multiple": false,
"options": [
{
"label": "First",
"value": "1",
"type": "str"
},
{
"label": "Second",
"value": "2",
"type": "str"
},
{
"label": "Odroid",
"value": "3",
"type": "str"
},
{
"label": "Sony Cam",
"value": "4",
"type": "str"
}
],
"payload": "",
"topic": "1&2",
"topicType": "str",
"className": "",
"x": 840,
"y": 500,
"wires": [
[
"dd0844b93cfb629d"
]
]
},
{
"id": "237ad28b7c87e310",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "Set 4X4 Matrix outputs topc",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "topic",
"statusType": "msg",
"x": 1580,
"y": 700,
"wires": []
},
{
"id": "d1121507219b1a79",
"type": "function",
"z": "23541210a65ebc7a",
"name": "Output Status",
"func": "var reply = msg.payload.split(\"+\");\nmsg.reply=reply;\n\n// msg.output=[];\nvar output1={};\nvar output2={};\nvar output3={};\nvar output4={};\nvar all={};\n// \noutput1.payload = reply[1].substr(0,1);\noutput2.payload = reply[1].substr(1,1);\noutput3.payload = reply[1].substr(2,1);\noutput4.payload = reply[1].substr(3,1);\n\n\n \n all.payload=\"Different\";\n \n if (reply[1].substr(0,4) == \"1111\"){\n \n all.payload = \"1\";\n }\n if (reply[1].substr(0,4) == \"2222\"){\n \n all.payload = \"2\";\n }\n \n if (reply[1].substr(0,4) == \"3333\"){\n \n all.payload = \"3\";\n }\n \n if (reply[1].substr(0,4) == \"4444\"){\n \n all.payload = \"4\";\n }\n\n\nreturn [output1,output2,output3,output4,all,msg];",
"outputs": 6,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 780,
"y": 720,
"wires": [
[
"5f449a6202d566f5",
"7135ec9cb8249475"
],
[
"2c3a86643c3b2c52"
],
[
"a8b9057920ceb4b8"
],
[
"246dbe771eb0064a"
],
[
"39c655441c925e58",
"ef6bdabedff6ef99"
],
[
"6f8f505add0bccce"
]
],
"inputLabels": [
"Input"
],
"outputLabels": [
"Output 1",
"Output 2",
"Output 3",
"Output 4",
"All",
"Full Message"
]
},
{
"id": "882063cf4061880c",
"type": "link in",
"z": "23541210a65ebc7a",
"name": "Matrix Reply",
"links": [
"2155d466070d8262"
],
"x": 565,
"y": 720,
"wires": [
[
"d1121507219b1a79"
]
]
},
{
"id": "2155d466070d8262",
"type": "link out",
"z": "23541210a65ebc7a",
"name": "Maxtrix Reply",
"mode": "link",
"links": [
"882063cf4061880c"
],
"x": 1905,
"y": 440,
"wires": []
},
{
"id": "7135ec9cb8249475",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "Output 1 State",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload",
"statusType": "msg",
"x": 880,
"y": 620,
"wires": []
},
{
"id": "dd0844b93cfb629d",
"type": "function",
"z": "23541210a65ebc7a",
"name": "Send Multiple 1&2",
"func": "var Input = msg.payload;\n\nmsg.topic= \"2\";\nnode.send (msg);\n\n\nmsg.topic= \"1\";\nnode.send (msg);\n\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1090,
"y": 500,
"wires": [
[
"da792723feed5aa8",
"948becdfc39aca47",
"29c2edd93e598f6e"
]
]
},
{
"id": "da792723feed5aa8",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "Multiple test",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1390,
"y": 400,
"wires": []
},
{
"id": "29c2edd93e598f6e",
"type": "delay",
"z": "23541210a65ebc7a",
"name": "",
"pauseType": "delay",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 1080,
"y": 340,
"wires": [
[
"fe36322ca4b78102"
]
]
},
{
"id": "e1076934197c047e",
"type": "inject",
"z": "23541210a65ebc7a",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "Different",
"payloadType": "str",
"x": 800,
"y": 860,
"wires": [
[
"39c655441c925e58"
]
]
},
{
"id": "ef6bdabedff6ef99",
"type": "debug",
"z": "23541210a65ebc7a",
"name": "All State",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "payload",
"statusType": "msg",
"x": 1020,
"y": 1040,
"wires": []
},
{
"id": "2b07c409543b5ee3",
"type": "serial request",
"z": "23541210a65ebc7a",
"d": true,
"name": "Serial Connection",
"serial": "8f50de74974f9fdc",
"x": 1730,
"y": 420,
"wires": [
[
"2155d466070d8262"
]
]
},
{
"id": "77e3cc083ba4d960",
"type": "comment",
"z": "23541210a65ebc7a",
"name": "Configure connection",
"info": "Enable whichever type of connection to are using to the Matrix",
"x": 1720,
"y": 380,
"wires": []
},
{
"id": "036dd1c88da526c7",
"type": "ui_group",
"name": "Matrix Switcher",
"tab": "d1ca25f397e68b43",
"order": 1,
"disp": true,
"width": "6",
"collapse": true,
"className": ""
},
{
"id": "8f50de74974f9fdc",
"type": "serial-port",
"serialport": "/dev/ttyUSB0",
"serialbaud": "9600",
"databits": "8",
"parity": "none",
"stopbits": "1",
"waitfor": "",
"dtr": "none",
"rts": "none",
"cts": "none",
"dsr": "none",
"newline": "\\n",
"bin": "bin",
"out": "char",
"addchar": "",
"responsetimeout": "10000"
},
{
"id": "d1ca25f397e68b43",
"type": "ui_tab",
"name": "4X4 Matrix",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]
Details of the commands that are being used are in the Tab description.