TCP Device Core / UDP Device Core

The TCP Device Core for Blue Pill, core-protocol-tcp, allows users to send and to some extend receive and process information of TCP to both ASCII and binary servers. Effectively, this can help to bridge communication with devices where a dedicated device core is not available.

The UDP Device Core for Blue Pill, core-protocol-udp, enables the exact same functionality as for TCP, just over a UDP connection.

This page describes how both device cores work, but using core-protocol-tcp as the example. The device cores have both a very basic mode and some more complex features that can come in handy in some cases. It has been designed to align with the corresponding TCP Client device core on the UniSketch platform.

Commands

The commands you can specify and send are ASCII by default and exactly what you see in the string will be sent as ASCII, unless:

Floating point

Inserting a floating point number with \f is based on the parameter p1-p3 being an integer which gets divided by the [scale] number. For example, if you insert \f2/10 then if meta value parameter p2 is a variable with the value 55, it will get formatted as "5.5" in the message.

Example

Say you want to send a command to fire DMEMs on GVG100, in that case you want to send the text string “03 01 DB 00” to fire DMEM 01, send “03 01 DB 01” to fire DMEM 02 etc.
So setting up a command like “03 01 DB \h1” and then using the “p1” meta value through a constant in Reactor would allow you to distribute the same behavior across multiple hardware components on a panel but vary the Dmem value easily.

Testing and tools

An advice is to use the "ipserver" binary tool provided by SKAARHOJ to set up a server to help testing the functionality until you are confident that everything works as expected and would function with the final target device.

Basic Configuration

The device core has some configuration fields:

image.png

Cowboy Style

The most straight forward way to use the device core would be to send one-shot triggers cowboystyle. This requires the minimum of configuration but provides the least amount of long term convenience. This is probably a good place to get started.

image.png

Command Configuration

The device core allows you to configure a number of fixed commands. The advantage is that you can bundle an A and B command into a single action for toggles etc. Also, this is the way you can use meta values with the \p1,\p2, ... placeholders etc. Finally, it's actually possible to decode some level of status back from the returned content of the device via a regular expressing.

image.png

The commands configured here will be available through these parameters in the device core:

image.png

Examples

Forwarding the position of a fader, 0-1000

Forwarding the position value of a fader requires us to use the "\i" placeholder to insert a dynamic value. The code below demonstrates a behavior called "VolumeFader" that is assumed to control volume on a given channel on a device by sending text strings like "CHx_Vol_n", where x is the channel number and n is the volume. In this case, we assume the device will access the value range of n to go from 0 to 1000 so that it's 1:1 compatible with a Raw Panel fader position value.

        "VolumeFader": {
            "ConstantDefinitions": {
                "Channel": {
                    "Description": "Channel",
                    "Type": "Integer"
                },
                "DeviceId": {
                    "Description": "Device Id",
                    "Type": "Integer"
                }
            },
            "EventHandlers": {
                "trigger": {
                    "AcceptTrigger": "Binary",
                    "EventPreProc": {
                        "A2B": {
                            "InputMapping": {
                                "Default": {
                                    "Threshold": 2,
                                    "RepeatThresholds": true,
                                    "OutputTriggerRising": "ActDown",
                                    "OutputTriggerFalling": "ActDown"
                                }
                            }
                        }
                    },
                    "IOReference": {
                        "Raw": "DC:protocol-tcp/{Behavior:Const:DeviceId}/cowboystyle/",
                        "MetaValues": {
                            "command": "CH\\d1_Vol_\\i2",
                            "p1": "Behavior:Const:Channel",
                            "p2": "Behavior:LastEvent/Analog:Value"
                        }
                    }
                }
            }
        }

Description:

Forwarding the position of a fader, arbitrary interval

