Use the Block Controller component to easily declare one or more controls and their connections, and then build the Lua script associated with those controls using a visual block interface.
After you configure your controls and connections in the elements configurator, you can then build your configuration using a visual programming tool that uses interlocking graphical blocks to represent common code programming concepts including logical expressions and loops. Rapid code creation and editing allows you to compose simple or sophisticated AV scripts while ensuring that the generated code is always syntactically correct.
The underlying script interacts with components through their control pins. You can write scripts to control elements entirely within the Q-SYS Designer file, or you can use it to interface Q-SYS with third-party hardware accessible via TCP, UDP or Serial.
Note: This component uses the Q-SYS Scripting Engine, which is a licensed feature on certain Cores manufactured with Q-SYS 7.0 and later. For more information, see Licensing.
Double-click the Block Controller component to open the elements editor, which is where you define controls for your block configuration. After defining your controls, click Edit to open the Blocks editor.
Control |
Function |
---|---|
Controls |
Click to add a new control to the list, and then configure its properties. See See Controls Properties. |
Connections |
Click to add a new connection to the list, and then configure its properties. See See Connections Properties. |
Property |
Function |
Choices |
---|---|---|
General |
||
Name |
Specify a name for the input. |
Text input |
Count |
Specify the number of controls of the specified type to create. |
1 to 256 |
Control Type |
||
Category |
Button
Select a Push Action:
Knob
Specify a Max Value and Min Value for the specified Units:dB, Hz, Float, Integer, Pan, Percent, Position, Seconds. Indicator
Specify a Type: LED, Meter, Text, Status. Text
Specify a Type: Text Box, Combo Box, List Box |
Button, Knob, Indicator, Text |
Control Pin |
Expose pins for these controls: None, Input (pins on the left), Output (pins on the right), or Both. |
None, Input, Output, Both |
Property |
Function |
Choices |
---|---|---|
Name |
Specify a name for the connection and its controls. |
Text input |
Type |
Specify how to communicate with the external device: TCP
Expose IP Address, Port, and Status pins for these controls: None, Input (pins on the left), Output (pins on the right), or Both.
UDP
Expose IP Address, Port, and Status pins for these controls: None, Input (pins on the left), Output (pins on the right), or Both. Serial
Expose Baud Rate, Bits, Parity, and Status pins for these controls: None, Input (pins on the left), Output (pins on the right), or Both. Note that this will expose a serial control pin that needs to be wired to a matching pin on the component that represents the hardware.
SSH
Expose IP Address, Port, Status, User Name, and Password pins for these controls: None, Input (pins on the left), Output (pins on the right), or Both.
|
TCP, UDP, Serial, SSH |
After configuring your controls and connections, click Edit to open the Blocks editor (Blocks tab). Controls and connections are presented as graphical blocks that you can drag into the script and configure with values and statements.
For examples of creating controls using the visual block interface, see Block Examples. To modify your script in a traditional script editor, see See Using the Script Editor.
To edit the script using a text-based editor, click the button and select Convert to Script.
WARNING: When you switch to the text-based editor, the editor is initially populated with the Lua script generated from the Block editor. If you later switch back to the Block editor ( > Revert to Blocks), your text editor changes are lost. Any text-based script you enter is overwritten by text generated by the Block editor.
The script editor contains three areas:
Tip: While in the Script area, press F1 for help on the Lua scripting language.
The available Control Pins depend on settings in Properties.
Pin Name |
Value |
String |
Position |
Pins Available |
---|---|---|---|---|
Code |
(text) |
Input / Output |
||
Script Start |
(trigger) |
Input / Output |
||
Script Status |
(text) |
Output |
||
Script Stop |
(trigger) |
Input / Output |
This section demonstrates how you can create controls using the visual block interface, which then generates the underlying Lua script. Refer to the Q-SYS Control Scripting topic for information on Lua scripting.
Serial port communication is supported via the RS-232 ports on some Q-SYS devices. To create a connection:
In this example, a trigger button is used to send data (entered in a text box) through the serial port on a Core 110f. For more information on serial port connections, and to see an example of the Lua script used to create this example, see SerialPorts.
Double-click the Block Controller component to open the elements editor. In this example, two controls and one connection are defined.
Tip: You can drag individual control and connection components into your schematic or copy them to the User Control Interface editor.
Click Edit to open the Blocks editor. Define the controller configuration using the available blocks in the left menu. The Controls and Connections categories contain the elements defined in the elements editor.
In this example, there are four groups of blocks that do the following:
Blocks | Script Equivalent |
---|---|
Controls['send'].EventHandler = function() local tx = Controls['data'].String tx = tostring(Controls['data'].String) .. tostring('\r') sp:Write(tx) print(tostring('sending data out to serial port ') .. tostring(Controls['data'].String)) end |
|
spStatusConnectedFunctions['W20|n-~B=8xbb@M)EUz]'] = function() print('serial port connected') print(tostring('baudrate ') .. tostring(Controls['sp.Baud_Rate'].String)) print(tostring('databits ') .. tostring(Controls['sp.Data_Bits'].String)) print(tostring('parity ') .. tostring(Controls['sp.Parity'].String)) end |
|
spStatusClosedFunctions['ik3z-W^jqC}cB9g*Vt!9'] = function(error_message) print('serial port disconnected') end |
|
sp.Data = function() message = sp:ReadLine(SerialPorts.EOL.Any) while (message ~= nil) do print(tostring('read line ') .. tostring(message)) message = sp:ReadLine(SerialPorts.EOL.Any) end end |
The Block Controller automatically produces script for handling the setting of baud rate, data bits, and parity. When you emulate or save and run your design to the Core, open the Block Controller control panel to set baud rate, data bits, and parity using the drop-down menus.
The TcpSocket object allows Q-SYS cores to make client TCP/IP connections to devices on the network. In this example, a trigger button is used to send data entered in a text box to a TCP device with a specified IP address and port number. For more information, and to see an example of the Lua script used to create this example, see TcpSocket.
Double-click the Block Controller component to open the elements editor. In this example, two controls and one connection are defined.
Tip: You can drag individual control and connection components into your schematic or copy them to the User Control Interface editor.
Click Edit to open the Blocks editor. Define the controller configuration using the available blocks in the left menu. The Controls and Connections categories contain the elements defined in the elements editor.
Blocks | Script Equivalent |
---|---|
sendData = 'Hello\x0d\x0a' |
|
sockStatusConnectedFunctions['rq{I?iu_o,WJQo?H:W2X'] = function() print('socket connected') end |
|
sockStatusClosedFunctions['jArNCFTp,o|3t(#/z?sc'] = function(error_message) print('TCP socket was closed by the remote end') end |
|
sock.Data = function() message = sock:ReadLine(TcpSocket.EOL.Any) while (message ~= nil) do print(tostring('TCP socket has data:\t') .. tostring(message)) message = sock:ReadLine(TcpSocket.EOL.Any) end end |
|
Controls['Trigger button'].EventHandler = function() -- A comment for this block sock:Write(sendData) print('sending data') end |
Use SSH to create secure client connections to devices on the network. It is very similar to creating a TCP socket, but requires additional connection arguments (host, port, user, password). For information about creating SSH connections in Lua, see Ssh.
In this example, an SSH connection is configured that:
Double-click the Block Controller component to open the elements editor. In this example, a new SSH connection is defined. Controls are available for IP Address, Port, UserName, Password, and Status, which can be dragged into your design.
Click Edit to open the Blocks editor. Define the controller configuration using the available blocks in the left menu. The Connections category contains the elements for the SSH connection.
Blocks | Script Equivalent |
---|---|
timer0 = Timer.New() |
|
SSH_Connection.Connected = function() timer0:Start(10) end |
|
timer0.EventHandler = function() SSH_Connection:Write('date\n') end |
|
SSH_Connection.Data = function() message = SSH_Connection:ReadLine(TcpSocket.EOL.Any) while (message ~= nil) do print(message) message = SSH_Connection:ReadLine(TcpSocket.EOL.Any) end end |
|
SSH_Connection.LoginFailed = function() print("Wrong password!") end |
Run or emulate your design. In the SSH connection controls, set the host/IP address, port, username, and password. Block Controller automatically attempts to connect with the provided parameters.
The Timer object is used to create delays or trigger events after a defined elapsed time. It should be used instead of Lua's native delay and time functions. For more information, and to see an example of the Lua script used to create this example, see System.
Blocks | Script Equivalent |
---|---|
timer1 = Timer.New() timer2 = Timer.New() timer_1 = 'timer1!' timer_2 = 'timer2' timer = 'timer2' |
|
function timerFunc() if timer == timer_1 then print(timer_1) elseif timer == timer_2 then print(timer_2) end end |
|
timer1.EventHandler = function() timer = timer_1 timerFunc() end |
|
timer2.EventHandler = function() timer = timer_2 timerFunc() end |
|
timer1:Start(1) timer2:Start(2) |
Use the after time block to create a single event or a series of events that execute after a specified period of seconds. Unlike a standard timer, this block only fires once.
To add more events to execute, click the gear icon and drag the then after time block under the after time block.
In this example, a series of debug print strings executes in three timed steps.
Blocks | Script Equivalent |
---|---|
Timer.CallAfter(function() print('This') Timer.CallAfter(function() print('is') Timer.CallAfter(function() print('Q-SYS') print(Qlib.version().Version) end,5) end,3) end,2) |
This is Q-SYS 7.1.0.27
This example shows how you can use the Block Controller component to create multiple controls (trigger buttons) and then use those controls in a user control interface with layer transitions.
This example UCI allows the user to push one of six buttons to either show a Q-SYS product category image or remove the current image and show the Q-SYS logo:
There are three overall steps to creating this UCI:
Double-click the Block Controller component to open the elements editor. In this example, six controls are defined - each for displaying a different Q-SYS product image (Control Type = Button; Button Type = Trigger).
Note: For information on creating UCIs, see User Control Interfaces.
Now, you will have a UCI with one page ("Page 1") containing seven layers:
Finally, use the Blocks editor to define the UCI functionality.
In this example, there are three groups of blocks that do the following:
Note: For information about the UCI Lua functions used behind the scenes in this example, see Uci.
Blocks | Script Equivalent |
---|---|
function clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'cores', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'network', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'conference', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'touchscreen', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'amplifiers', false, 'fade') end |
|
clear() |
|
Controls['cores'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'cores', true, 'left') end Controls['network'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'network', true, 'right') end Controls['conference'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'conference', true, 'bottom') end Controls['touchscreens'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'touchscreen', true, 'top') end Controls['amplifiers'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', false, 'fade') Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'amplifiers', true, '') end Controls['logo'].EventHandler = function() clear() Uci.SetLayerVisibility('Q-SYS', 'Page 1', 'logo', true, 'fade') end |
In this example, a UCI contains two pages with distinct graphics. Two shared layers – one for a Toggle Time control and another for a time display – are used on each page. When the Toggle Time button is pushed, the time display is therefore shown or hidden on both pages.
Note: For information about adding a date/time text box to your UCI, see Date/Time.
In this example, one control is defined (Category = Button; Push Action = Toggle). The button is configured in the visual Blocks editor to turn on/off the shared layer containing the time display.
This simple UCI (named "MyUCI") contains two pages, each with a different QSC graphic. Two shared layers - one for the Toggle Time control ("ToggleTime") and the other for the time display ("Time") - are also included on each page. For information about creating shared layers, see Working with Layers.
Use the Blocks editor (accessible via the Edit button) to define what happens when the Toggle Time button is pushed: Show or hide the Time shared layer across any page that includes that shared layer, and with a specified transition type. This example uses blocks from the Flow Control, Operators, System, and Controls categories.
Note: For information about the UCI Lua functions used behind the scenes in this example, see Uci.
Blocks | Script Equivalent |
---|---|
Controls['Toggle Time'].EventHandler = function() if Controls['Toggle Time'].Boolean == true then Uci.SetSharedLayerVisibility('MyUCI', 'Time', true, 'fade') elseif Controls['Toggle Time'].Boolean == false then Uci.SetSharedLayerVisibility('MyUCI', 'Time', false, 'fade') end end |
In this example, whenever the Start_Loop button is pushed, two "for loop" blocks start a countdown - one to 10, and one from 10.
Blocks | Script Equivalent |
---|---|
Controls['Start_Loop'].EventHandler = function() local output = '' for index = 1, 10, 1 do output = tostring(output) .. tostring((tostring('-') .. tostring(index))) end print('Count to 10') print(output) output = '' for index = 10, 1, -1 do output = tostring(output) .. tostring((tostring('-') .. tostring(index))) end print('Count from 10') print(output) end |
Count to 10 -1-2-3-4-5-6-7-8-9-10 Count from 10 -10-9-8-7-6-5-4-3-2-1
In this example, a trigger button control (MyControl) changes color depending on whether a condition is met.
Blocks | Script Equivalent |
---|---|
if 5 * 2 == 10 then Controls['MyControl']:Trigger() Controls['MyControl'].Color = '#33ff33' else Controls['MyControl']:Trigger() Controls['MyControl'].Color = '#ff0000' end |
When your design contains Named Controls, blocks for these controls become available in the block editor from a Named Controls drop-down menu:
In the following example, a timeline (after time) block is configured to trigger playback and set control values in a timed sequence for four named controls from an Audio Player component.
Note: For more information about timelines, see Creating a Timeline. For information about referencing named controls in Lua script, see NamedControl.
Blocks | Script Equivalent |
---|---|
Timer.CallAfter(function() NamedControl.Trigger('AudioPlayerPlay') print('Playback started') Timer.CallAfter(function() NamedControl.SetPosition('AudioPlayerGain', 0.75) print('Gain reduced') Timer.CallAfter(function() NamedControl.SetValue('AudioPlayerMute', 1) print('Playback muted') Timer.CallAfter(function() NamedControl.SetValue('AudioPlayerMute', 0) print('Playback unmuted') Timer.CallAfter(function() NamedControl.Trigger('AudioPlayerStop') print('Playback stopped') end,5) end,5) end,5) end,15) end,5) |
For further explanation of the Block Controller component, see the following videos:
Learn the basic Q-SYS third party control principles, including Lua scripting basics.
Learn about the Block Controller component through a navigational overview. In this lesson, you'll learn how to manipulate a simple button control using blocks.
Learn about sections of the Block Controller, including control change, flow control, if statements, operators, boolean values, and converting blocks to lua script.
Software and Firmware | Resources | QSC Self Help Portal | Q-SYS Help Feedback
Copyright © 2019 QSC, LLC. Click here for trademark and other legal notices. |