Reactor - the manual

SKAARHOJ Reactor is the powerful software running on BluePills and BluePill-Inside-Products. Using reactor you can

  • do simple things like controlling your ATEM mixers
  • more advanced things like powerful macros, that automatically start several hyperdecks and position your PTZ Cameras
  • highly custom things like protocol translation

All this and a lot more can be done, but at times configuration can also get quite extensive.

This manual tries 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

-> Reactor Changelog

-> System Manager Changelog

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 quickly go over the main areas of Reactor and the BluePill device web ui.

We will cover:

The HomeScreen

When you first open your BluePill you will find the so called 'home screen'

home screen areas

  1. 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.

  2. On the left side you can ddd and configure panels

  3. On the right side you can add and configure devices

  4. You can access and edit all reactor projects by clicking Manage Projects or restart reactor's engine by clicking on the green Running button

  5. 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" on the bottom to open the device browser. You will see a list of all devices Reactor discovers on the network. This is done using mDNS or other mechanisms. If your device does not support these you can also click "Add manually" in the top and add your device from the list.

Tip

Pressing shift while clicking "select" will not close the dialog and let you add multiple devices quicker

Panels

On this side you can add your panels. When you are working with a BluePill-Inside device you should automatically see your panel when creating a new project.

Clicking on the panels name allows you to adjust its IP Address, name, brightness and sleep settings

image

After a panel is added it will automatically choose one of the available standard configurations. In many cases these configurations are the generic SKAARHOJ default configurations, that will allow you to easily add devices from different manufacturers to your panel.

image

Below the selected configuration you can see it's configuration options. When the configuration has a Camera Selector you will also see, which devices are already mapped to the controller, or add new ones. To configure the settings of your panel in more details click the blue name of the setting (eg: Camera Selector, Switcher Inputs, QuickClass, ...) to open them in a table.

image

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 selects. From here you can select one of the built-in default configurations or create a fully custom config by clicking "Create Custom Config" in the dropdown.

Using the small info icon you can check additional info of your config, edit it in the JSON Editor, or delete/reset it to system

image
image
See details of a configuration in the Info Window

When creating custom configs or modifying system configurations you will see a small 'customized' indicator next to the configuration. Modifications are local to the current project.

image

Tip

To manage all available configs click "Manage Projects" and select "Manage Used Configs" in the top

Panel Groups

Panels can be grouped to set a 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 them.

image
Panel Groups are shown after enabeling them in View Options

Groups can be renamed and their settings adjusted. Panels can be moved between groups. Also 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 configuration.

To do so open the Project Window from reactors HomeScreen by clicking on Manage Projects

manage projects button

Manage Projects

alt text

Here you can see all projects saved on the controller.

  1. Use the buttons in the bottom to create new projects or import/export existing projects. Reactor Projects are stored as .rpj (ReaactorProject Format) and can be imported on other controllers easily.
  2. You can use search to find your projects, or click the triangle icons next to the name or created columns to sort your projects.
  3. Click Activate to switch the currently active project of reactor.
  4. Duplicating your project allows you to easily experiment with new configs and revert back to the previous state with ease
  5. Use the red trash can to delete your project
  6. Click Manage Used Configs to see all sub configs that the current project includes (See Manage Included Configurations)
  7. Using the advanced toggle you can show the components of your project. See below.

Tip

You can also switch the project from the controller using the SystemBehavior Change Reactor Project

Advanced Project View

Under the hood a project in reactor consists out of 3 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 config

These files can also be shared between projects. This is for example 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 also simply duplicate the full project it might sometimes be useful to create these shared setups. In the advanced view of the project dialog you can view and change the underlying configs for the individual parts of your projects.

example tree
Advanced view of the project window

Manage Included Configurations

While your project might have one root layer config, reactor will several files to build up the layer tree needed for your project. (See The layer tree)

In this section you can get a quick overview of all configurations that are currently used in your projects layer configuration. This might be system default configurations, customized system defaults or custom configs that you have created yourself. You can quickly see infos about them and even delete them from this view.

Example:

This configuration includes a PTZPro that uses...

  • it's default (Standard Class) configuration
  • Additionally a Canon Camera has been added
  • The FrameShot Pro has 2 custom configs created for it, one is used, the other one not.

alt text

Here you can see how the scenario looks in 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.

alt text

The Configurator

The Configurator (also sometimes called "Configuration Tab") is the main place where you can make customizations to your controller layout.

configurator-areas

There is 4 main areas:

  1. Controller:

    Here you can see and interact with your controller. Check the legend (blue question mark in the top right corner) on tips to navigate the canvas with your controllers. You can zoom in and out by scrolling and move by alt/option + dragging the mouse.

    Press ctrl+e (or cmd+e on macOS) to toggle between "configuration mode" and "simulation mode"

  2. 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, eg a Component Behavior, Variable, or other.

    Sometimes you might be looking at a Behavior that can not be seen on the controller, due to a different layer covering it. In this case Inspector will give you a hint and let you switch to the Active Behavior currently visible.

  3. Section Selector:

    The section selector in the bottom of the controller lets you select which section of panel you are currently editing. SKAARHOJ default configurations allow you to simply edit pages of existing menus. You can select these pages by clicking on their names, or add and remove and rename them to your needs.

  4. Tree:

    The tree is initially hidden. You can show it by clicking the little green icon in top left 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. They can also again have sub layers and include other layer files. Read more about this here: The tree

Reactor Configuration

In this chapter we will take a look into the details of controller configuration. We will learn about the different components of a controller, the layer tree and it's elements and how they all tie together.

We will take a look at:

Hardware Components and Behaviors

What is a HardwareComponent (HWC) ?

Hardware Components are everything you can find on a SKAARHOJ controller or any RawPanel compatible device (eg: xpanel-applications).

Some physical components, such as a Joystick can be represented as multiple HardwareComponents in Reactor (in this case Up/Down, Left/Right and Rotate)

There are 4 basic types of hardware components:

  • Buttons (Binary Inputs)
  • Faders / potentiometers (Analog Inputs)
  • Encoders (Pulsed Inputs)
  • Joysticks (Speed Inputs)

