RS232 / LAN control of 4X4 4K HDMI Matrix switcher

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)

image

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)

image

[
    {
        "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.

3 Likes

That is a nice KVM.

1 Like