Forwarding the position value of a fader in a different range is more trouble, but can be done. We will use a behavior variable for that. This is a variable only available in the scope of the behavior definition.

        "VolumeFader": {
            "ParentID": "SKAARHOJ:FaderMotorized",
            "Variables": {
                "FaderValue": {
                    "Name": "Volume",
                    "MinMaxCenterValue": [
                        0,
                        100
                    ],
                    "DefaultToFirst": true
                }
            },
            "ConstantDefinitions": {
                "Channel": {
                    "Description": "Channel",
                    "Type": "Integer"
                },
                "DeviceId": {
                    "Description": "Device Id",
                    "Type": "Integer"
                }
            },
            "IOReference": {
                "Raw": "Var:FaderValue"
            },
            "EventHandlers": {
                "forward": {
                    "AcceptTrigger": "Binary",
                    "EventPreProc": {
                        "A2B": {
                            "InputMapping": {
                                "Default": {
                                    "Threshold": 2,
                                    "RepeatThresholds": true,
                                    "OutputTriggerRising": "ActDown",
                                    "OutputTriggerFalling": "ActDown"
                                }
                            }
                        }
                    },
                    "IOReference": {
                        "Raw": "DC:protocol-tcp/{Behavior:Const:DeviceId}/cowboystyle/",
                        "MetaValues": {
                            "command": "CH\\d1_Vol_\\d2",
                            "p1": "Behavior:Const:Channel",
                            "p2": "Var:FaderValue"
                        }
                    }
                }
            }
        },

Description:

Sending TCP commands with an encoder

This examples shows how to program an encoder to send a different command whether you turn it clockwise or counterclockwise. It's build over the same idea as in the previous examples where the behavior is design for use as a Master Behavior, using a constant definition for the channel and Device ID.

        "VolumeUpDown": {
            "Description": "QSYS Volume Up/Down for Encoders/4Ways",
            "ConstantDefinitions": {
                "Channel": {
                    "Description": "Channel",
                    "Type": "Integer"
                },
                "DeviceId": {
                    "Description": "Device Id",
                    "Type": "Integer"
                }
            },
            "IOReference": {},
            "EventHandlers": {
                "down": {
                    "AcceptTrigger": "Binary",
                    "EventPreProc": {
                        "P2B": {
                            "InputPolarity": {
                                "Default": {},
                                "Negative": {
                                    "OutputTrigger": "ActDown",
                                    "OutputEdge": "Left"
                                }
                            },
                            "SpeedmodeConfig": {}
                        }
                    },
                    "BinaryEdgeFilter": "Left",
                    "BinarySetValues": {},
                    "IOReference": {
                        "Raw": "DC:protocol-tcp/{Behavior:Const:DeviceId}/cowboystyle/",
                        "MetaValues": {
                            "command": "CH\\d1_Down",
                            "p1": "Behavior:Const:Channel"
                        }
                    }
                },
                "up": {
                    "AcceptTrigger": "Binary",
                    "EventPreProc": {
                        "P2B": {
                            "InputPolarity": {
                                "Default": {},
                                "Positive": {
                                    "OutputTrigger": "ActDown",
                                    "OutputEdge": "Right"
                                }
                            },
                            "SpeedmodeConfig": {}
                        }
                    },
                    "BinaryEdgeFilter": "Right",
                    "BinarySetValues": {},
                    "IOReference": {
                        "Raw": "DC:protocol-tcp/{Behavior:Const:DeviceId}/cowboystyle/",
                        "MetaValues": {
                            "command": "CH\\d1_Up",
                            "p1": "Behavior:Const:Channel"
                        }
                    }
                }
            },
            "FeedbackDefault": {
                "DisplayText": {
                    "Title": "Ch. {Behavior:Const:Channel} Volume",
                    "Textline1": "Up/Down"
                },
                "Intensity": "Dimmed"
            },
            "FeedbackConditional": {
                "10": {
                    "ActiveIf": "Behavior:Events/trigger:TimeToNow \u003c 300",
                    "Intensity": "On"
                }
            }
        }

Description:



Revision #7
Created 25 October 2022 10:54:04 by Kasper
Updated 8 January 2025 08:30:40 by Kasper