Additionally these could have different kinds of displays linked to them.

Buttons can have different kinds of color LEDs to show status.

Larger Displays can also consist of different Tiles that allow you to configure individual parts separately in an easy way.

What is a Behavior ?

To configure what a specific component does and shows we need to configure it's Behavior. Click any Hardware component on the configurator view and you will get to the Behavior that is defined on it. In case there is no Behavior created yet for this component the inspector will show you a palette of pre-configured Behaviors based on the devices you have added on HomeScreen.

Tip

Clicked on a Component and found a purple Generator ? This component's behavior is likely defined by a table from home screen. You can simply overlay it by selecting the UserSection in the section dropdown. If you like to know more about this or modify the generator please see the chapter on generators

Selecting a Parameter

To select a Behavior simply select the component you want to change. If there is no behavior yet on the component you can see the behavior palette in the inspector. You can select any preconfigured parameter from the list of your devices.

create-behavior-inspector

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 and lets you change to a different one.

Manually changing parameter in a Behavior

To edit the parameter inside of a behavior manually (without using the pre-configured behaviors from the palette) simply click the Show More button. A yellow pen icon will appear next to the name of the parameter field. Simply click it and use the parameter reference helper window to configure the parameter you want to choose.

create-behavior-inspector
create-behavior-inspector

Edit the parameter using the Helper Window

 

Once you click submit you will be presented with this window:

Automatic Behavior Configuration

If you click the green Continue 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 fast to add almost any parameter to a component.

In some cases you might want to keep the settings you have configured manually on the Behavior. In this cases just click Keep current and reactor will only change the parameter reference.

Changing Template Behavior

Reactor does it's best to choose the correct Template Behavior for your behavior. It does so based on what it knows about the type of component and the parameter you select. Sometimes you might still want to change this. To do so click Show More. This will show the Template Behavior dropdown

The Template Behavior shows the most commonly used templates at the top. If fou have created Template Behaviors yourself they will also be shown. If you can not find what you are looking for click Show All inside of the dropdown to show more included Template Behaviors of reactor

Available Template Behaviors

Here is a list of the most important Template Behaviors included in Reactor.

None

Start with no selected Template Behavior

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 a 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 whe you want to move up and down a value using an encoder or 4way 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 longer 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 .01 values of a degree

Change by step with limited values

Sometimes a parameter might have many options to choose from but you want to limit the possible options that can be selected with the current button or encoder. Use this Settings template to define several valid options that can be set for the parameter

Example: Making an Encoder only switch between 3 certain WhiteBalance modes (eg Manual/Preset1/Preset2)

Change by step with confirmation

Use this Template Behavior on encoders and 4 way buttons if you want to have them not immediately change the value, but let you select and change by pressing down.

If no change is confirmed the value shown will jump back to the current value after the specified time.1

Example: Loading a new setup file on an Arri Camera. On an encoder use left and right to select first then press down to confirm.

Change a value on fader / potentiometer

This is the default Template Behavior to use when 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 to use when mapping a parameter to a motorized fader. It will correctly send back the position to the fader if the value changes in the system.

Example: Controlling Iris using a ColorFlyV2 Fader

Toggle two options

Choose this Template Behavior for any kind of On/Off, Show/Hide, Enable/Disable scenarios. The button will light up bright once the function is activated and show dimmed if not.

Example: Turning on and off bars on a camera

Toggle on hold

This Template Behavior can be used similar to the above, but it will only react after pushing down for a specified amount of time, defaults to 1000 milliseconds

Example: A NETIO Power outlet shall only be toggled when the button is held down for one second

Trigger Action

Use this template for all kind of one-shot parameters (commands)

Example: Triggering OnePush Autofocus on a camera

Speed parameter

This is the default Template Behavior for mapping things to a speed component (Joysticks). But it can also be used to control speed commands from other components like encoders

Example: Control Pan Speed using a joystick

Binary Output (for GPO)

This Template Behavior uses the parameter to set or clear the Output of a GPO contact on RCPs or LinkIO boxes.

Example: map a TallyFlag 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 it is released it is set to off.

Useful for GPI Inputs

Example: Mapping Record to the state of a GPI closed contact of an RCP

Display value (without control)

Show a value that does not provide control, or deliberately lock control of a value.

Example: Show 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

1

Before Reactor v2.0.5-pre5 this needed a ':Confirm:1000' modifier and would only work on devicecore parameters. In any later versions this Masterbehavior will work without any extra config steps. The old SettingsTemplate used to be 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 controllers menus and components is the so called "LayerTree". 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 see that these visibilities can be controlled by all kinds of Conditions, but for now: lets take a closer look at how the tree works.

Info

Tip: The tree is hidden by default. Check this page to see how to open it: Configurator Layout

The inverted tree

When looking at the tree you will notice that it does not unfold as in other applications (like a file browser). This is because we are looking at the tree from above like we are looking at the controller, layers and behaviors on top will be visible first, layers and behaviors further down might be covered.

The tree's Root Layer is the very base on the bottom. Layers can be opened and collapsed to show their sub layers (branches).

Multiple Files make up the tree

The Tree can be the combination of one or more layer files. The root layer is always the one defined by the current reactor project, but it can include other files that then get appended on the layer that includes them. To add a layerfile you can use the Included Layer File section in the layer's inspector window. When looking at the tree you can identify the places where other files have been included.

Having the tree split into separate files allows to reuse parts of the configuration in other places. This is sometimes referred to as Snippets. In our default configuration this is an essential concept, allowing to quickly switch out subconfigs like for example TallyForwarding or RoutingTriggers.

image
Create a sub layer in a separate file in the "Included Layer Files" section of the inspector
image
myimportedlayer and its child layers is defined in a separate file

Layer Visibility and Behaviors

In the tree every layer can have an Active-If condition. Depending on this condition the layer is active or hidden. When looking at the tree in the configurator you can see if a layer is currently visible by looking at the blue border on the left side. If it is visible the layer is active, else it is hidden.

