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
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'
-
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 ddd 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" 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.
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
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.
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.
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
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.
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.
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
Here you can see all projects saved on the controller.
- 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.
- You can use search 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 of reactor.
- Duplicating your project allows you to easily experiment with new configs and revert back to the previous state with ease
- Use the red trash can to delete your project
- Click Manage Used Configs to see all sub configs 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 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.
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.
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.
The Configurator
The Configurator (also sometimes called "Configuration Tab") is the main place where you can make customizations to your controller layout.
There is 4 main areas:
-
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"
-
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.
-
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.
-
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:
- 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 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.
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.
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.
Once you click submit you will be presented with this window:
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.
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
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.
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.
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.
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.
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
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
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.
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:
- Camera Selector
- Tally Config
- GPIO Mappings
- (See more here: Default configurations)
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.
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.
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
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.
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:
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.
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.
The helper window can make it quick to create the condition you need. You can:
- select ParameterReferences 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 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)
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.
There are several parts to the helper window:
- In the top you can see the actual text string that is being built by the options you choose
- Select the type of parameter reference you want to create
- 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.
- 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:
)
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:
)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
)
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:
)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
)
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 Reference Comment Behavior:LastEvent:Type Type 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: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 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
)
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
)
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
)
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:
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 an integer range with less than 100 values, it will calculate and return that as an option list. (June 23) | 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 "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, a concatenation of all values it had, separated by the Token string. | Yes | Yes | Yes |
Current:SingleValue:Index | Returns a single value out of 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 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. | 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]: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 2 integers are specified returns the name of the specified Element | Yes | No | No |
ID | ||||
ID:[integer / Constant or Variable Reference] | Return 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 (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
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 in which you want a button attract additional attention, like warnings or others.
Text Display
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
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 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
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
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
-
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:
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.
Then go ahead and add a VirtualTrigger
After creation click on the name to edit it. You will see this in you inspector:
-
When adding a virtual trigger you first need to 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. Make an edit
-
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 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 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:
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 have currently 3 videos over on youtube channel documenting Virtual Trigger Configuration:
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:
- Flags
- Custom Template Behaviors
- Settings Tables and Generators
- Scripting in Javascript
- History View
- The JSON Editor
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.
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.
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)
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.
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, 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.
Then go ahead and add a 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)
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
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)
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:
- https://wiki.skaarhoj.com/books/blue-pill-reactor/page/quick-class-configurations
- https://wiki.skaarhoj.com/books/blue-pill-reactor/page/quick-class
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.
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.
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.
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