Reactor™ - The manual
SKAARHOJ Reactor™ is a powerful broadcast control application running on Blue Pill Servers and Blue Pill Inside-Products. Using Reactor you can
- do basic things like controlling your ATEM switchers, video routers and PTZ cameras etc.
- more advanced things like create powerful macros, that automatically start several Hyperdecks or position multiple PTZ cameras
- highly custom things like protocol translation
We aim to make common tasks and use cases intuitive and quick, but we also believe it's reasonable to expect users to invest time in learning to master our technology to fully utilize its advanced features. It's that balance that allows us to provide the entire spectrum in one package.
This manual aims to document most of the features available in Reactor. It will focus on helping you understand the basic primitives and concepts that make up the world of Reactor, help you master them, and serve you as a reference to a variety of topics.
Other useful information
The main changelog of Reactor and other SKAARHOJ software can be found on devices.skaarhoj.com
Be sure to also check out out YouTube channel, with videos on many topics regarding our products
For example our Blue Pill - Basic Training Series
Other Infos can be found on our Website
Manual Version: online
Basics
In this chapter, we will provide a brief overview of the main areas of Reactor and the Blue Pill device's web UI.
We will cover:
The Home Screen
When you first open your Blue Pill product, you will see the so-called 'Home Screen.'
-
Right below the navigation on the top you can see the current project name, and also edit it's details by clicking on the pen.
-
On the left side you can add and configure panels
-
On the right side you can add and configure devices
-
You can access and edit all Reactor projects by clicking Manage Projects or restart Reactor's engine by clicking on the green Running button
-
In the bottom (footer) you can (from left to right):
- open the view settings. These are saved in your browser.
- change reactors global text size
- check the status of remote support mode (active when support text is yellow)
- find a link to the tools page (toolbox icon)
Devices
This is where you can add all connections to other devices on the network that you want to control with Reactor. Simply click "Add Device" at the bottom to open the device browser. You will see a list of all devices Reactor discovers on the network, using mDNS or other mechanisms. If your device does not support these, you can also click "Add manually" at the top and select your device from the list.
Pressing shift while clicking "select" will not close the dialog and let you add multiple devices quicker
Panels
On this tab, you can add your panels. When working with a Blue Pill device, your panel should automatically appear when creating a new project.
Clicking on the panels name allows you to adjust its IP Address, name, brightness and sleep settings
After a panel is added, it will automatically select one of the available standard configurations. In many cases, these configurations are the generic SKAARHOJ default settings, allowing you to easily add devices from different manufacturers to your panel.
Below the selected configuration, you can see its configuration options. If the configuration includes a Camera Selector, you will also see which devices are already mapped to the controller, or you can add new ones. To configure the settings of your panel in more detail, click the blue name of the setting (e.g., Camera Selector, Switcher Inputs, Quick Class, etc.) to open them in a table.
Selecting Configurations for your Panels
Once you have added panels and devices, you need to select the preferred configuration for your panels. This is done using the dropdown menus. From here, you can choose one of the built-in default configurations or create a fully custom configuration by clicking "Create Custom Config" in the dropdown.
Using the small info icon, you can check additional details of your configuration, edit it in the JSON Editor, or delete/reset it to the system.
When creating custom configurations or modifying system configurations, you will see a small 'customized' indicator next to the configuration. Modifications are local to the current project.
To manage all available configurations, click "Manage Projects" and select "Manage Used Configs" at the top.
Panel Groups
Panels can be grouped to set shared brightness and sleep time, and to provide additional organization.
This feature is disabled by default. Open the View Options (cog wheel in the footer) and activate it.
Groups can be renamed and their settings adjusted. Panels can be moved between groups, and sleep settings and brightness can be managed for multiple panels at once.
Projects
Using Projects, you can save and switch out the entire setup you have configured in Reactor, including panels, devices, and all configurations.
To do so, open the Project Window from Reactor's Home Screen by clicking on Manage Projects.
Manage Projects
Here, you can see all projects saved on the controller.
- Use the buttons at the bottom to create new projects or import/export existing ones. Reactor Projects are stored as .rpj (Reactor Project Format) and can easily be imported on other controllers.
- You can use the search function to find your projects, or click the triangle icons next to the name or created columns to sort your projects.
- Click Activate to switch the currently active project in Reactor.
- Duplicating your project allows you to experiment with new configurations and revert to the previous state easily.
- Use the red trash can icon to delete your project.
- Click Manage Used Configs to view all sub-configurations that the current project includes (See Manage Included Configurations).
- Using the advanced toggle, you can show the components of your project. See below.
You can also switch the project from the controller using the System Behavior Change Reactor Project
Advanced Project View
Under the hood, a project in Reactor consists of three parts:
- A panel collection, containing info about panels
- A device collection, containing all your cores and devices
- A root layer configuration, containing the actual layers of the configuration
These files can also be shared between projects. This is useful when you have the same set of devices or panels in a studio but want to run different configurations on different days. While you can duplicate the full project, it might sometimes be more beneficial to create these shared setups. In the advanced view of the project dialog, you can view and change the underlying configurations for the individual parts of your projects.
Manage Included Configurations
While your project might have one root layer configuration, Reactor uses several files to build the layer tree required for your project (See The layer tree).
In this section, you can get a quick overview of all configurations currently used in your project's layer configuration. This might include system default configurations, customized system defaults, or custom configs that you have created yourself. You can quickly view information about them and even delete them from this view.
Example:
This configuration includes a PTZ Pro that uses:
- its default (Standard Class) configuration
- Additionally, a Canon Camera has been added
- The Frame Shot Pro has two custom configurations created for it, one of which is used, while the other is not.
Here you can see how the scenario looks on the Used Configurations page:
Several Canon-specific system default configurations are included automatically. The unused Frame Shot config (created by the user) shows up below.
The Configurator
The Configurator (also sometimes called "Configuration Tab") is the main place where you can make customizations to your controller layout.
There are 4 main areas:
-
Controller:
Here you can see and interact with your controller. Check the legend (blue question mark in the top right corner) for tips on navigating the canvas with your controllers. You can zoom in and out by scrolling and move by holding alt/option and dragging the mouse.
Press ctrl+e (or cmd+e on macOS) to toggle between "configuration mode" and "simulation mode".
-
Inspector:
Here you can see and adjust individual elements of the controller or the layer tree. The Inspector shows all properties of the currently selected object, such as a Component Behavior, Variable, or others.
Sometimes, you may be looking at a Behavior that cannot be seen on the controller due to a different layer covering it. In this case, the Inspector will give you a hint and allow you to switch to the Active Behavior currently visible.
-
Section Selector:
The section selector, located at the bottom of the controller, lets you choose which section of the panel you are currently editing. SKAARHOJ default configurations often allow you to simply edit pages of existing menus. You can select these pages by clicking on their names, or add, remove, and rename them as needed.
Using sections to customize the control panel is recommended for most users due to its simple paradigm of pages and shift levels.
-
Tree:
The tree is initially hidden. You can show it by clicking the small green icon in the top left corner of the controller view (⭕️ Red Circle in the screenshot above). In the tree view, you can see all configuration layers. Every project has one root layer, on which your configurations are added as sub-layers. These can also have their own sub-layers and include other layer files. Read more about this here: The tree.
Using the layer tree is recommended only if you're committed to learning more about the underlying technology in Reactor. The benefit is that, once understood, everything can be tweaked and modified without limits.
Reactor Configuration
In this chapter, we will dive into the details of controller configuration. We will explore the different components of a controller, the Layer Tree and its elements, and how they all work together.
We will cover the following topics:
- Components and Behaviors
- The Tree and its Layers
- Variables and Conditions
- The Parameter Reference (IOReference)
- Feedbacks and Actions
- Virtual Triggers
- Advanced Topics Note: This chapter will be added later 👷♀️
Hardware Components and Behaviors
What is a Hardware Component (HWC)?
Hardware Components are all the elements found on a SKAARHOJ controller or any Raw Panel compatible device (e.g., xpanel-* applications).
Some physical components, such as a joystick, can be represented as multiple Hardware Components in Reactor (e.g., Up/Down, Left/Right, and Rotate).
There are four basic types of hardware components:
- Buttons (Binary Inputs)
- Faders/Potentiometers (Analog Inputs)
- Encoders (Pulsed Inputs)
- Joysticks (Speed/Intensity Inputs)
Additionally, these components may have various types of displays linked to them.
Buttons can have different types of color LEDs to indicate status.
Larger displays can consist of different Tiles, allowing you to configure individual parts separately and easily.
What is a Behavior?
To configure what a specific component does and shows, we need to assign a Behavior to it. Click any hardware component in the configurator view to access the Behavior defined for it. If no Behavior has been created for this component yet, the inspector will show a palette of pre-configured Behaviors based on the devices you've added in the Home Screen.
Clicked on a component and found a purple Generator? This component's behavior is likely defined by a Settings Table from the Home Screen. You can overlay it by selecting the User Section in the section dropdown. If you'd like to learn more or modify the generator, please refer to the chapter on generators.
To select a Behavior, simply choose the component you want to modify. If no behavior has been defined for the component yet, you will see the behavior palette in the inspector. You can select any preconfigured parameter from the list of your devices.
If you have selected a component that already has a configured behavior, you can click Change Behavior in the top right corner. This will reopen the behavior palette, allowing you to switch to a different one.
Manually Changing a Parameter in a Behavior
To manually edit a parameter inside a behavior (without using the preconfigured behaviors from the palette), click the Show More button. A yellow pen icon will appear next to the name of the parameter field. Click it and use the parameter reference helper window to configure the parameter you want.
Once you click submit, you will be presented with this window:
If you click the green Confirm button, you will use the Automatic Behavior Configuration.
This means Reactor will automatically select a Template Behavior and add configuration constants to your behavior. This makes it very quick to add almost any parameter to a component.
In some cases, you may want to keep the settings you have manually configured in the behavior. In these cases, simply click Keep current, and Reactor will only change the parameter reference.
Changing Template Behavior
Reactor does its best to choose the correct Template Behavior based on the type of component and the parameter you select. However, you may still want to change it. To do so, click Show More to display the Template Behavior dropdown.
The Template Behavior dropdown shows the most commonly used templates at the top. If you have created Template Behaviors yourself, they will also appear. If you cannot find what you're looking for, click Show All to display more included Template Behaviors from Reactor.
Available Template Behaviors
Here is a list of the most important Template Behaviors included in Reactor.
Set specific value
Use this template if you want any action on the component to set a specified value on the selected parameter.
Example: Setting an AUX of an ATEM to input 1 using a button.
Set a value by index
Same as "Set specific value," but you can specify an index of the option for the specific parameter.
Example: Setting the current Scene in OBS to the 5th scene from the start.
Change by Step
Use this when you want to move a value up and down using an encoder or Four-Way button.
Example: Use an encoder to control the current shutter speed of a camera.
This Template Behavior is the most versatile one. It is almost always usable.
Change by step for larger ranges
Same as "Change by step," but for larger value ranges.
- Encoders will move more steps if rotated faster, and a fine/coarse selection can be made by pressing down shortly.
- Buttons will continue to increment when held down. Example: Changing the electronic shutter in 0.01 values of a degree.
Change by step with limited values
Sometimes a parameter has many options, but you want to limit the options selectable with the current button or encoder. Use this template to define several valid options for the parameter.
Example: Making an encoder only switch between three specific white balance modes (e.g., Manual/Preset1/Preset2).
Change by step with confirmation
Use this template on encoders and Four-Way buttons if you want the user to select a value first, then confirm the change by pressing down.
If no change is confirmed, the value will revert to the current one after the specified time.1
Example: Loading a new setup file on an Arri Camera. Use left and right on an encoder to select, then press down to confirm.
Change a value on fader / potentiometer
This is the default Template Behavior for mapping a parameter to a fader or LEDBar.
Example: Controlling Gain on an RCP joystick.
Change a value with motorized fader
This is the default Template Behavior for mapping a parameter to a motorized fader. It correctly sends back the position to the fader if the value changes in the system.
Example: Controlling Iris using a Color Fly V2 fader.
Toggle two options
Choose this Template Behavior for any On/Off, Show/Hide, Enable/Disable scenarios. The button will light up bright when the function is activated and dim when inactive. Example: Turning on/off bars on a camera.
Toggle on hold
This Template Behavior works similarly to "Toggle two options," but the action is triggered only after holding the button down for a specified time (default: 1000 milliseconds).
Example: A NETIO power outlet is toggled only when the button is held down for one second.
Trigger Action
Use this template for any one-shot parameters (commands).
Example: Triggering OnePush Autofocus on a camera.
Speed parameter
This is the default Template Behavior for mapping speed components (joysticks). It can also control speed commands from other components like encoders.
Example: Control Pan speed using a joystick.
Binary Output (for GPO)
This Template Behavior sets or clears the output of a GPO contact on RCPs or Link IO boxes using the parameter.
Example: Map a Tally Flag to the closed contact on the back of an RCP.
Hold-Down
Used for parameters with two options. When the button is pressed down, the parameter is set to "on." When released, it is set to "off."
Example: Mapping Record to the state of a GPI closed contact of an RCP.
Display value (without control)
Show a value without control or deliberately lock control of a value.
Example: Display the battery voltage of a camera.
Custom Template Behaviors
You can also create your own Template Behaviors. See the chapter Template Behaviors in Advanced Configuration.
Before Reactor v2.0.5-pre5, this required a ':Confirm:1000' modifier and only worked on devicecore parameters. In later versions, this Template Behavior works without any extra configuration steps. The old Template Behavior was called 'SKAARHOJ:Confirm,' while the new one is called 'SKAARHOJ:ConfirmValue.'
The Layer Tree
Although it is hidden at first, the underlying structure that powers the controller’s menus and components is called the "Layer Tree". For most people, this is initially an advanced concept, but it's extremely powerful and well worth understanding. Think of it like Photoshop for controller configuration: Different layers can be visible or invisible, and depending on that, different Behaviors are visible on your controller. We will later explore how these visibilities can be controlled by various Conditions, but for now, let's take a closer look at how the tree works.
Tip: The tree is hidden by default. Check this page to see how to open it: Configurator Layout
The Inverted Tree
When viewing the tree, you will notice that it doesn’t unfold like hierarchies in other applications, such as file browsers. This is because we are looking at the tree from above, just like viewing the controller. Layers and behaviors on top will be visible first, while those further down may be covered.
The tree’s Root Layer is the base at the bottom. Layers can be opened and collapsed to show their sub layers (branches).
Multiple Files Make Up the Tree
The Tree can be a combination of one or more layer files. The root layer is always defined by the current Reactor project, but it can include other files that get appended to the layer that includes them. To add a layer file, use the "Included Layer File" section in the layer's inspector window. When viewing the tree, you can identify where other files have been included.
Having the tree split into separate files allows for the reuse of configuration parts in other places. This is sometimes referred to as Snippets. In our default configuration, this concept is essential, allowing for quick switching of sub-configurations like Tally Forwarding or Routing Triggers. For building most custom configurations, we recommend not splitting it into multiple files, as this tends to increase complexity.
Layer Visibility and Behaviors
In the tree, every layer can have an Active-If condition. Depending on this condition, the layer is either active or hidden. When viewing the tree in the configurator, you can check if a layer is currently visible by looking at the blue border on the left side. If the border is visible, the layer is active; if not, it is hidden.
When a layer is hidden, all its elements are also hidden. Behaviors defined on the layer, variables, sub layers, virtual triggers, layer scripts, and other elements are hidden or disabled from the controller.
In the simplified example below, the root layer defines a Behavior called Behavior1. Since layer 2 above it redefines the behavior, the one shown on the controller is the one defined on layer 2, as it is higher up in the tree. Behavior2 on the other hand is not redefined, so the definition on the root layer is the active one.
Tree Elements
Layers in the tree include the definition of every other configuration element. These include:
- Behaviors
- Variables
- Virtual Triggers
- Flags
- Preset Kinds
- Template Behaviors (aka Master Behaviors)
- Settings Tables (aka Constant Sets)
- Key Maps
In the tree view, you can see most of these elements, making it easier to find them and the layer they are defined on. You can use the tree search function at the top of the tree to find elements more quickly. Additionally, you can select which elements of the tree are shown.
Inheritance
When a tree element is defined on a layer, it is also inherited by all of its sublayers. Let’s take a simple example of a variable.
The variable myvariable is defined on layer 2. This means that behaviors defined on the layer can read and modify this variable. The same applies to all behaviors of sublayers of layer 2, such as layer 2.1. However, the two behaviors on the Root Layer - Treetest cannot access the variable myvariable.
By following this basic concept, we can understand which tree elements are available to which behaviors and layers. 1
Types of Tree Elements
Let’s take a look at the different tree elements and their functions.
Behaviors
Behaviors are shown in the tree by their names. The color indicates whether the behavior is selected and visible (or covered).
When a behavior is shown in:
- blue: It is currently visible.
- green: It is currently visible and selected.
- grey: It is currently hidden (covered by a different behavior above or on a non-visible layer).
- orange: It is currently hidden and selected.
Variables
Variables are shown in the tree with their key. A variable can have a key and a name — the name is a friendly name displayed in the interface, while the key is the actual reference to this variable used in all Parameter References. Changing the name only changes how the variable appears in different places, but changing its key breaks the links to other parts of the configuration.
Next to the variable, you can also see its current value. A variable can have more than one value at once (an array); if that is the case, the current values will be shown separated by commas.
Key Maps
A Key Map can map behavior names to the physical hardware components on panels. They can also remap behavior names to different ones. Most of the time, Key Maps are managed automatically by the configurator.
Each hardware component of a panel has a fixed address format:
_p<panelID>.<componentID>
For example: _p1.15 (Panel 1, Hardware Component 15) or _p3.23 (Panel 3, Hardware Component 23).
To make configurations compatible with multiple panels and more understandable, Key Maps are used to assign names to these addresses.
A Key Map can contain different mappings:
- Component address to behavior name: This assigns behavior names to hardware components in the configurator.
- Behavior name to behavior name: Remap a behavior name to a different one in the layers below, often used when a configuration is remapped to a different set of buttons.
- Panel Wildcard (e.g., _p1.*): Remap a panel ID used in the layers below to a different one. This is mostly used by the Home Screen to map your panels to their selected configurations.
Behavior to behavior mapping and Panel Wildcard mapping are often used in combination with the inclusion of different layer files. This is useful when remapping IDs in an included configuration.
The Key Map is shown in the tree on the layer where it is defined, and its mapping is valid for that layer and all its sublayers, like the inheritance of any other tree element.
Virtual Triggers
Virtual Triggers are defined on layers in the tree. When a layer becomes hidden, the virtual trigger will not execute anymore. See more about Virtual Triggers in the chapter Virtual Triggers.
Preset Kinds
Preset Kinds define a Reactor Preset as a list of parameters that can be stored and recalled from your panel. You can read more in the chapter Shading Presets.
Flag Group
Flag Groups are defined in the tree. Read more about them in the chapter Flag Groups.
Custom Template Behaviors
If you find yourself creating the same kind of behavior repeatedly, you might want to create a Template Behavior. In Reactor, Template Behaviors are also called Master Behaviors.
You can create a Template Behavior on any layer and configure it as needed. Afterward, you can select the new Template Behavoir for other Behaviors (within the scope of inheritance). See more in the chapter Custom Template Behaviors.
Settings Tables (aka Constant Sets)
Settings Tables - or Constant Sets - are a table structure used for various purposes in Reactor, such as:
- Storing configuration settings that can be changed directly on the Home Screen.
- Generating layers with Behaviors based on table rows.
- Creating multiple Virtual Triggers based on table rows.
As with all other tree elements, they follow inheritance. Learn more about their use here: Generators and Constant Sets.
Examples of Settings Tables in default configurations include:
- Camera Selector
- Tally Config
- GPIO Mappings
- (See more examples in Default Configurations)
We call them Settings Tables because they often store important settings available from the Home Screen. Their original name, Constant Sets, reflects the fact that their values are stored within the configuration and cannot be changed while the controller is running, unlike variables. Any modifications require updating the configuration through the UI.
Layer Paths
Technically, every layer has a path. Paths are denoted as, for example, 0/1/4/1/.
0/ always references the root layer. 0/0/ references the topmost child layer of the root layer, and so on.
Knowledge of layer paths is not required to use Reactor, but it can help you better understand the system.
Variables and Settings Tables (Constant Sets) can have advanced options that affect inheritance, such as Expand Scope, Capture, and Always Define. This is an advanced topic and will be covered later. Please refer to the corresponding tool tips in the configurator for more details.
Variables and Conditions
To better understand how menus and other logic can be created in Reactor, we need to understand Reactor's Variables and Conditions.
Variables
A Variable is, like many other things, an element in the tree (See Tree Elements). Variables are a concept used in programming and mathematics to store information. In Reactor, they can be used to store values like:
- the current page of a menu
- the currently selected Device ID
- whether the engineering menu is open
- and much more...
Types of Variables
Reactor variables can have two main types:
- Option List: A list of options, where each option can also have a label. Option values can be numbers or strings.
- Range: A numeric range with a minimum, a maximum, and a default (or center) value.
When a variable is set, the system checks if the value matches the possible defined values. If not, it will not set the variable unless the option Accept any value is checked under "Show More".
Basic Usage of Variables
Variables can be created on layers. The quickest way to do so is to select the base layer of your current configuration and add a variable.
When a variable is created, its value defaults to the first value unless otherwise specified. From that point on, you can use your variables in all Parameter or Condition fields in any layer or behavior. Keep in mind that variables are available only to the layer they are defined on and its child layers. This follows Tree Inheritance.
Example:
The components on the layer MyCustomOverlay (1) and INLINE10-Custom-2 (2) can use the variable ShowCustomButtons (3). Components on the layer QuickBar-Custom-1 (4) cannot use the variable, as they do not inherit its definition.
To create variables that can be accessed by all layers, they need to be created on the main root layer of the project (5). The variable MyGlobalVariable (6) is accessible to all layers and controllers.
Setting and Checking Variables Using the Configurator
In the configurator, you can always see the current values of variables in the tree.
In the Inspector, you can also set different options active using the blue flag icon next to them.
Finally, you can use the bottom of the form to force set a variable or even set more than one value.
One Variable, Multiple Values
Any variable in Reactor can be seen as an array of values. While this array will only contain one element in most cases, it can also be empty or contain multiple elements. To add or remove values from a variable, you can use the Set Mode in the EventHandler config:
Here are the relevant ones explained:
- Add To Array: Adds a new value to the current value array.
- Remove From Array: Removes a specified value from an array.
- Clear: Clears all values of a variable, resetting it to an empty array.
- Toggle Add Remove: Adds a value to the array or removes it if it's already there.
Example: In a setup with multiple cameras, you may want to have one button controlling gain on several cameras at once. You can set up buttons to add more than one ID to the DeviceIndex
to make this possible. ParameterReferences that already reference Var:DeviceIndex
will now control all Devices in the array.
Conditions
Conditions are a structure used in many places in Reactor. They are text strings that combine multiple Parameters into a condition that can ultimately evaluate to either "true" or "false".
Some example places where they are used are:
- Active-If Condition on Layers: Determines if a layer is visible (rendered) or not.
- Active-If Conditions on FeedBack Handlers: Determines if a certain Feedback (e.g., Text, Color, etc.) is active or not.
- Active-If Conditions on Event Handlers: Determines if a certain interaction (e.g., left edge press) is active or not.
- Conditions on Virtual Triggers: Determines if a Virtual Trigger simulates an active button press (See Virtual Triggers).
- And several other places...
The Condition Helper Window
When you see a condition in Reactor, you can simply click it once to open the Condition Helper Window.
The helper window can make it quick to create the condition you need. You can:
- Select Parameter References by clicking the yellow pencil icons or just start typing values into the text field.
- Change the comparison operator in the middle to check.
- Add logical branches to your conditions.
- Change how your conditions are combined (AND or OR).
- Edit the raw string value of your condition.
- Evaluate the current result of the condition in Reactor by clicking the button. If true, you will see a green check ✅, else a red mark ❌.
Basic Format
The basic format of a Condition looks like this:
<Value or Parameter Reference> <comparison operator> <Value or Parameter Reference>
Comparison Operators
The basic operators for comparing values are:
- == equal to
- != not equal to
- < smaller than (only for numeric values)
- <= smaller than or equal to (only for numeric values)
- > larger than (only for numeric values)
- >= larger than or equal to (only for numeric values)
You can also quickly "force" a variable by simply typing true or false directly into the first field and leaving the second one empty.
Combining Different Conditions into One
You can also combine several different conditions using the logical combination operators:
- && AND
- || OR
Additionally, you can use parentheses ( ) to group parts together and specify the order in which the individual parts of a combined condition are evaluated.
Example:
Var:MyVariable == true && (DC:bmd-atem/1/programInputVideoSource/1 == 5 || DC:bmd-atem/1/programInputVideoSource/1 == 8)
This will evaluate to true if the variable MyVariable
is set to true and the Program Parameter of the ATEM device 1 (on ME1) is either 5 or 8.
Example:
Var:MyVariable == true && DC:bmd-atem/1/programInputVideoSource/1 == [5,8]
This is the same, but shorter, using an array for the literal values 5 and 8, which implies an OR operator.
Checking Against Empty or Zero Values
When checking if a value is empty, there are different possibilities to consider:
- A value can be completely undefined: In this case, we can check against an empty array
[]
or['']
. - A value can be an empty string: In this case, we can check against
''
.
Inside of the Condition Helper Window, you will get these values recommended in a dropdown.
Example Usages of Variables and Conditions
The simplest use case for variables and conditions is to switch the visibility of a layer on and off. To do so, simply create a Variable — let's use "ShowCustomButtons" as the name for this example.
In the variable settings, set it to "Options" (1), click "Add option" (2), and add true and false options (3). We can also add labels (4) to these options — let's type in "Show" and "Hide" for this example.
The next step is to add our custom layer.
(If the tree is not open yet, click the green arrow in the top left corner (1)).
We can click the config layer (2) of our controller's config and click the Add Child Layer button (3).
Let's add two Behaviors to our buttons. To do this, we click the layer (1), select the two components by dragging (2), right-click them, and choose Create Behaviors (3). By default, Reactor will create dummy behaviors that show their button name and layer path.
We also need to map one of the encoders of our controller to the variable we just created. Simply click the component, choose System -> Change Variable from the sidebar, and select the Variable ShowCustomButtons.
Finally, we need to add an Active-If condition to our layer. To do this, click the layer and select Add Active-If Condition in the inspector.
On the left side, click the yellow pencil and select the variable ShowCustomButtons. On the right side, you can just type out true.
Click "Submit", and we are done.
To check the result, activate simulation mode (ctrl/cmd+e) and change the variable using the encoder. It should look like this:
The Parameter Reference (aka IO Reference)
One of the fundamental concepts in Reactor is the Parameter Reference, also sometimes referred to as IO Reference. This is a text string used to address any parameter within Reactor. Parameter References are similar to URLs, providing a consistent method for accessing and manipulating data. The main groups of addressable parameters are:
- Device Core Values
- Variables and Flags
- System Values
- Presets
- Panel Settings
- The current Behavior and its settings
- A value from a specific Settings Table
Additionally, the parameter reference can also include simple (literal) values, like a number or a text string.
Configuring Parameter References using the helper window
In Reactor, wherever you encounter a Parameter Reference, you can open a helper window to select what you need easily. You can also configure the Parameter Reference manually if you wish.
The helper window consists of several parts:
- The top displays the actual text string being built by the options you choose.
- Select the type of Parameter Reference you want to create.
- Configure the Parameter Reference; in this case, select the parameter of a device. The form will show more options as you make selections.
- Click the Edit Raw button to directly edit the Parameter Reference text string.
Manual Configuration
To manually configure a Parameter Reference, you must first understand the format and the possible options that make up the reference.
Basic Format
The basic format looks like this:
Type:part1/part2/part3:modifier1:modifier2:modifier3
Some parts can include nested Parameter References using curly brackets { }, allowing a different Parameter Reference to select a certain device ID for example. This is valid in some combinations but not universally. Refer to the specific option in the reference for more information about templating.
It is also possible to create a Parameter Reference that points to multiple parameters using array syntax with [ ] for IDs.
Types and their Options
Different Types of Parameter References can have different options or modifiers.
Literal Values
Literal values can be written as they are, provided they do not include a colon.
For example: 3
, true
, or page1
To specify an array of values, enclose the values in brackets and separate them with commas, for example, [red, green, blue]
.
In cases where your value contains special characters, prefix the value with String:
to explicitly indicate that the rest of the value is a literal value.
Eg: String:{"DATA":"Custom JSON value"}
Variables (Var:
)
Var:
)Variables can be referenced by combining the type and the variable key.
For example: Var:SEC_Page
or Var:DeviceIndex
Modifiers can be added at the end.
For example: Var:SEC_Page:Name
(displays the friendly name of the variable) or Var:DeviceIndex:Current:Name
(displays the label of the current value).
Device Core Parameters (DC:
)
DC:
)Device parameters follow this syntax:
DC:[name of the core1]/[device ID]/[name of parameter]/[dimension1 index]/[dimension2 index]/...:Modifiers
The device ID and dimension values can be set in different ways, as they are Parameter References themselves, meaning they can be Variables, Behavior Constants, or any other reference. If the reference includes slashes (/
), it must be wrapped in curly braces {}
.
Examples: DC:bmd-atem/{Var:DeviceIndex}/AuxSource/{Var:AuxChannel}/
This references AUX sources on the ATEM switcher with Device ID found in "Var:DeviceIndex" and the AUX Channel denoted by "Var:AuxChannel".
In this case, wrapping the nested Parameter Reference is not required, as there are no forward slashes that might interfere with parsing, but it improves readability to do so.
Panel Settings (Panels
)
Panels
)Panel parameters like brightness and sleep can be controlled using this type of parameter reference.
The basic format is:
Panels:[target type]/[target index]/[panel parameter type]
Target Type can be one of the following:
- Canvas - Directly address the whole canvas (panel group) by its ID.
- Panel - Address a specific panel by its ID.
- CanvasOfPanel - Address the whole canvas (panel group) of the panel specified by the target ID.
The target index can be a Parameter Reference, which means it can be a Variable, Behavior Constant, or any other reference. If the reference includes slashes (/
), it must be wrapped in curly braces {}
.
Important: Reactor typically addresses panel parameters like this: Panels:CanvasOfPanel/Behavior:Panels/[panel parameter type]
, ensuring the full panel group is addressed. In most cases, this is the best method.
Panel Parameter Types:
- SleepTime (minutes)
- DimTime (minutes)
- DisplayBrightness (0-8)
- LEDBrightness (0-8)
- GlobalBrightness (0-8)
- Sleep (binary: "on", "off")
- ResetSleepTimer (one-shot trigger)
- Name (read-only)
- Model (read-only)
System Values (System:
)
System:
)System variables can be accessed using the System parameter type.
Available options:
-
System:PanelLock - Locks the entire Reactor system.
-
System:IPAddress - Displays the IP address of Reactor. It can also be used to change the system IP with a set value command or the SKAARHOJ:ChangeIP Template Behavior.
-
System:CurrentProject - Triggers a project change using Set Value.
-
System:RestartEngine - Restarts Reactor's engine, similar to switching projects.
-
System:ProjectTitle - Displays the current project title.
-
System:ConfigTitle - Shows the current name of the root layer.
-
System:UptimeFormatted - Displays the uptime since Reactor was started.
-
System:Panels:Connected - Number of currently connected panels.
-
System:Panels:Warnings - Number of panels with warnings.
-
System:Panels:Unconnected - Number of unconnected panels (errors).
-
System:Panels:LastEvent - Last event as a string, e.g., "Down (T)" if the top edge of a Four-Way button was pressed down.
-
System:Panels:LastEventSource - The HWC source of the last hardware event, including panel ID, in the form "P[panel id]#[HWC id]", for example, "P1#43."
-
System:Devices:Connected - Number of connected devices.
-
System:Devices:Warnings - Number of devices with warnings.
-
System:Devices:Unconnected - Number of unconnected devices (errors).
-
System:Devices/[idx]:Name - The name of a device, where
idx
is an index number. -
System:Warnings - Total number of warnings in Reactor.
-
System:Errors - Total number of errors in Reactor.
The current Behavior and its settings (Behavior
)
Behavior
)Behavior parameters reference values configured for the current Behavior or display related information. These are often used in Template Behaviors.
Format: Behavior:[subtype]:[additional type]:Modifiers...
Examples include accessing the main parameter’s value or name using Behavior:IOReference:Name
(to display the name) or Behavior:IOReference:Current
(to display the current value).
Subtypes
- IOReference (main parameter reference)
Using this subtype, the main parameter in the behavior can be referenced. Additionally, modifiers can be added. This allows you to refer to the main parameter's value or name without hardcoding it in other parts of a behavior (such as Feedbacks or Actions).
Examples:
Behavior:IOReference:Name
(Displays the main parameter's name) or
Behavior:IOReference:Current
(Displays the main parameter's current value).
- Const (BehaviorConstant)
Using Behavior:Const:[constant key]
, you can access constant fields of the behavior. This allows you to create SettingsTemplates for behaviors with customizable constant fields. It is used in many built-in Template Behaviors.
Advanced Subtypes
Several other subtypes exist to access information about the current behavior:
-
Name - The friendly name of the behavior.
-
Path - Returns the "path" of the behavior in the layer tree, e.g., "0/3/0/A3".
-
ID - Returns the behavior's main mapping to a panel, for example,
"_p4.32"
(panel ID 4, Hardware Component (HWC) 32). -
Panels - An array of all panel IDs this behavior is mapped to (used mainly for accessing panel parameters, see below at Panel Settings).
-
Script - Using the Script subtype, you can access information about the currently running scripts of this behavior. See Scripting Engine.
- LastEvent
Access information about the last hardware event (trigger) received by the behavior.
IO Reference | Comment |
---|---|
Behavior:LastEvent:Type | Type of last event. Options: Binary, Pulsed, Analog, Speed |
Behavior:LastEvent:TimeToNow:[Limit] | Returns the time in milliseconds that has passed since the last event. Although setting a limit is optional, it's recommended to set it at or above the comparison value for performance efficiency. If a limit is set, it designates the maximum returned value. |
Behavior:LastEvent/Binary:Pressed | Returns whether the last binary trigger was pressed (ActDown) or not (ActUp). Options: true, false |
Behavior:LastEvent/Binary:Edge | Returns which edge the last binary trigger sent. Options: NoEdge, Top, Left, Bottom, Right, Encoder |
Behavior:LastEvent/Pulsed:Direction | Returns the direction of the last pulsed trigger received. Options: Up, Down |
Behavior:LastEvent/Pulsed:Value | Returns the value of the last pulsed trigger |
Behavior:LastEvent/Analog:Value | Returns the value of the last analog trigger (0 to 1000) |
Behavior:LastEvent/Speed:Value | Returns the value of the last intensity trigger (-500 to 500) |
-
Events
Access information about the last Action executed on the behavior.Behavior:Events/[Action Name]:TimeToNow:[Limit]
Returns the time in milliseconds since the last accepted trigger for the specified action. Setting a maximum limit is recommended for performance reasons in Reactor.
Behavior:Events/[Action Name]:SequenceStep
The current sequence step being executed (see Binary Sequence).
Presets (Presets
)
Presets
) Preset Parameters control Reactor’s Parameter Preset Engine.
The basic format:
Preset:[preset kind name]/[command]/[preset index]/[device index]/
Command can be one of the following:
- Store
- Recall
- Delete
The preset index and device indexes can be set in different ways. They are Parameter References, meaning they can be a Variable, Behavior Constant, or any other reference. If the reference includes slashes (/
), it needs to be wrapped in curly braces {}
.
Flags (Flag
)
Flag
) Flags can be set, cleared, or displayed. The format:
Flag:[flag group name]/[flag color]/[flag number]:modifier1:modifier2:modifier3 Flags can be referenced to set, clear, or display them. The basic format is:
Flag:[flag group name]/[flag color]/[flag number]:modifier1:modifier2:modifier3
Make sure you have created a flag group before using this. More information can be found here: Flag Groups.
The Flag color can be selected from the fixed list of [Red, Green, Blue, White].
Finally, an index between 0 and 99 can be selected.
Note: Flags are generally used for SKAARHOJ Default Tally Forwarding and Routing Triggers. However, most things that can be done with flags can also be achieved with variables.
Value from Settings Tables (Const
)
Const
) This type of parameter reference allows read-only access to a value in a constant set table.
It can be useful for accessing settings values defined on the home screen or values from a constant set in virtual triggers.
Reactor's constants are unchangeable values embedded in the configuration code, used for various purposes within the configuration. Unlike variables, constants can only be modified by altering the configuration. Settings Tables in Reactor are essentially tables of related constants.
The basic format is:
Const:[constant set name]/[row index]/[constant name (column)]:Modifiers...
The Row Index can be set in different ways. It is a Parameter Reference, meaning it can be a Variable, BehaviorConstant, or any other reference. If the reference includes slashes (/
), it must be wrapped in curly braces {}
.
Examples:
Const:CameraSelector/0/CameraName
Returns the value of the constant "CameraName" in the first row (index 0) of the constant set "CameraSelector."
Const:CameraSelector/{Var:CameraIndex:Current:Offset:-1}/CameraName
This retrieves the value of the constant CameraName from the row in the CameraSelector constant set, as indicated by the CameraIndex variable. If the CameraIndex variable is set to 1, it refers to the first row (index 0), as the variable's value is reduced by one when inserted as the row index (:Current:Offset:-1
).
Modifiers are used by certain Parameter References to access additional information or present the data in a different format. Modifiers are simply appended to the Parameter reference like this:
ParameterReference:Modifier1:Modifier2 ...
Most of the time, modifier combinations are dependent on their order.
Not all Parameter types support all modifiers. Reactor will limit the selection based on your Parameter selection in the helper window.
Here is a complete list for reference:
Modifier | Comment | DC | Var | Const |
---|---|---|---|---|
(no modifiers) | Without any modifiers, returns the values. | Yes | Yes | Yes |
Name | Returns the name of the reference, such as a parameter or variable name. | Yes | Yes | Yes |
Default | Returns the default values of the IO reference. | Yes | Yes | - |
Default:Name | Returns the names/labels of the default values of the IO reference. | Yes | Yes | - |
All | Returns all option values for a parameter. For integer ranges with fewer than 100 values, it will calculate and return that as an option list. | Yes | Yes | No |
Exists | Returns "true" if the reference exists. | Yes | Yes | Yes |
Mutable | Returns "true" if the reference can be changed. | Yes | Yes | Yes |
Assumed | Returns "true" if a parameter is assumed in the core. | Yes | - | - |
FineSteps | Returns the recommended fine steps for a Device Core; otherwise, returns 1. | Yes | - | - |
CoarseSteps | Returns the recommended coarse steps for a Device Core; otherwise, returns 10. | Yes | - | - |
ASCIIOnly | Returns true if only ASCII characters are found in the return value. | Yes | Yes | Yes |
Current | ||||
Current | Returns the current values. Same as not using the "Current" modifier. | Yes | Yes | Yes |
Current:Name | Returns the names of the current values. | Yes | Yes | Yes |
Current:Normalized | Returns the normalized value in the range of 0-1000. | Yes | Yes | No |
Current:NormalizedInverted | Returns the normalized value in the inverted range of 1000-0. | Yes | Yes | No |
Current:Percent | Returns the normalized value in the range of 0-100. | Yes | Yes | No |
Current:Remap:[low int]:[high int]:[optional integer divisor, default to 1] | Returns the value normalized to the range [low int]-[high int], divided by the divisor. | Yes | Yes | No |
Current:Index | Returns the index of the current value from the option list, starting with zero. Works only for parameters and variables with option lists, not ranges. | Yes | Yes | No |
Current:Count | Returns the number of values in the IO reference array. | Yes | Yes | Yes |
Current:Join:Token | Returns an IO reference with a single value, concatenating all values it had, separated by the Token string. | Yes | Yes | Yes |
Current:SingleValue:Index | Returns a single value from the current values by index. | Yes | Yes | No |
Current:Offset:[int] | Returns the value with [int] added to it. | Yes | Yes | Yes |
Current:BufferTimeToNow | Returns the time in milliseconds from the buffered value timeout to the current time. | Yes | - | - |
Confirm:[int] | Changes the value only locally, waiting to be confirmed for [int] milliseconds. | Yes | - | - |
Wait:[int] | Similar to Confirm, but the change is automatically accepted after the time expires. | Yes | - | - |
Index | ||||
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference] | Returns option value with index [int] or, if it's a string, the constant of the HWC Behavior. | Yes | Yes | No |
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference]:Name | Returns the name of the option value with index [int]. | Yes | Yes | No |
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference]:Exists | Returns true if the index exists. | Yes | Yes | No |
Index:[integer comma list incl. "Last" keyword/ Constant or Variable Reference]:Offset:[int] | Returns the value at index with a numeric offset (can be negative). | Yes | Yes | No |
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference]:Raw | Returns the raw index value of the option value with index [int]. | Yes | Yes | No |
DimensionName | ||||
DimensionName:[int]:[optional int] | Returns the name of the specified dimension (0 index). If two integers are specified, returns the name of the specified element. | Yes | No | No |
ID | ||||
ID:[integer / Constant or Variable Reference] | Returns an option by its value ID (different than index on some cores). Also supports :Name and :Exists. | Yes | Yes | No |
without core- prefix
Feedbacks and Actions
So far, we have been using the included Template Behaviors to define how a component interacts with a parameter.
When we want to customize individual parts of a behavior or even create one from scratch (without selecting a Template Behavior), we need to understand Feedback Handlers and Actions (formerly known as Event Handlers).
Feedback Handlers
Feedback Handlers are the parts of the Behavior that define what a component shows. They can adjust things like LED color, display text and elements, and even the position of a motorized fader.
Every Behavior and Layer has a Default Feedback, which is shown automatically. Additionally, there are Conditional Feedbacks, which are only active when their Active-If condition returns true.
Let’s take a look at the available fields in a Feedback Handler:
There are several groups of fields:
General Feedback Fields
Description
Give your Feedback Handler a readable description. This will be shown in the header and can make your behavior easier to understand.
Color
Set the LED Color. You can select one from the color picker or even use a parameter to define the color of a component.
NOTE: You will not see a color show up if Intensity is OFF.
Blink Pattern
Make the component blink in a certain pattern. This is useful for cases where you want a button to attract additional attention, like warnings or other alerts.
Text Display
Solid Title Bar
Select whether the Title Bar should have a solid white background or be transparent. In SKAARHOJ default configs, a transparent title bar is often used to indicate that a button "Sets" the value written on it, while displays with a solid header bar usually show the current state of a value.
Textline 1 & Textline 2
Specify the main text for the component. You can add dynamic values with parameters into the text using the helper window or braces {}
.
Text Size
Select a specific text size. This value corresponds to the font width and height as a comma-separated pair: 0,0
= Auto, 1,1
= smallest, 3,3
= largest, 1,2
= Tall and narrow, etc.
AutoWrap
AutoWrap will automatically break the contents of Textline 1 to Textline 2 if the text exceeds the available display space.
Use Graphics for Unicode
By default, our displays do not support unicode characters. When turning on this option, text that contains unicode will automatically be rendered into an image, allowing the displays to fully support unicode.
Note: This may sometimes slightly change the rendering, or modify text size and font.
Icons
State Icon Fine
Set a condition for when to show the fine icon, generally used to indicate when coarse mode is active.
Modifier Icon
Select one of several modifier icons to use. Modifier Icons are usually used to indicate what type of interaction is possible.
Tip: If you need these to be shown based on a condition, you will need to use several conditional feedback handlers.
Advanced Feedback Fields
Don't Inherit
Turning on this option will ensure no parameters are inherited from the Template Behavior for this entire Feedback. Read more about inheritance here: Behavior Inheritance.
Actions
Actions are the parts of the Behavior that define what the component does when it is interacted with in various ways. Multiple Actions can be added to each behavior to enable different types of interactions or control different parameters.
Actions can also have an Active-If condition, but unlike Conditional Feedbacks, Actions are always active by default.
General Action Settings
Let's take a look at the available fields in an Action:
Handler Type
The Handler Type is a special field that determines the other available fields for configuration.
An Action can have one main type of trigger it interacts with. The trigger types are (as described earlier in Hardware Components): Binary, Pulsed, Analog, and Speed.
- A Binary Component can create ActDown and ActUp triggers.
- A Pulsed Component can create Pulsed Value triggers, like +1 and -1.
- An Analog Component can create Analog Value triggers from 0 to 1000.
- A Speed Component can create Speed Value triggers from -500 to +500, resetting to 0 when released.
After selecting the Handler Type, you can still add PreProcessors to the Action, which define how to respond when a different trigger type is received.
General Action Fields
Parameter
Each Action can specify a different parameter to control. If no parameter is specified, the one defined at the top of the behavior form will be used.
Active If Condition
Each Action can have a condition. If the condition is false, the Action remains disabled and is not used.
Example: This can be used to specify different Actions based on the value of a variable.
Invert Condition
Specifies a condition that (if true) inverts the normal direction for control. If you would like to always invert it, simply select true.
Specific Settings: Binary
Binary Type
Specify whether this handler reacts only on a down press (ActDown) or only on release (ActUp). If not set, it will fire in both cases.
Edge Filter
When mapped to a Four-Way button or encoder, use this setting to filter for a specific event, like pressing only up.
Set Mode
This allows you to specify how a press of the component will change the parameter. The following options are available:
-
Set
Set a specific value (specified using set values, see below). -
Cycle Up
Cycle up through the available options. -
Cycle Down
Cycle down through the available options. -
Cycle Up and Roll Over
Cycle up through the available options and continue at the start when going over the maximum. -
Cycle Down and Roll Over
Cycle down through the available options and continue at the maximum when going below the start. -
Random
Set a completely random value out of the possible ones that is not the same as the current value. -
Sequence
Sequence allows you to set several values in sequence, even for different parameters. You can specify a different parameter at each step. Choose sequence and add several steps. -
Array-specific options for Variables:
See Chapter Variables.
Set Values
Specify the list of values that this Action selects from. This defaults to using all options from the main parameter of the behavior (:All
modifier).
Specific Settings - Pulsed
Rollover Condition
Specify a condition in which Rollover is allowed. Rollover means that when the end of the value range is reached, the next step jumps to the other end of the range.
Fine Step
Specify the fine step size for stepping through the parameter. You can either use the default for the behavior’s parameter (Behavior:IOReference:FineSteps
) or specify your own.
For example: Select Literal Values -> then type 0.01 in the field.
The fine step size is used by default unless the CoarseCondition is true (see below).
Coarse Step
Specify the coarse step size for stepping through the parameter. You can either use the default for the behavior’s parameter (Behavior:IOReference:CoarseSteps
) or specify your own.
For example: Select Literal Values -> then type 10 in the field.
The coarse step size is used when the CoarseCondition is true (see below). In Reactor built-in behaviors like Change by step for long ranges, this is used when pressing down an encoder.
Coarse Condition
Selects between using fine steps (when false) or coarse steps (when true).
In Reactor built-in behaviors like Change by step for long ranges, this is used when pressing down an encoder.
Ganged Control Mode
When set to "Relative", and the component controls multiple parameters at once, they will all be stepped relative to their own values.
Otherwise, only the first value will be stepped, and all other values will be set to the destination value of the first.
Specific Settings - Analog
Discontinuity
Discontinuity specifies what happens if the parameter being controlled has a different value than the current setting of the analog component. It defines the takeover strategy.
For example: If Iris is mapped to a RCP Joystick but has been changed on the camera in the meantime.
-
Double Linear: Double linear will map the value linearly from the current value towards each end of the value range. The rate of change (slope) may be different in each direction depending on the actual position of the analog component.
-
Offset: Offset will change the value from the current value towards the ends using the same and original rate of change. This means it may not entirely reach the end value as the analog component hits its end stop or it may reach the end value earlier than when the analog component hits its end position.
-
CatchUp: In this mode, the value won't change until the analog component is moved to the position that represents the current parameter value. At that instant, the analog component will linearly map its position to the value range of the parameter.
-
None: The value will jump to the correct mapped value when the component is moved.
Some information on this feature can be found in this YouTube video:
Note: This is not recommended to be used with MultiBehaviors.
Specific Settings - Speed
Speed handlers currently don't have configuration options exposed in the UI.
Advanced Action Fields
Event Preprocessor
Event preprocessors allow all kinds of advanced modifications, like hold down, repeat, and other tricks. See the advanced chapter on Event Preprocessors for more details.
Don't Inherit
Turning on this option will ensure no parameters are inherited from the Template Behavior for this entire Feedback. Read more about inheritance here: Behavior Inheritance.
Inheritance of Feedback and Event Handlers from Template Behaviors
When adding Feedback Handlers to a behavior that uses a Template Behavior, they will be combined with those from the template. Feedback Handlers defined in the template are marked as Inherited.
Feedback Handlers with the same index number in both the template and the behavior will be merged (overridden). The same applies to Actions with the same name.
In the example above, after modifying the Feedback Handler with index 10 (changing the color), the fields inherited from the Template Behavior's Feedback Handler with index 10 are still visible.
Virtual Triggers
While a component can generate triggers, sometimes you might want to trigger something based on an external event, such as a parameter change on one of your switchers. To facilitate this, Reactor can generate a trigger based on:
- Conditions
- Time
- Value Changes
Modes
Virtual triggers can operate in one of the following modes:
Change: Trigger when an external value changes
In Change mode, you can select any parameter. When the parameter changes or updates, the trigger is fired, simulating a button press (similar to Binary mode).
Analog: Simulate a fader move
In Analog mode, the selected parameter becomes an Analog Trigger (simulating a fader). Every time the value changes, a new Analog Value is sent to the defined Behavior.
Schedule: Use a fixed time schedule to trigger something
In Schedule mode, you can configure a schedule for when your trigger will be executed using cron-like syntax. Every time the specified time is reached, the Virtual trigger sends a Binary trigger (simulating a button press) to the defined behavior.
See below for how to configure the time format.
HoldGroup
Special Virtual Trigger type designed for use cases like a Joystick Hold Group with multiple RCPs 1.
Creating and Configuring Virtual Triggers
Like many other elements, VirtualTriggers are part of the tree and are defined on a layer. To keep things simple, it is recommended to create VirtualTriggers on the base configuration layer of your configuration. You can select this using the layer icon next to the Section Selector.
To create a VirtualTrigger, follow these steps:
After creation, click on the name to edit it. You will see this in your inspector:
- When adding a Virtual Trigger, first select its mode using the dropdown.
- After creating a trigger, select either a Condition, Parameter Reference, or time schedule.
- Click Create to create a Behavior.
- Click on the Behavior to configure a behavior that will be used for the Virtual Trigger.
Configuring 'Schedule' Virtual Triggers
Schedule Virtual Triggers use a configuration format called Cron. Cron is a Linux application that schedules commands or scripts to run automatically at specified times and dates.
The syntax works as follows:
* | * | * | * | * | * | |
---|---|---|---|---|---|---|
Field name | Seconds | Minutes | Hours | Day of month | Month | Day of week |
Allowed values | 0-59 | 0-59 | 0-23 | 1-31 | 1-12 or JAN-DEC | 0-6 or SUN-SAT |
Allowed special characters | * / , - | * / , - | * / , - | * / , - ? | * / , - | * / , - ? |
All six fields are required.
Allowed special characters explained:
-
Asterisk ( * ) The asterisk indicates that the cron expression will match all possible values of the field. For example, using an asterisk in the 5th field (month) would indicate every month.
-
Slash ( / ) Slashes describe increments of ranges. For example,
3-59/15
in the 1st field (minutes) would indicate the 3rd minute of the hour and every 15 minutes thereafter. The form*/...
is equivalent tofirst-last/...
, meaning an increment over the largest possible range of the field. The formN/...
is accepted as meaningN-MAX/...
, starting at N and using the increment until the end of the specific range. It does not wrap around. -
Comma ( , )
Commas separate items in a list. For example, "MON,WED,FRI" in the 5th field (day of the week) would mean Mondays, Wednesdays, and Fridays. -
Hyphen ( - )
Hyphens define ranges. For example,9-17
would indicate every hour between 9am and 5pm inclusive. -
Question mark ( ? )
A question mark may be used instead of*
to leave either the day-of-month or day-of-week field blank.
Alternatively, we also allow the following inputs:
Entry | Description | Equivalent To |
---|---|---|
@yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 * |
@monthly | Run once a month, midnight, first of month | 0 0 0 1 * * |
@weekly | Run once a week, midnight between Sat/Sun | 0 0 0 * * 0 |
@daily (or @midnight) | Run once a day, midnight | 0 0 0 * * * |
@hourly | Run once an hour, beginning of hour | 0 0 * * * * |
Videos
We currently have 3 videos on our YouTube channel documenting Virtual Trigger Configuration:
Advanced Topics
In this chapter, we will explore some of the more advanced topics in Reactor's configuration. Many of these concepts are used extensively in our default configurations, and learning about them will provide a deeper understanding of what is happening within our built-in configurations.
We will cover the following topics:
- Flags
- Custom Template Behaviors
- Settings Tables and Generators
- Scripting in Javascript
- History View
- The JSON Editor
Custom Template Behaviors
To simplify repetitive configuration tasks, you can create your own Template Behaviors. These are sometimes referred to as Master Behaviors in Reactor (similar to a MasterSlide in PowerPoint or Keynote).
For example, suppose you want to create a custom behavior for an Encoder that performs a preset recall with a left turn and a preset store with a right turn. Additionally, you want the encoder to have a green ring light.
Once configured, you can reuse this encoder across multiple places in your configuration, controlling different preset IDs. This is a perfect use case for creating a Template Behavior.
Creating and Configuring Template Behaviors
Template Behaviors are a Tree Element and can be defined on a layer, following the usual scheme for Inheritance, as explained in the Tree Chapter.
To keep things simple, we recommend creating Template Behaviors on the global Root Layer of your configuration or the configuration layer related to your panel. In this example, we will use the second option. You can select the configuration layer related to your panel using the layer icon next to the Section Selector.
Next, add a Template Behavior. You can also use the "Copy From" function to copy the current behavior of a component into a new Template Behavior.
Afterward, you can configure your Template Behavior just like any other Behavior. 1
Using Constant Definitions to Add Fields to the Template Behavior
When creating Template Behaviors, it’s often useful to make certain parts of the nested configuration available at the top of the Behavior form. This is best done using Constants.
You can define Constants by adding Constant Definitions to your Template Behavior. Type a name for the new Constant (1) and press Create (2).
Once added, the new fields will be available at the top of the form (3).
Click on the definition to edit the properties of the new field. You can choose its type, add an extra label, and limit how many values it can hold.
Using a Custom Template Behavior
Once you have created your Template Behavior, you can use it in the Template Behavior field of any Behavior that inherits it.
Keep in mind that some features of the form might not be available, such as checking conditions and correctly filtered parameter lists (in the parameter selection helper window).
Flag Groups
In Reactor, a flag group is a structure used to store tally and routing information. It is a matrix of values, each with a color and a label.
The available colors are:
- Red
- Green
- Blue
- Yellow
Flag Groups are used in all default configurations for Tally Forwarding and Routing Triggers.
Creating and Configuring Flag Groups
Flag Groups are a Tree Element and can be defined on a layer, following the usual scheme for Inheritance, as explained in the Tree Chapter.
To keep things simple, we recommend creating Template Behaviors on the global Root Layer of your configuration or on the configuration layer related to your panel. In this example, we will use the second option. You can select the configuration layer related to your panel using the layer icon next to the Section Selector.
Next, go ahead and add a Flag Group.
Once you have created a flag group, you can use it right away.
Flag Groups are Global
One of the most important settings of a flag group is its Group Index. This number is similar to a TSL Screen ID. Flag Groups with the same Group Index will share their state, no matter where they are defined in Reactor. You can use this to make two controllers share the same tally information or to separate tally for controllers by using a different number for the index.
Controlling Flags from a Behavior
Flags can easily be set from a Behavior or used in a Condition. To do this, simply select Flag in the Parameter Helper Window.
Once you have selected a Flag, you can use Hold Down, Change By Step, or Set Specific Value Template Behaviors to control it. For GPO contacts, we usually use the Output Template Behavior.
Flags behave like any other Boolean Parameter. They have a value called 'true' and one called 'false'.
See more here: Parameter Reference.
Monitoring and Debugging Flag Groups
If you open "Show More," you can see the first 150 flags as switches. This allows you to monitor their state and also control them manually while working on your configuration.
(Note: The number of flags is technically unlimited, but only the first 150 are shown in the inspector for performance reasons.)
SKAARHOJ Default Configurations
Out of the box, we provide a quick setup to get you started controlling your devices. We’ve created a curated set of configurations to make it easy to add and combine devices from different manufacturers with our panels.
Panel Classes
To create systematic configurations, we’ve developed Configuration Classes, categorizing each SKAARHOJ panel by its intended purpose.
The following Configuration Classes exist:
- Camera Light Class
- Camera Standard Class
- Camera Pro Class
- Switcher Class
- Audio Class
- Quick Class
- Routing Panels
- MegaPanel Configurations
Camera Light, Pro, and Standard Class
Pro and Standard Class compatible panels are used for shading and PTZ control. A Pro Class panel has a menu based on 8 standard encoders, while a Standard Class panel has a menu based on 4 standard encoders.
These configurations are usually called "Generic Camera Control."
Light Class Panels
- PTZ Wiz
- Air Fly Pro (V2 and V3) Wiz Section
Standard Class Panels
- PTZ Fly
- PTZ Pro
- Color Fly
- Right Side of Rack Fusion Live
Pro Class Panels
- PTZ Extreme (V1, V2)
- RCP Pro
- RCPv2
- PTZ View (aka MKA 2)
- INLINE 22 + XC 7
Configuration Options
In these configurations, each panel has a Camera Selector, a Tally Forwarding Config, and a Routing Trigger Config.
The Camera Selector allows you to add different cameras. Each panel has a dedicated button row for camera selection. Depending on the device core used to connect the camera, a different menu will be loaded when the camera is selected. You can also configure its name, tally index, and routing index in the Constant Set Table.
Switcher Class Configurations
Switcher Class configurations are designed for live switching controllers and device cores. They provide the most common functions needed to control a switcher system while offering advanced features for deeper control, such as the Quick Class or PTZ sections.
Switcher Class Panels
- Air Fly
- Air Fly Pro (V1, V2, V3)
- Master Key One (V1, V2)
Audio Class Configurations
Audio Class configurations are default setups for controllers with at least four faders as the main components.
To use them in Reactor, select a "Generic Audio" configuration for your panel and fill the channel configuration with devices.
Audio Class Panels
- Wave Board (V1, V2)
- Wave Board Mini
- Color Fly (V2, V3)
- Wave Board (V1) 1
Quick Class Configurations
Quick Class configurations work with a Quick Bar and selected controllers that have a section of six Four-Way buttons. Select a Quick Class configuration in Reactor and fill the selector with the devices you want to control.
For more info, visit:
Routing Configurations
Routing Configurations map router devices to utility controllers like the Rack Fly series or the Quick Bar.
MegaPanel Configurations
SKAARHOJ MegaPanel configurations typically consist of one large configuration for several controllers, often based around a T-Block (Left or Right).
One M/E row usually consists of two Master Key 48s and one T-Block. Additional modules, such as the Wave Board Mini or PTZ View, can also fit the MegaPanel frame.
Understanding Sections in Default Configurations
The default configurations provide a few easily configurable sections.
User Section (1)
The User Section exists in all SKAARHOJ default configurations. It covers nearly all components of a panel. When you create a behavior in the User Section, the new behavior overlays those defined below, allowing you to easily modify button functions even if they are deeply embedded in the default configuration.
Camera Adjustments (2)
The Camera Adjustments section is present in all camera-related configurations (Light/Standard/Pro Classes). The menu corresponding to the selected camera’s device core is loaded and can be customized here.
Wave Board V1 has an alternative setup utilizing two extra buttons instead of the encoder.
Tips and Tricks
Using Context Menus
In many areas of Reactor, you will find context menus by right-clicking to interact with elements. These can help you work faster. Here are a few examples:
- Remove a panel faster using right-click.
- Copy Variables in the Tree quickly.
- Create behaviors on the controller.
- Clear the contents of behaviors easily.
Use Shortcuts
Shortcuts are a great way to speed up your workflow in Reactor. Here is a list of the most useful ones:
- cmd+e: Toggle simulation mode in the configurator.
- cmd+u: Upload a new package manually (works everywhere).
- Hold shift on Add Device or Add Panel: Add a device or panel without closing the dialog, allowing you to add multiple devices faster.
- cmd+i: Quickly open the project import window.
Use Copy/Paste
Many places in Reactor support copy and paste to speed up your configuration workflow. For example, you can create a behavior on one component and then copy it to several others. You can also copy and paste in many areas of the tree view, to duplicate constant set tables, variables, and other configuration parts between different layers.
Use Undo/Redo
If you ever get lost in the configurator, don't worry—you can use the undo and redo buttons to revert or restore your previous changes. If you want to create a "checkpoint," use History View to create a tagged version of your config.
Batch Editing Components
The Batch Editor allows you to quickly edit several components at once. To batch edit multiple components, drag a selection across them in the configurator. If the selected components don’t have behaviors yet, the Inspector will offer to create new ones for all of them from the library. Otherwise, you'll see all common options of the selected behaviors to edit them quickly. To edit individually, click the table icon below to open a table view of all selected behaviors.
Using "Load Recent" in the Parameter Reference or Condition Helper Windows
When configuring parameters or conditions, you can quickly recall recent parameter references by clicking the Load Recent button in the top right corner of the window.
SKAARHOJ Glossary
Here you can find an alphabetically ordered list of all terms used in SKAARHOJ products that might need additional information.
Behavior
A behavior in Reactor defines how a hardware component should behave. It consists of Actions, and Feedbacks that enable you to define how the Parameter is interacted with and how it is displayed on your component (button, display, fader, etc.). Additionally, there are templates for the settings of a behavior. (See Behaviors)
Blue Pill
Blue Pill is the the platform or "brain" of most modern SKAARHOJ products. As the successor to our legendary Unisketch products, it packs a full Linux operating system into a tiny package and enables control of many devices. Blue Pill Server is a product containing only this brain alone, while most of our outer products ship with the Blue Pill "brain" inside.
Device Core
A device core is a package that can be installed on a Blue Pill device. It acts like a driver that allows Reactor to communicate with your broadcast and AV devices using different protocols.
Device Collection
The Device Collection is a file storing all configurations of the devices that Reactor connects to. (See Projects)
devicecore-connector
The devicecore-connector is a tool that allows one Blue Pill device to share its device cores with other Blue Pill devices on the network.
Hardware Component (HWC)
Hardware Components are input or output components on SKAARHOJ panels, such as buttons, displays, faders, encoders, and more. (See Components)
hardware-manager
A package running on your Blue Pill devices that communicates with the actual buttons, displays, faders, and encoders of your controller. It connects to Reactor or can expose the controller as a Raw Panel device on the network for external control.
IO Reference (IOref)
Same as Parameter.
LinkID
A LinkID is a reference to a different layer configuration file. It can be used inside the tree to include sub-configurations.
Master Behavior
Same as Template Behavior (or Settings Template). Originally named after "Master Slides" in presentation programs like Apple Keynote or PowerPoint.
Panel Collection
The Panel Collection is a file storing all configurations of panels and Raw Panel devices that Reactor connects to. (See Projects)
Parameter (IO Reference)
A text string used to address any kind of parameter inside Reactor. (See Parameter Reference)
Raw Panel
Raw Panel is the protocol that Reactor uses to communicate with panels and controllers. It has different protocol variants. Learn more on the wiki.
Reactor
The main application running on your Blue Pill device, connecting panels to devices using configurations.
Settings Table (Constant Set)
A Settings Table is a table in the configuration. It can be used to store settings available on the Home Screen and to generate layers, behaviors, and virtual triggers based on its table rows. It's also called a Constant Set.
Template Behavior
A Template Behavior is used to quickly configure a behavior in Reactor for a given use case. (See Behaviors -> Changing Template Behavior)
system-manager
System Manager is the main package running on every Blue Pill device. It provides access to system configuration using the web interface, handles WiFi, logging, package updates, and all other system-related tasks.
Variable
A variable in Reactor is used to store information like the current menu page. (See Learn more on the wiki).