When a layer is hidden in the tree all it's elements are not used anymore. Behaviors defined on the layer, variables, sub layers, virtual triggers, layer scripts and other elements will also be hidden from the controller.

In the simplified example you can see the root layer. It defines a Behavior called Behavior1. As the layer 2 above redefines the behavior, the one that will be shown on the controller is the one defined on layer 2, as it is higher up in the tree. The Behavior Behavior2 is not covered and therefore the definition on the root layer is the active one.

example tree
Example Layer Tree

Tree Elements

Layers in the tree include the definition of every other configuration element. These include:

  • Behaviors
  • Variables
  • Virtual Triggers
  • Flags
  • PresetKinds
  • Template Behaviors (aka MasterBehaviors)
  • Constant Set Tables
  • KeyMaps

In the tree view you can see most of these elements to make it easier to find them, and the layer that they are defined on. You can use the tree search function in the top of the tree to find them quicker. Additionally you can select which elements of the tree are shown.

image
Use the tree search function to find elements quickly

Inheritance

When a tree element is defined on a layer it also gets inherited by all of its sub layers. Lets 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 goes for all behaviors of sub layers of layer 2, in this case layer2.1

varinherit
myvariable gets inherited by _layer 2.1_ from _layer 2_

By following this basic concept we can understand which tree elements are available to which behaviors and layers. 1

Types of tree elements

Lets take a look at the different tree elements and their functions

Behaviors

Behaviors are shown in the tree with their names. The color indicates if the behavior is selected and if it is visible (or covered)

When a behavior is shown in

  • blue it is the currently visible.
  • green it is the currently visible and selected.
  • grey it is the currently hidden (covered by a different behavior above).
  • orange it is the currently visible and selected.

Variables

Variables are shown in the tree with their key. Variables can have a key and a name, the name is a friendly name that will be shown, while the key is the actual reference to this variable that will be used in all Parameter References pointing to it. Changing the name will just make this variable show up different in several places, while changing it's key will actually break it's links to other points in the configuration.

Next to the variable you can also see it's current value. A variable can have more than 1 value at once, if that is the case the current values will be shown next to each other separated by commas

variable-in-tree
1: Variable Key, 2: Variable Friendly Name, 3: this variable currently has 3 values

KeyMaps

A KeyMap can map the behavior names to different ones. Most of the time the keymaps are managed automatically by the configurator.

Any component of panel has a fixed address at the beginning. These have the following format

_p<panelID>.<componentID>

For example: _p1.15 (Panel 1, Component 15) or _p3.23 (Panel 3, Component 23)

To make our configurations compatible with multiple panels and to make them more understandable we use the keymap to map these addresses to a name.

A KeyMap can contain different kinds of mappings:

  • Component address to behavior name: This is done to make the components have proper names in hte configurator
  • Behavior name to behavior name: Remap a behavior alias to a different one in the layers below. Often used when a config is remapped to a different set of buttons
  • Panel Wildcard (eg: _p1.*) to Panel Wildcard: 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 combinations with the inclusion of different layer files. This use case id often used in combination with including layer files as described before (See Multiple Files make up the tree) to remap the ids used in the included config.

The KeyMap is shown in the tree on the layer where it is defined and it's mapping is valid for the layer itself and all its sub layers, like the inheritance of any other tree element.

rootlayer keymap
The KeyMap defined on the root layer, mapping component addresses to behavior names
inpector keymap
Contents of root layer keymap

Virtual Triggers

Virtual Triggers are defined on layers in the tree. When a layer becomes hidden the virtual trigger will also not be executed anymore. See more about virtual triggers in the chapter Virtual Triggers

PresetKinds

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 Flag Groups

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 many times in your configuration you might want to create a Template Behavior yourself. In Reactor Setting Templates are also called MasterBehaviors.

You can create a Template Behavior on any layer and configure it to your needs. After this you can select the new template on all other Behaviors (in the scope of inheritance) See more in the chapter Custom Template Behaviors.

Constant Set Tables

Constant Set Tables are a Table structure that can be used for several things in Reactor:

For Example:

  • Storing configuration that can be changed directly on the home screen
  • Generating Pages of Behaviors based on Table Rows
  • Creating several Virtual Triggers based on TableRows

As all other tree elements they follow inheritance. Learn more about the usage of them here: Generators and Constantsets.

Examples of Settings Tables in default configurations are:

Layer Paths

Technically every layer has a layer has a path. Paths are denoted for example like this: 0/1/4/1/

0/ always references the root layer. 0/0/ references the top most child layer of the root layer, and so on.

image
Layer Paths in the example tree

Knowledge of the layer paths is not required when you want to use reactor, but it can be useful to develop a better understanding of the system.

1

Variables and ConstantSets can also have more advanced options that change how inheritance applies to them (like ExpandScope, Capture and Always Define). This is an advanced topic and will be covered later on. Please see the corresponding tooltips in the configurator for more info.

Variables and Conditions

To understand better how menus 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
  • if the engineering menu is open
  • and much more...

Types of Variables

Reactor variables can have 2 main types:

  • Optionlist: a list of options, each options can also have a label. Option values can be numbers or strings
  • Range: A numeric range with a minimum and a maximum and a default (or center) value.

When a variable gets set in the system the system will check if the value that is set matches the possible values defined. 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 config and add a variable

modes
modes

When a variable is created its value defaults to the first value unless otherwise specified. From that point on you can now 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 it's child layers. This follows Tree Inheritance.

Inheritance Example

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) can NOT use the variable, as they do not inherit it's 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 variable 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 1 value

One Variable, multiple values

Any variable in reactor can be seen as an array of values. Wile 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 SetMode in the EventHandler config:

modes

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 in case it is already in

Example: In a setup with multiple cameras you want to have one button controlling gain on several cameras at once. You can setup buttons to add more than 1 ID to the DeviceIndex to make this possible. ParameterReferences that already reference the Var:DeviceIndex will now control all Devices in the array.

Variable with multiple active values shown in tree
Setting multiple variable values using force set in the bottom of the variable inspector (open Show More)

Conditions

