Tesira Text Protocol
Tesira's subscription feature allows for an automatic response to be sent from a Tesira server when a state change occurs to a specified DSP block. This allows a control system to be aware of the system status at all times without needing to continuously query DSP blocks for their values.
The state or the value of the DSP block will be returned when a subscription is first created. After this initial response, subsequent messaging is suppressed until such time as the state of that block changes. Multiple subscriptions can be defined within a single Tesira system, and therefore a user-defined Custom Label should be assigned to each one. The Custom Label will then act as a unique identifier for the DSP block providing the data updates.
Refer here for the list of DSP Blocks and attributes that support the TTP Subscription service.
The Tesira Command String Calculator is a great tool, allowing copy and paste of generated strings. This helps in avoiding simple formatting errors.
Sessions
TTP can be used over Secure Shell (SSH), Telnet or RS-232 Serial connections. Multiple sessions to a single server can be created, however, subscriptions are session based, meaning that the subscription will only be available to the session that initiated it. If that session goes away or is disconnected, then the subscription is lost and must be re-established.
Command formatting
Instance Tag | Command | Attribute | Index | Index | Value |
MyLevel1 | subscribe | level | 1 | MyLevelCustomLabel | 500 |
Instance Tag: Identifies the DSP block to monitor for state changes. The Instance Tag is case sensitive and is the unique name of a software object used in a Tesira project.
Command: Will either be ‘subscribe’ or ‘unsubscribe’ depending whether the Subscription is being added or removed
Attribute: Addresses the specific element to subscribe to within the DSP block being monitored
[Index]: Indicates the desired channel number to subscribe to within the DSP block being monitored. A value here may or may not be required, depending on the DSP block type and attribute being referenced
[Index]: Is used to assign a Custom Label to the subscription. The label indicates to the control system which DSP block is providing the state change
[Value]: Can be used to specify a minimum rate of responses to the control system so the control processor does not get overrun. This value is specified in milliseconds and should be used especially for DSP blocks that generate a lot of data, for example an RMS or Peak Meter. A subscription update will be provided immediately after a state change, however subsequent updates will never be provided more frequently than this number of milliseconds. This value is optional and can be left out if not needed.
Responses
In addition to the subscribe and unsubscribe commands, get, set, increment, decrement, and toggle are supported by many blocks.
The Tesira Command String Calculator is a valuable resource, allowing cut and paste of the generated strings. This helps in avoiding simple formatting errors.
Expected responses
For simple TTP set commands Tesira will return a +OK message.
Level3 set level 2 0
+OK
Get commands illicit a response.
Level3 get level 2
+OK "value":0.000000
-ERR responses
If there is a missing or incorrect part of the string sent in the TTP command Tesira will return an error message. The message will typically indicate where in the string the fault was found, or which parameter is invalid. The invalid parameter message can be daunting at first but is generally a straight-forward issue to resolve.
Common errors are missing or added spaces between terms, instance tag mismatch, or the specified control value is not valid for the control object (e.g. - trying to control channel 3 in a 2 channel level control block, or trying to set a level control to +20 when the max limit is +12)
level3 set mute 3 true
-ERR address not found: {"deviceId":0 "classCode":0 "instanceNum":0}
Verify that the instance tag is correct. You can send the query "SESSION get aliases" to return a list of get a listing of available Instance Tags via TTP or check the Tesira configuration file. Here we can see that the name "level3" was incorrect, "Level3" was correct - capitalization and spaces matter in TTP commands.
SESSION get aliases
+OK "list":["AecInput1" "AudioMeter2" "AudioMeter4" "DEVICE" "DanteInput1" "DanteOutput1" "Level1" "Level2" "Level3" "Mixer1" "NoiseGenerator1" "Output1" "Router1" "ToneGenerator1" "ToneGenerator2" "USBInput1" "USBOutput1"]
Here the instance tag is correct but the channel index value is not valid. 1 or 2 would be legal.
Level3 set mute 3 true
-ERR INVALID_PARAMETER Index out of range:channelIndex min:1 max:2 received:3
In a ganged level or mute control block the channel ID is 0, but for an un-ganged block the channel number of interest must be used. Here 0 is used in an un-ganged level control block. The correct channel index value must be used. 1 or 2 would be legal.
Level3 set mute 0 true
-ERR INVALID_PARAMETER Index out of range:channelIndex min:1 max:2 received:0
All control commands required by the TTP string must be sent
Level3 set mute
-ERR Parse error at 15: not enough parameters supplied
Correct formatting is important, leaving out a space where one is required will generate a fault.
Level3 set level1 1
-ERR 'level1' is not supported by LevelControlInterface::
Attributes
Subscription responses
All Subscription responses are preceded by a ! “publishToken” statement when using TTP in Verbose Mode (default mode) *. This is to indicate to the control system that the returned packet is from a subscription response, not just a reply to a singular command. Using the TTP subscription example command above, the responses would look like this:
MyLevel1 subscribe level 1 MyCustomLabel 500
! “publishToken”:”MyLevelCustomLabel” “value”:-100.000000
! “publishToken”:”MyLevelCustomLabel” “value”:-98.099998
! “publishToken”:”MyLevelCustomLabel” “value”:-77.800003
The responses above show the subscription to a single channel. If a multi-channel DSP object is used, by changing the attribute field, multiple channels can be made to report within one response. Note that this example subscribes to the "levels" parameter rather than the "level" parameter.
MyLevel1 subscribe levels MyCustomLabel 500
! “publishToken”:”MyLevelCustomLabel” “value”:[-100.000000 0.000000 4.000000 -12.000000]
! “publishToken”:”MyLevelCustomLabel” “value”:[ -98.099998 0.000000 4.000000 -12.000000]
! “publishToken”:”MyLevelCustomLabel” “value”:[ -77.800003 0.000000 4.000000 -12.000000]
Subscriptions are lost when the Tesira server is rebooted however they can be recreated by subscribing to the same block at regular intervals. Ensure that the same Custom Label is used in the re-subscription otherwise multiple sessions to the same object may be inadvertently opened. Consideration should be given to buffer sizes to make sure all of the subscribed responses can be processed by the control system. If a Subscription is no longer needed an ‘unsubscribe’ command can be issued to reduce the load on the control processor.
* If non-verbose responses are required, the mode should be changed before any subscriptions are made. The response type for each subscription is fixed according to the mode that was active at the time the subscription was made.
Examples
Camera tracking example
Instance Tag | Command | Attribute | Index | Index | Value |
LogicMeter1 | subscribe | state | 1 | LogicStateCH1 | 600 |
LogicMeter1 | subscribe | state | 2 | LogicStateCH2 | 600 |
1 | Welcome to the Tesira Text Protocol Server... |
2 | |
3 | LogicMeter1 subscribe state 1 LogicStateCH1 600 |
4 | ! "publishToken":"LogicStateCH1" "value":false +OK |
5 | |
6 | LogicMeter1 subscribe state 2 LogicStateCH2 600 |
7 | ! "publishToken":"LogicStateCH2" "value":false +OK |
8 | |
9 | ! "publishToken":"LogicStateCH1" "value":true |
10 | ! "publishToken":"LogicStateCH1" "value":false |
11 | ! "publishToken":"LogicStateCH2" "value":true |
12 | ! "publishToken":"LogicStateCH1" "value":true |
13 | ! "publishToken":"LogicStateCH1" "value":false |
14 | ! "publishToken":"LogicStateCH1" "value":true |
15 | ! "publishToken":"LogicStateCH1" "value":true |
16 | ! "publishToken":"LogicStateCH2" "value":false |
Monitoring level changes example
Instance Tag | Command | Attribute | Index | Index | Value |
Level4CH | subscribe | level | 1 | MyLevel4CH1 | 500 |
Level4CH | subscribe | levels | <not required> | MyLevel4ALL | 500 |
1 | Welcome to the Tesira Text Protocol Server... |
2 | |
3 | Level4CH subscribe level 1 MyLevel4CH1 500 |
4 | ! "publishToken":"MyLevel4CH1" "value":6.000000 +OK |
5 | |
6 | ! "publishToken":"MyLevel4CH1" "value":3.300000 |
7 | ! "publishToken":"MyLevel4CH1" "value":4.300000 |
8 | ! "publishToken":"MyLevel4CH1" "value":5.200000 |
9 | ! "publishToken":"MyLevel4CH1" "value":5.700000 |
10 | |
11 | Level4CH subscribe levels MyLevel4ALL 500 |
12 | ! "publishToken":"MyLevel4ALL" "value":[5.200000 3.000000 -10.000000 -70.000000] +OK |
13 | |
14 | ! "publishToken":"MyLevel4ALL" "value":[5.200000 3.000000 -10.000000 -60.000000] |
15 | ! "publishToken":"MyLevel4ALL" "value":[5.200000 3.000000 -5.000000 -60.000000] |
16 | ! "publishToken":"MyLevel4ALL" "value":[5.200000 3.000000 -3.000000 -60.000000] |
Meter subscription example
Instance Tag | Command | Attribute | Index | Index | Value |
AudioMeter11 | subscribe | level | 1 | MeterCH1 | 500 |
1 | Welcome to the Tesira Text Protocol Server... |
2 | |
3 | AudioMeter11 subscribe level 1 MeterCH1 500 |
4 | ! "publishToken":"MeterCH1" "value":-79.996880 +OK |
5 | |
6 | ! "publishToken":"MeterCH1" "value":-79.996857 |
7 | ! "publishToken":"MeterCH1" "value":-81.009888 |
8 | ! "publishToken":"MeterCH1" "value":-83.010132 |
9 | ! "publishToken":"MeterCH1" "value":-78.010574 |
10 | ! "publishToken":"MeterCH1" "value":-56.011780 |
11 | ! "publishToken":"MeterCH1" "value":-47.022346 |
12 | ! "publishToken":"MeterCH1" "value":-43.021805 |
Call Progress for telephone interfaces example
Instance Tag | Command | Attribute | Index | Index | Value |
VoIPControlStatus1 | subscribe | callState | <not required> | VoIP_PHL1 | 1500 |
1 | Welcome to the Tesira Text Protocol Server... |
2 | |
3 | VoIPControlStatus1 subscribe callState VoIP_PHL1 1500 |
4 | ! "publishToken":" VoIP_PHL1" "value":{"callStateInfo":[{"state":VOIP_CALL_STATE_RINGBACK "lineId":0 "callId":0 "action":UI_DISPLAY_STATUS "cid":"\"07131038\"\"146\"\"\"" "prompt":VOIP_PROMPT_CONNECTING} {"state":VOIP_CALL_STATE_IDLE "lineId":0 "callId":1 "action": UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_NONE} {"state":VOIP_CALL_STATE_IDLE "lineId":0 "callId":2 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_NONE} {"state":VOIP_CALL_STATE_IDLE "lineId":0 "callId":3 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_NONE} {"state":VOIP_CALL_STATE_IDLE "lineId":0 "callId":4 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_NONE} {"state":VOIP_CALL_STATE_IDLE "lineId":0 "callId":5 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_NONE} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":0 "action":UI_DISPLAY_STATUS "cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":1 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":2 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":3 "action":UI_CLEAR_STATUS"cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":4 "action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED} {"state":VOIP_CALL_STATE_INIT "lineId":1 "callId":5"action":UI_CLEAR_STATUS "cid":"" "prompt":VOIP_PROMPT_SIP_USER_NOT_CONFIGURED}]} +OK |