Conditions are a structure used in many places in reactor. They are a text string that combine multiple Parameters into a condition that can ultimately evaluate to be either "true" or "false".

Some example places where they are used are:

  • Active-If Condition on Layers: determine if a layer is shown (rendered) or not
  • Active-If Conditions on FeedBackHandlers Layers: determine if a certain FeedBack (eg: Text, Color, ...) is shown or not
  • Active-If Conditions on EventHandlers: determine if a certain interaction (eg: left edge press) is active or not
  • Conditions on VirtualTriggers: determine if a VirtualTrigger simulates an active button press (See text)
  • and several other places...

The Condition Helper Window

When you see a condition in reactor you can simply click it once and open the condition helper window.

Tip

If you would like to directly edit it as a string simply double click tie field

The helper window can make it quick to create the condition you need. You can:

  1. select ParameterReferences by clicking the yellow pencil icons or just start typing values into the text field
  2. change the comparison operator in the middle to check
  3. add logical branches to your conditions
  4. change how your conditions are combined (AND or OR)
  5. edit the raw string value of your condition
  6. 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 so:

<Value or ParameterReference> <comparison operator> <Value or ParameterReference>

Comparison Operators

the basic operators for comparing values are:

  • == equals
  • != is not equal
  • <= smaller than (only for numeric values)
  • >= bigger than (only for numeric values)

Tip

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 brackets ( ) 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) 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

Checking against empty or zero values

When checking if a value is empty one needs to remember that there are different possibilities here:

  • 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 usecase for variables and conditions is to switch a layer on and off. To do so simply create a Variable, we use "ShowCustomButtons" as the name for this example

In the variable settings set it to "Options" (1), click add option (2) and add a true and false option (3). We can add labels (4) to these options as well, lets type in "Show" and "Hide" for the example.

The next step is to add our custom layer.

(If the tree is not open yet click the green arrow in the left top corner (1))

We can click the config layer (2) of our controllers config and click the add child layer button (3).

Lets add 2 Behaviors on 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 encoder 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 on our layer. Therefore click the layer, and select Add Active-If Condition in the inspector.

On the left side we will click the yellow pen and select our variable (ShowCustomButtons). On the right side we 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 th encoder, it should look like so:

The Parameter Reference (IOReference)

One of the fundamental concepts in reactor is the Parameter Reference, also called IO Reference. This is a text string that can be used to address any kind of parameter inside of Reactor. Parameter References are similar to URLs as encountered on websites, 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 it's settings
  • A value of a specific Constant Set Table

Additionally the parameter reference can also include a simple value, like a number or a text string

Configuring Parameter References using the helper window

Everywhere in Reactor where you find a Parameter Reference you can open a helper window. This will allow you to select what you need in the easiest way. You can also choose to configure the parameter reference manually if you wish.

parameter reference helper window
parameter reference helper window

There are several parts to the helper window:

  1. In the top you can see the actual text string that is being built by the options you choose
  2. Select the type of parameter reference you want to create
  3. Configure the parameter reference, in this case we select the parameter of a device. The form will show more options when you make your selections.
  4. Click the Edit Raw button to directly edit the text string of the parameter reference

Manual Configuration

To manually configure a parameter reference you must first understand the format, and then the possible options that make up the reference.

Basic Format

The basic format looks like this:

Type:part1/part2/part3:modifier1:modifier2:modifier3

Additionally some of the parts can include nested IOreferences using curly brackets { }. This means for example that you can use a different IOReference to select a certain device id. While this is possible on some combinations it is not universally valid. See the specific option in the reference below for more info on if it can be templated.

It is also possible to create an IOReference that points to multiple parameters by 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 simply be written as they are, as long as they do not include a colon.

For example: 3, true, or page1

Sometimes you might also want to specify an array of values. In this case the values are enclosed in brackets, with individual values separated by commas, for example, [red, green, blue].

In special cases where your value contains a lot of special character you might want to prefix the value with String: to explicitly tell reactor that the rest of the value is a literal value.

Eg: String:{"DATA":"Custom JSON value"}

Variables (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:)

Parameters of devices follow the following syntax:

DC:[name of the core1]/[device index]/[name of parameter]/[dimension1 index]/[dimension2 index]/...:Modifiers

The device index and the dimension indexes can be set in different ways. They are IOReferences itself, meaning that it can be a Variable, BehaviorConstant or any other reference. If this reference would include slashes (/) it needs to be wrapped in curly braces {}

Examples: DC:bmd-atem/{Var:DeviceIndex}/AuxSource/{Var:AuxChannel}/

Reference to AUX sources on the ATEM switcher with Device ID found in "Var:DeviceIndex" and in the AUX Channel denoted by "Var:AuxChannel".
Both examples provided are identical. In this scenario, encapsulating the nested IO Reference is not required, as there are no forward slashes included that might interfere with the parsing process.

Panel Settings (Panels)

Panel Parameters like brightness and sleep can be controlled using this type of parameter reference

The basic format looks like this:

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 it's id
  • Panel - Address a specific panel by it's id
  • CanvasOfPanel - Address the whole canvas (panel group) of the panel specified by the target ID

The target index can be set in different ways. It is an IOReferences itself, meaning that it can be a Variable, BehaviorConstant or any other reference. If this reference would include slashes (/) it needs to be wrapped in curly braces {}

Important: Normally the way addressing is done in reactor for panel parameters is like so: Panels:CanvasOfPanel/Behavior:Panels/[panel parameter type]. This makes sure we always address the full panel group of the panel that the behavior is mapped to. In most cases this is the best way to do it.

Panel Parameter Type can be one of the following:

  • SleepTime (minutes)
  • DimTime (in minutes)
  • DisplayBrightness (0-8)
  • LEDBrightness (0-8)
  • GlobalBrightness (0-8)
  • Sleep (binary: "on", "off") - (Is reset by the panel when it wakes up again. It's probed once a second, so it can feel a little like a "hold down" function)
  • ResetSleepTimer (one-shot trigger)
  • Name (read only)
  • Model (read only)

System Values (System:)

System Variables can be accessed using the System parameter Type.

Current list of possible options:

  • System:PanelLock - Lock function for the whole of reactor

  • System:IPAddress - Show the IP Address of reactor. Can also change the system IP using a set value command or the SKAARHOJ:ChangeIP Template Behavior

  • System:CurrentProject - Allows to trigger a change of projects using SetValue

  • System:RestartEngine - Perform a restart of reactors engine, like switching projects

  • System:ProjectTitle - Show current Project title

  • System:ConfigTitle - Show current name of root layer

  • System:UptimeFormatted - Show 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, eg. "Down (T)" if a four way buttons top edge was pressed down.

  • System:Panels:LastEventSource - The HWC source of last event, including panel ID, on 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 - Name of devices. idx is just an index.

  • System:Warnings - Total number of warnings in Reactor

  • System:Errors - Total number of errors in Reactor

The current Behavior and it's settings (Behavior)

Using Behavior Parameters you can reference some of the values configured for the current Behavior or show some information about it. This is used in many of the built in Template Behaviors

Format: Behavior:[sub type]:[additional type]:Modifiers...

Subtypes

  • IOReference (main parameter reference)

Using this subtype the main Parameter in the Behavior can be referenced. Additionally Modifiers can be added. This way you can refer to the main parameters value or name without having to hardcode it in other parts of a behavior (like Feedbacks or Actions)

Examples: Behavior:IOReference:Name (Display the main parameters Name) or Behavior:IOReference:Current (Display the main parameters current value)

  • Const (BehaviorConstant)

Using Behavior:Const:[constant key] you can access constant fields of the behavior. This way you can create SettingsTemplates for behaviors that have certain constant fields that can be customized in an easy way. This is used in many of the 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. Eg. "0/3/0/A3"

  • ID - Returns the behaviors 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 current running scripts of this behavior. See

  • LastEvent Access information about the last hardware event (trigger) received by the behavior.

    IO ReferenceComment
    Behavior:LastEvent:TypeType of last event. Options: Binary, Pulsed, Analog, Speed
    Behavior:LastEvent:TimeToNow:[Limit]This 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:PressedReturns whether the last binary trigger was pressed (ActDown) or not (ActUp). Options: true, false
    Behavior:LastEvent/Binary:EdgeReturns which edge the last binary trigger sent. Options: NoEdge, Top, Left, Bottom, Right, Encoder
    Behavior:LastEvent/Pulsed:DirectionReturns the direction of the last pulsed trigger received
    Options: Up, Down
    Behavior:LastEvent/Pulsed:ValueReturns the value of the last pulsed trigger
    Behavior:LastEvent/Analog:ValueReturns the value of the last analog trigger (0 to 1000)
    Behavior:LastEvent/Speed:ValueReturns 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 that has passed since the last accepted trigger for the specified Action. It is recommended to set a maximum limit for performance reasons in reactor.

    Behavior:Events/[Action Name]:SequenceStep: The current sequence step being executed (See Binary Sequence)

Presets (Presets)  

Preset Parameters are used to control reactors Parameter Preset Engine. You can learn more about here: Parameter Preset Engine

The basic Format looks like this:

Preset:[preset kind name]/[command]/[preset index]/[device index]/

Command can be one of the following:

  • Store
  • Recall
  • Delete

The preset index and the device indexes can be set in different ways. They are IOReferences itself, meaning that it can be a Variable, BehaviorConstant or any other reference. If this reference would include slashes (/) it needs to be wrapped in curly braces {}

Flags (Flag)  

Flags can be referenced to set, clear or display them. The basic format looks like this:

Flag:[flag group name]/[flag color]/[flag number]:modifier1:modifier2:modifier3

Make sure you have created a flag group before to use this. More info can be found here Flag Groups

The Flag color can be selected from the fixes list of [Red, Gree, Blue, White]

Finally a index between 0 and 99 can be selected

Note: Flags are generally used for SKAARHOJ Default Tally Forwarding and Routing Triggers. otherwise most things that can be done with flags can also be achieved with variables.

Value from Constant Set Tables (Const)  

This type of parameter reference allows read only access to a value in a constant set table directly.

This can be useful to access settings values defined on the home screen or access values of 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 looks like this:

Const:[constant set name]/[row index]/[constant name (column)]/:Modifiers...

Row Index can be set in different ways. It is an IOReferences itself, meaning that it can be a Variable, BehaviorConstant or any other reference. If this reference would include slashes (/) it needs to be wrapped in curly braces {}

Examples:

Const:CameraSelector/0/CameraName

Returns the value of the constant called "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), because the variable's value is reduced by one when inserted as the value for the row index. (:Current:Offset:-1)

General Modifiers

Modifiers are used by certain Parameter References to access additional information from the parameter or present the data in a different format. Modifiers are simply appended to the Parameter reference like so:

ParameterReference:Modifier1:Modifier2 ...

Most of the time modifier combinations are dependent on their order.

Not all Parameter types support all modifiers. Reactor will actively limit the selection based on your Parameter Selection in the helper window.

For reference here is a complete list:

ModifierCommentDCVarConst
(no modifiers)Without any modifiers, returns the values.YesYesYes
NameReturns the name of the reference, such as a parameter or variable name.YesYesYes
DefaultReturns the default values of the IO reference.YesYes-
Default:NameReturns the names/labels of the default values of the IO reference.YesYes-
AllReturns all option values for a parameter. For an integer range with less than 100 values, it will calculate and return that as an option list. (June 23)YesYesNo
ExistsReturns "true" if the reference exists.YesYesYes
MutableReturns "true" if the reference can be changed.YesYesYes
AssumedReturns "true" if a parameter is assumed in the core.Yes--
FineStepsReturns the recommended fine steps for a Device Core; otherwise, returns 1.Yes--
CoarseStepsReturns the recommended coarse steps for a Device Core; otherwise, returns 10.Yes--
ASCIIOnlyReturns true if only ASCII characters are found in the return value.YesYesYes
Current
CurrentReturns the current values. Same as not using "Current" modifier.YesYesYes
Current:NameReturns the names of the current values.YesYesYes
Current:NormalizedReturns the normalized value in the range of 0-1000.YesYesNo
Current:NormalizedInvertedReturns the normalized value in the inverted range of 1000-0.YesYesNo
Current:PercentReturns the normalized value in the range of 0-100.YesYesNo
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.YesYesNo
Current:IndexReturns the index of the current value from the option list, starting with zero. Works only for parameters and variables with Option Lists, not ranges.YesYesNo
Current:CountReturns the number of values in the IO reference array.YesYesYes
Current:Join:TokenReturns an IO reference with a single value, a concatenation of all values it had, separated by the Token string.YesYesYes
Current:SingleValue:IndexReturns a single value out of the current values by indexYesYesNo
Current:Offset:[int]Returns the value with [int] added to it.YesYesYes
Current:BufferTimeToNowReturns the time in milliseconds from the buffered value time out 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.YesYesNo
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference]:NameReturns the name of the option value with index [int].YesYesNo
Index:[integer comma list incl. "Last" keyword/ Constant or Variable Reference]:ExistsReturns true if the index exists.YesYesNo
Index:[integer comma list incl. "Last" keyword / Constant or Variable Reference]:RawReturns the raw index value of the option value with index [int].YesYesNo
DimensionName
DimensionName:[int]:[optional int]Returns the name of the specified dimension (0 index) if 2 integers are specified returns the name of the specified ElementYesNoNo
ID
ID:[integer / Constant or Variable Reference]Return an option by its value ID (different than index on some cores) also supports :Name and :ExistsYesYesNo
1

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 (formally known as Event Handlers)

Feedback Handlers

FeedbackHandlers are the parts of the behavior that define what a component shows. They can adjust things the LED color, display text and elements and even the position of a motor fader.

Every Behavior and Layer has a Default Feedback. This is what is shown automatically. Additionally there are the so called Conditional Feedbacks, that are only active when their Active-If condition returns true.

Lets 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 more easy to understand

Intensity

Intensity defines the strength of the LED light. It can be Off, Dimmed or On.

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

Text Display

Title

The title appears on top of the display.

Title Font

Select a font variation for the title.

Solid Title Bar

Select if the Title Bar shall have a solid white background of 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

With Solid Header Bar

Without Solid Header Bar

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 {}

Textline Helper Window

Text Size

Select a specific test 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 gets longer than 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 that will then be shown, so the displays can fully support unicode.

(Note: This might sometimes change the rendering slightly or modify text size and font)

Icons

Icons

Set a condition when to show the lock icon

State Icon NoAccess

Set a condition when to show the no access (forbidden sign)

State Icon Fine

Set a condition 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 defines what the component actually does when it is interacted with in different ways. There can be multiple Actions on every Behavior, to add different kinds of possible interactions, or to make the component control different parameters.

Actions can also have an Active-If condition, but in difference to Conditional Feedbacks the Actions are always active by default.

General Action Settings

Lets take a look at the available fields in an Action:

Handler Type

Handler Type is a special field, as it will change the other available fields to configure.

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 BinaryComponent can create ActDown and ActUp triggers
  • A PulsedComponent can create PulsedValue triggers like +1 and -1
  • A AnalogComponent can create a AnalogValue triggers from 0 to 1000
  • A SpeedComponent can create a SpeedValue triggers from -500 to +500, it will always reset to 0 when released.

After the Handler Type has been selected you can still add PreProcessors to the Action, that define how to react when a different trigger type comes in.

General Action Fields

Parameter

Each Action can specify a different parameter to control. If no parameter is specified the one defined in 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 stays disabled and is not used.

Example: This can be used to specify different Actions dependent 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

Description

Give the Action a general description

Specific Settings: Binary

Binary Type

When set you can specify if this handler only reacts on a down press (ActDown) or only on a release (ActUp). When not set it will fire in both cases

EdgeFilter

When mapped to a 4 way button or encoder you can use this setting to filter for a specific event, like only pressing 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 weh 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 after each other, even for different parameters. You can even specify a different parameter on each step. Simply choose sequence and add several steps

    Binary Sequence Example
  • 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 so called Rollover is allowed. Rollover means that when the end of the value range of the parameter is reached the next step will jump to the other end of the range again.

Fine Step

Specify the fine Step Size for stepping through the parameter. You can either use the default for the behaviors parameter (Behavior:IOReference:FineSteps) or specify your own. For example: selecting 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 fine coarse Step Size for stepping through the parameter. You can either use the default for the behaviors parameter (Behavior:IOReference:CoarseSteps) or specify your own. For example: selecting 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 step (when false) or coarse step (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 this is 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 that is controlled has a different value than the analog component is set to currently. It specifies the take over strategy

For example: Iris is mapped to a RCP Joystick but has been changed on the camera in the meanwhile.

  • Double Linear: Double linear will map the value linearly to the desired point
  • None: Value will jump to the correct mapped value when 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 Pre processors 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 EventHandlers from Template Behaviors

When adding Feedback handlers to a behavior that uses a Template Behavior they will be combined with the ones from the Template. You can see the ones defined on the template marked as Inherited.

Feedback Handlers that have the same index number in the template and the behavior will be merged (overridden). The same goes for Actions with the same name

Above example shows: After making a change to the feedback handler with index 10 to the color we can still see the fields that inherits from the Template Behavior's Feedback handler with index 10

Virtual Triggers

While a component can generate triggers sometimes you might also want to trigger something based on an external event, eg the change of a parameter of one of your switchers. To facilitate this reactor can generate a trigger based on

  • Conditions
  • Time
  • Value Changes

Modes

Virtual triggers can use one of the following modes:

Binary: Use a condition, simulates a button press

In Binary mode a condition will be interpreted like a Binary trigger (basically imitating a button). When the condition becomes true a button press is simulated (ActDown trigger) and a release (ActUp trigger) when it becomes false

Change: Trigger when a external value changes

In change mode you can select any parameter. When the parameter changes or updates in any way the trigger is fired and simulate a button press (like Binary)

Analog: Simulate a fader move

In Analog mode the selected parameter becomes an Analog Trigger (basically imitating a fader). Every time the value is changed 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 of when your trigger will be executed using cron like syntax. Every time the specified time is reached the Virtual trigger will send a Binary trigger (basically a buttonpress) to the defined behavior

See below on how to configure the time format

HoldGroup

Special VirtualTrigger type to facilitate usecases like a Joystick HoldGroup with multiple RCPs 1

Creating and configuring Virtual Triggers

Like many other things VirtualTriggers are an element of the tree. They are usually defined on a layer. To keep things simple we recommend to create VirtualTriggers on the configuration layer related to your panel. You can select it using the layer icon next to the Section Selector.

alt text

Then go ahead and add a VirtualTrigger

create virtual trigger

After creation click on the name to edit it. You will see this in you inspector:

edit virtual trigger
  1. When adding a virtual trigger you first need to select its mode using the dropdown

  2. After creating a trigger select either a Condition, Parameter Reference or time schedule.

  3. Click Create to create a Behavior. Make an edit

  4. Click on the Behavior to configure a Behavior that is used for the Virtual Trigger

Configuring 'Schedule' Virtual Triggers

Schedule Virtual triggers use configuration format called Cron Cron is a Linux ppplication that schedules a command or script on servers to run automatically at a specified time and date. 

The syntax works in the following way

******
Field nameSecondsMinutesHoursDay of monthMonthDay of week
Allowed values0-590-590-231-311-12 or
JAN-DEC
0-6 or
SUN-SAT
Allowed special characters* / , -* / , -* / , -* / , - ?* / , -* / , - ?

All 6 points of information is required.

Allowed special characters explained:

  • Asterisk ( * ) The asterisk indicates that the cron expression will match for all values of the field; e.g., using an asterisk in the 5th field (month) would indicate every month.

  • Slash ( / ) Slashes are used to 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 to the form "first-last/...", that is, an increment over the largest possible range of the field. The form "N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the increment until the end of that specific range. It does not wrap around.

  • Comma ( , ) Commas are used to separate items of a list. For example, using "MON,WED,FRI" in the 5th field (day of week) would mean Mondays, Wednesdays and Fridays.

  • Hyphen ( - ) Hyphens are used to define ranges. For example, 9-17 would indicate every hour between 9am and 5pm inclusive.

  • Question mark ( ? ) Question mark may be used instead of '*' for leaving either day-of-month or day-of-week blank.

Alternatively we also allow these inputs:

EntryDescriptionEquivalent To
@yearly (or @annually)Run once a year, midnight, Jan. 1st0 0 0 1 1 *
@monthlyRun once a month, midnight, first of month0 0 0 1 * *
@weeklyRun once a week, midnight between Sat/Sun0 0 0 * * 0
@daily (or @midnight)Run once a day, midnight0 0 0 * * *
@hourlyRun once an hour, beginning of hour0 0 * * * *

Videos

We have currently 3 videos over on youtube channel documenting Virtual Trigger Configuration:

1
This is an advanced feature

Advanced Topics

In this chapter we will take a look into some more advanced topics of reactor's configuration. Some of these concepts are used heavily in our default configurations, and learning about them can give a better understanding of what is going on inside our built-in configurations.

We will take a look at:

Custom Template Behaviors (formally known as Master Behaviors)

To simplify repetitive configuration tasks you can create your own Template Behaviors. These are sometimes referred to as Master Behaviors in Reactor (like a MasterSlide in a Powerpoint or Keynote Presentation).

Lets say you want to create for example a custom behavior for an Encoder that performs a preset recall left turn and a preset store push on a right turn. Additionally you want such an encoder to have a green ring light.

Afterwards you want to reuse this encoder on several places inside your configuration, controlling different preset IDs. That is a 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 to create 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.

image

Then go ahead and add a Template Behavior. Additionally you can use the "CopyFrom" function to copy the current behavior of a component into a new Template Behavior.

image
Create a Template Behavior

After that 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 can often be useful to make certain parts of the nested configuration available on the top of the Behavior form. This is best done using Constants.

Constants can be defined by adding Constant Definitions to your Template Behavior. Type a name for the new Constant (1) and press create (2)

image
Editing the new Constant, make sure to choose a Type for the new field (1)

Once added the new fields will be available on the top of the form. (3)

Click on the definition to edit the properties of the new Field. You can choose its type, choose if it shall have an extra 'label' and limit how many values it can hold.

image
Editing the new Constant, make sure to choose a Type for the new field (1)

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.

image
Selecting the new Template on a normal Behavior
1

Keep in mind that some features of the form might not be available, like 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 that each have a color and a label.

These colors can be

  • 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 to create 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.

image

Then go ahead and add a Flag Group.

flag group

Once you have created a flag group you can go and use it straight 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 quickly make 2 controllers share the same tally information, but also to make sure tally is seperated for controllers (by using a different number for the index)

flag group

Controlling Flags from a Behavior

Flags can easily be set from a Behavior or used in a Condition. To do that 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. On 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

flag group 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 you are working on your configuration.

(Note: the amount of flags is technically unlimited, but only the first 150 are shown in the inspector for performance reasons)

flag group control in show more

SKAARHOJ Default Configurations

Out of the box we try to provide you with the quickest possible setup to get started controlling your devices. To do so we have created a curated set of configurations, that make it easy to add and combine different devices from different manufacturers with our panels.

Panel Classes

To be able to make systematic configurations we created our Configuration Classes. These classes categorizes every SKAARHOJ Panel for 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

  • Mega Panel configurations

Camera Light, Pro and Standard Class

The Pro and Standard Class compatible panels are our shading and PTZ panels. A ProClass panel is defined by having a menu based around 8 standard Encoders, a Standard Class panel has a menu based around 4 standard encoders,

Usually these configurations are 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
  • RCP V2
  • PTZ View (aka MKA 2)
  • INLINE 22 + XC 7

Configuration Options

In these configurations every panel has a CameraSelector, a TallyForwardingConfig and a RoutingTriggerConfig

The Camera Selector is where you can add different Cameras. Every Panel has a button row dedicated to selecting the camera. Depending on the devicecore used to connect to this camera a different menu will be loaded for the camera when it is selected. You can also configure its name, tally index and routing index in the same Constant Set Table

Switcher Class configurations

Switcher Class configurations are meant for our live switching controllers and device cores. They will provide you with all the most common functions that most people will need to control a switcher system. But we also provide many layers of advanced features and options, that allow you to control most aspects of your switcher device, like our 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 configurations provided by SKAARHOJ that work with controllers that have at least 4 Faders as their main components.

To use them in Reactor, select a "Generic Audio" configuration for your panel, then fill the channel config 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 are configurations that work with a Quick Bar and selected controllers that have a section of 6 4-way buttons. To use them in Reactor, select a configuration supporting Quick Class for your panel, then fill the Quick Class selector with devices you want to control.

See here for more info:

Routing Configurations

Routing Configurations map router devices to utility controllers like the Rack Fly series or the QuickBar

MegaPanel configurations

The SKAARHOJ MegaPanel configurations usually consist out of one big configuration for several controllers, most of the time based around a TBlock (Left or Right)

Then several MK48 controllers can be added. One ME Row usually consists out of 2x MK48 and 1 TBlock.

Additional modules that fit the MegaPanel frame are for example the WaveBoardMini or the PTZ View

Understanding Sections in default configs

The default configurations usually provide a few easily configurable sections.

camera-adjustment-sections

User Section (2)

The User Section exists on all SKAARHOJ default configurations. It covers almost all components of a panel. When you create a behavior on the User Section the new behavior will overlay the ones defined below, therefore allowing you to easily change the function of a button even if it is defined somewhere deep in the default configuration.

Camera Adjustments (1)

The Camera Adjustments section is present on all camera related configurations (light/standard/pro classes). Depending on the selected camera the corresponding menu for this specific device core is loaded and can be customized here.

1

Wave Board V1 has an alternative setup utilizing the extra two buttons instead of the encoder.

Tips and Tricks

Using Context Menus

In many places in Reactor you will find context menus when using right-click to interact with things. These can help you do things faster. Here are a few examples:

  • Remove a panel faster using right click
  • Copy Variables in the Tree faster
  • Create behaviors on the controller
  • Clear out the contents of behaviors

Use shortcuts

Shortcuts are a great way to work much faster in reactor. here is a list of the most useful ones

  • cmd+e: toggle simulation mode in 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, so you can add multiple devices much faster
  • cmd+i: to quickly open the project import window

Use Copy/Paste

Many places in reactor can use copy and paste to speed up your configuration workflow. you can for example create a behavior on one component and then copy it to several others. You can also use copy and paste in many places inside of the tree view, to copy constant set tables, variables and other configuration parts between different layers.

 

Use Undo/Redo

If you ever get lost in the configurator just rest assured and know you can use undo and redo buttons to get back to all your previous changes. If you want to create yourself a "checkpoint" you can use History View (2) to create a tagged version of your config.

undo redo buttons

Batch Editing Components

The Batch Editor allows you to quickly edit several components at once. To Batch Edit multiple components simply drag a selection across several components in the configurator. If you have highlighted components that do not have a behavior yet the Inspector will offer you to create new ones for all of them from the library. Else you will see all common options of the selected Behavior to quickly edit them. In case you want to edit them individually click the table icon below to open a table view of all selected behaviors.

Using "Load Recent" inside of the Parameter Reference or Condition Helper Windows

When configuring parameters or conditions you can quickly recall the last few parameter references you have created by clicking on the Load Recent button in the top right corner of the windows.

SKAARHOJ Glossary

Here you can find an alphabethically ordered list of all terms used in SKAARHOJ Products that might need additional information

Behavior

A behavior in reactor defines how a component should behave. It consists out of Parameter and Actions and Feedbacks that enable you to define how this parameter is interacted with, and how it is displayed on your component (button, display, fader...) Additionally there are Templates for the Settings of a behavior. (See Behaviors)

BluePill

The BluePill is the brain of most modern SKAARHOJ Products. As the successor to our old Unisketch products it packs a full linux operating system into a tiny package and enables control of many devices.

Constant Set

A constant set is a Table in the Configuration. It can be used to store settings available on hte home screen and to generate layers, behaviors and virtual triggers based on its table rows.

Device Core

A devicecore is a package that can be installed on a BluePill. It acts like a driver that allows reactor to talk to your devices using different protocols.

DeviceCollection

The DeviceCollection is a file storing all configurations of the devices that reactor connects to. See Projects

devicecore-connector

DeviceCore connector is a tool that allows your BluePill to share it's device cores with other BluePills on the network.

Hardware Component (HWC)

Hardware Components are every kind of input or output component on SKAARHOJ panels. EG: Buttons, Displays, Faders, Encoders and more. (See Components)

hardware-manager

A package running on your BluePill Inside 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 RawPanel device on the network

IOReference (IOref)

Same as Parameter

LinkID

A LinkID is a reference to a different layer configuration files. It can be used inside of the tree to include sub-configurations. See

Master Behavior

Same as Template Behavior (or Settings Template). Originally named after "Master Slides" in presentation programs like Apple Keynote or Powerpoint.

PanelCollection

The PanelCollection is a file storing all configurations of panels or xpanel devices that reactor connects to. See Projects

Parameter (IOReference)

A text string that can be used to address any kind of parameter inside of Reactor. See Parameter Reference

RawPanel

RawPanel is the protocol that reactor uses to talk to panels and controllers. It has different protocol variants. Learn more on the wiki

Reactor

The main application running on your BluePill, connecting panels to devices using your configurations

Template Behavior

A Template Behavior is used to quickly configure a Behavior in Reactor for your use case. See Behaviors -> Changing Template Behavior

system-manager

System Manager is the main package running on every BluePill. It provides access to the system configuration using the webinterface, handles WiFi, logging, package updates and all other system related Tasks.

Variable

A variable in reactor is used to store information like eg the current menu page. See Learn more on the wiki