# Advanced Configuration

Information and references which are useful for integrators using Reactor to create advanced configurations in Config tab or JSON editor.

# Advanced Fader Range Setup

<div class="ql-block" data-block-id="block-4af2cf47-fe51-47dd-96c1-d047a949a538" id="bkmrk-this-is-an-example-o">This is an example of an eventhandler that makes it so moving the full range of the physical fader only moved the top half of the actual "fader" parameter, using the "Analog to Analog" conversion and Map1:</div>[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-01/scaled-1680-/8PXimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-01/8PXimage.png)

```
"EventHandlers": {
    "change": {
        "EventPreProc": {
            "A2A": {
                "InputMapping": {
                    "Default": {
                        "Map1": {
                            "InputEnd": 1000,
                            "OutputStart": 500,
                            "OutputEnd": 1000
                        }
                    }
                }
            }
        },
        "BinarySetValues": {},
        "IOReference": {}
    }
},
```

<div class="ql-block" data-block-id="block-57ec6ed5-5b0d-46e3-a211-a6c4968f66af" id="bkmrk--0">  
</div><div class="ql-block" data-block-id="block-4ecb81e3-cc6c-4679-96d6-acbb5d6ea59a" id="bkmrk-this-does-however-co"><div class="ql-block" data-block-id="block-4ecb81e3-cc6c-4679-96d6-acbb5d6ea59a">This does however completly remove the option to go to 0 on the param, if you want that you might want this kind of code instead where Map2 makes it so the last 5% of the physical fader makes it jump down to 0 or "inf" when talking audio faders, while still keeping the scaling on the rest of the fader positions:  
</div></div>[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-01/scaled-1680-/1tgimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-01/1tgimage.png)

```
"EventHandlers": {
    "change": {
        "EventPreProc": {
            "A2A": {
                "InputMapping": {
                    "Default": {
                        "Map1": {},
                        "Map2": {
                            "InputStart": 50,
                            "InputEnd": 1000,
                            "OutputStart": 500,
                            "OutputEnd": 1000
                        }
                    }
                }
            }
        },
        "BinarySetValues": {},
        "IOReference": {}
    }
},
```

<div class="ql-block" data-block-id="block-73cbb8b3-0813-49aa-83f6-34aabcb20dcf" id="bkmrk--2">  
</div><div class="ql-block" data-block-id="block-1f58d13d-c39b-46d1-a0cf-54417389ed2a" id="bkmrk-all-values-here-are-">All Values here are set in a "Normalized" range, so this will always be a number between 0 and 1000, think of it as a % of the values on your param where 1000 = 100%, 500 = 50% and so on.</div><div class="ql-block" data-block-id="block-ec33ce14-cdbd-4d4f-8744-51be647e10d6" id="bkmrk--3">  
</div><div class="ql-block" data-block-id="block-3875e42d-2daf-4274-bba8-d5620d97dd51" id="bkmrk-inputstart-and-input">InputStart and InputEnd controls the max movement of the physical fader, so setting these can give you "deadzones" at the ends of a fader, if you'r newer quite able to hit the max and min values.</div><div class="ql-block" data-block-id="block-62f4c855-1825-460a-8bc6-ecf68c21986b" id="bkmrk--4">  
</div><div class="ql-block" data-block-id="block-dc28c0d5-56f5-4968-b5b1-7246affda738" id="bkmrk-by-default-you-would">by default you would always want them on 0 or 1000 on a fader when using map1.</div><div class="ql-block" data-block-id="block-48f22ce0-8330-49c2-83b3-6d6b3ae2ba1c" id="bkmrk-if-you%27re-using-map2">If you're using map2 you might want the lower one to be a certain % above 0, so our recommendation would be to start at 50 (5%) or 100 (10%) and experiment from there, and keeping the max on 1000.</div><div class="ql-block" data-block-id="block-6faeeab0-980d-47cf-a54e-6e522bc22d2e" id="bkmrk--5">  
</div><div class="ql-block" data-block-id="block-11d2744f-1d89-4feb-9a9f-209704b1aed1" id="bkmrk-outputstart-is-the-m">OutputStart is the minimum value you want the fader to set</div><div class="ql-block" data-block-id="block-d11800d6-2cd8-4d6d-9f67-26f01bc331fc" id="bkmrk-outputend-is-the-max">OutputEnd is the maximum value you want the fader to set</div><div class="ql-block" data-block-id="block-b63bc625-7f18-478e-8474-4c7875e9b05c" id="bkmrk--6">  
</div><div class="ql-block" data-block-id="block-e5f19871-4741-4a4e-b63a-7f98645e908f" id="bkmrk-in-the-example-above">In the example above you will see them limit the output values to only cover the upper 50% of the parameter by using the values 500 and 1000. play around with these to fit your desired outcome range.</div><div class="ql-block" data-block-id="block-e5f19871-4741-4a4e-b63a-7f98645e908f" id="bkmrk--7"></div>### Feedback

The above section only covers how to configure the eventhandler. For getting correct feedback for motorfaders, an additional step is needed.

Open the default feedback handler, and open the advanced feedback options. Select a Static Value Mapping Type of 'Coords'. Now add the Static Value Mapping Coords graph. Open the Coords popup and press '+' to add a new point. Set this new point to the same mapping as the eventhandler map. This might take some experimenting.

The Json should look something like this:

```json
"FeedbackDefault": {
        "Extended": {
            "IOReference": {},
            "StaticValueMapping": {
                "Type": "Coords",
                "CoordPairs": [
                    [
                        0,
                        0
                    ],
                    [
                        900,
                        1000
                    ],
                    [
                        1000,
                        1000
                    ]
                ]
            }
        }
    }
```

# Double click button

You may wish to detect 'double-click' or 'triple-click' on buttons. This would be useful for showing special menus (layers) - or sending commands that need a little more security.

To detect 'multiple-clicks' we use 'Event handler - preprocessor'.

In this simple guide we want to control a variable called "ShowMenu". It has just two options: off / on.  
We create a behavior on a button - It must be double-clicked in order to set "ShowMenu" to 'on'

##### Create button behavior

• right-click desired button and select 'Create behavior'  
\- Parameter: Var:ShowMenu  
\- Settings template: \[leave blank\]

##### Create Event handler

• click 'Show more' &gt; locate Event handler section &gt; enter name "DblPress" and click 'Create' &gt; click new Event handler to open it  
\- Handler type: Binary  
\- Set values: 'on'

[![behavior.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-07/scaled-1680-/behavior.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-07/behavior.png)

##### Create preprocessor (from binary)

• Locate the Event Preprocessor section &gt; next to From binary &gt; click '+' to create &gt; click it to edit  
• select 'Default' &gt; click '+' to create &gt; click 'ActDown' to open settings  
\- Repeat: Delayed &lt;-- start a timer  
\- Repeat delay: 300 &lt;-- timer lenght in milleseconds  
\- Burst count: 2 &lt;-- number of required button presses to proceed with output trigger  
\- Output trigger: ActDown

[![preprocessor.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-07/scaled-1680-/preprocessor.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-07/preprocessor.png)

With the above, you must press button 2 times within 300ms for the action to proceed (ie. set ShowMenu to 'on')

# External Camera Select

With a few simple steps it is easy to set up an external camera selector on your [Standard](https://wiki.skaarhoj.com/books/blue-pill-reactor/page/standard-class-configurations) or [Pro](https://wiki.skaarhoj.com/books/blue-pill-reactor/page/pro-class-configurations) Class Skaarhoj PTZ panels. This can be used to have the camera select of your PTZ panel follow along with a video router or video switcher or it could be used to set up an additional Skaarhoj panel for an expanded camera select.

<details id="bkmrk-external-camera-sele"><summary>External Camera Select from External Device</summary>

1. Make sure you have connected to all your needed devices on the Home Page
2. On the Home Page, open the Camera Selector settings table.  
    ![Screenshot 2025-05-26 at 11.53.11 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-53-11-am.png)
3. Enable Show Advanced in the Camera Selector  
    ![Screenshot 2025-05-26 at 11.52.36 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-52-36-am.png)
4. Input a unique number to associate with the camera in the Ext. Cam Number column. <p class="callout info"> It is recommended to use the same number as is used for the input on the triggering device. Example if using a BMD VideoHub and the camera is Input 5, set the Ext. Cam Number to 5 as well. </p>
    
    ![Screenshot 2025-05-26 at 11.53.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-53-51-am.png)
5. Navigate to the Configuration Page.
6. If setting up for a single panel only, click anywhere on the panel background (blue part) to open the Inspector on the configuration base layer. ![Screenshot 2025-05-26 at 12.01.59 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-01-59-pm.png)
7. If setting up for multiple panels within the same project, open the Configuration Tree and click on the Root Layer at the bottom.   
    ![Screenshot 2025-05-26 at 1.13.02 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-13-02-pm.png)
    
    ![Screenshot 2025-05-26 at 1.16.46 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-16-46-pm.png)
8. Create Variable called **ExternalCameraSelect** Exact name is needed as it is prebuilt into a Virtual Trigger.   
    ![Screenshot 2025-05-26 at 11.19.14 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/mJfscreenshot-2025-05-26-at-11-19-14-am.png)
9. Adjust the needed range of the Variable based on numbers used in the Camera Selector on the Home Page for the Ext. Cam Number. The range used should encompass all numbers you have defined. By default the range is 1-10, if that is all that is needed, then no adjustment is required. ![Screenshot 2025-05-26 at 12.27.42 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-27-42-pm.png)
10. Create a Virtual Trigger to set the ExternalCameraSelect Variable based on desired parameter. Name the Virtual Trigger something that will allow you to easily identify what it is doing. <p class="callout info">Shown is an example using a Blackmagic VideoHub, but it can be any other device.  
    </p>
    
    ![Screenshot 2025-05-26 at 11.20.10 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-20-10-am.png)
11. Open the newly created Virtual Trigger.
12. Set the Mode to Change.   
    ![Screenshot 2025-05-26 at 12.49.03 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-49-03-pm.png)
13. For the IF parameter, set the source of the trigger. In this instance a route of the VideoHub on a specific output will be used to change the ExternalCameraSelect variable.   
    ![Screenshot 2025-05-26 at 12.56.35 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-56-35-pm.png)
    
      
    ![Screenshot 2025-05-26 at 11.20.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-20-51-am.png)
14. For the THEN parameter, select the ExternalCameraSelect Variable   
    ![Screenshot 2025-05-26 at 12.57.57 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-57-57-pm.png)
    
    ![Screenshot 2025-05-26 at 11.21.21 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-21-21-am.png)
15. The needed Template Behavior for the THEN should be auto suggested. If it is not, you will want to select SET SPECIFIC VALUE.   
    ![Screenshot 2025-05-26 at 1.00.22 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-00-22-pm.png)
16. For the Value, set again the same parameter you used for the IF parameter. In this example it was Output 1 of a Blackmagic VideoHub. <p class="callout warning">This is why it is recommended to set the Ex. Cam Number in the Camera Selector Settings Table to match the Input number from the trigger source. It can then easily be synced. </p>
    
    ![Screenshot 2025-05-26 at 1.02.01 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-02-01-pm.png)
    
    ![Screenshot 2025-05-26 at 11.20.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/KUTscreenshot-2025-05-26-at-11-20-51-am.png)
17. The trigger is now set up and can be used. Note that any change in the source trigger's status will trigger the route (within the variable range set) but you are able to freely choose a different camera to control from the camera select row without it retriggering.

</details><details id="bkmrk-external-camera-sele-2"><summary>External Camera Select from External TCP Command</summary>

1. Add an instance of TCP Server as a device on the Home Page.   
    ![Screenshot 2025-10-30 at 11.54.34 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-11-54-34-am.png)
2. On the Home Page, open the Camera Selector settings table.  
    ![Screenshot 2025-10-30 at 12.10.45 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-10-45-pm.png)
3. Enable Show Advanced in the Camera Selector  
    ![Screenshot 2025-10-30 at 12.11.29 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-11-29-pm.png)
4. Input a unique number to associate with the camera in the Ext. Cam Number column. ![Screenshot 2025-10-30 at 12.12.30 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-12-30-pm.png)
5. Navigate to the Configuration Page.
6. Click on the background of the panel in the controller section to open the background layer of the configuration in the Inspector.   
    ![Screenshot 2025-10-30 at 12.09.26 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-09-26-pm.png)
7. Create Variable called **ExternalCameraSelect** Exact name is needed as it is prebuilt into a Virtual Trigger.   
    ![Screenshot 2025-10-30 at 12.15.08 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-15-08-pm.png)
8. Adjust the needed range of the Variable based on numbers used in the Camera Selector on the Home Page for the Ext. Cam Number. The range used should encompass all numbers you have defined. By default the range is 1-10, if that is all that is needed, then no adjustment is required. ![Screenshot 2025-05-26 at 12.27.42 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-27-42-pm.png)
9. Create a Virtual Trigger to set the ExternalCameraSelect Variable based on external trigger. Name the Virtual Trigger something that will allow you to easily identify what it is doing. ![Screenshot 2025-10-30 at 12.17.05 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-17-05-pm.png)
10. Open the newly created Virtual Trigger.
11. Set the Mode to Change.
    
    ![Screenshot 2025-10-30 at 12.18.43 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-18-43-pm.png)
12. For the IF parameter, set the source of the trigger. In this instance a specific TCP command will be used to change the ExternalCameraSelect variable.   
    ![Screenshot 2025-10-30 at 12.26.42 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-26-42-pm.png)
    
      
    Device Core: TCP Server  
    Parameter Name: Integer Value  
    Number: Literal: 1  
    ![Screenshot 2025-11-20 at 1.25.07 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-11/scaled-1680-/screenshot-2025-11-20-at-1-25-07-pm.png)
13. For the THEN parameter, select the ExternalCameraSelect Variable  
    First Expand System to select Change Variable behavior   
    ![Screenshot 2025-11-20 at 1.27.09 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-11/scaled-1680-/screenshot-2025-11-20-at-1-27-09-pm.png)
    
      
    Second click to edit the parameter
    
    ![Screenshot 2025-11-20 at 1.29.10 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-11/scaled-1680-/screenshot-2025-11-20-at-1-29-10-pm.png)
    
      
    Third select the ExternalCameraSelectVariable
    
    ![Screenshot 2025-10-30 at 12.35.12 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-35-12-pm.png)  
    Fourth select Confirm when prompted.
    
    [![Screenshot 2025-10-30 at 12.37.02 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-37-02-pm.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/screenshot-2025-10-30-at-12-37-02-pm.png)
14. The needed Template Behavior for the THEN should be auto suggested. If it is not, you will want to select SET SPECIFIC VALUE.   
    ![Screenshot 2025-10-30 at 12.38.27 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-38-27-pm.png)
15. For the Value, set again the same parameter you used for the IF parameter. ![Screenshot 2025-10-30 at 12.40.02 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-40-02-pm.png)
    
    ![Screenshot 2025-11-20 at 1.25.07 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-11/scaled-1680-/sX4screenshot-2025-11-20-at-1-25-07-pm.png)
16. The trigger is now set up and can be used by sending the command **Int#1=X** (X = the number set in Ex. Cam Number column in the Camera Select Settings Table on the Home Page) to the IP address of the Blue Pill device and the port defined in the TCP Server device details on the home page.  
    ![Screenshot 2025-10-30 at 12.44.12 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-10/scaled-1680-/screenshot-2025-10-30-at-12-44-12-pm.png)  
    Example using a Terminal window on Mac.
    
    ![Screenshot 2025-11-20 at 1.31.12 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-11/scaled-1680-/screenshot-2025-11-20-at-1-31-12-pm.png)

</details><details id="bkmrk-external-camera-sele-1"><summary>External Camera Select from Skaarhoj Panel in the Same Project</summary>

1. Make sure you have connected to all your needed devices on the Home Page
2. On the Home Page, open the Camera Selector settings table.  
    ![Screenshot 2025-05-26 at 11.53.11 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-53-11-am.png)
3. Enable Show Advanced in the Camera Selector  
    ![Screenshot 2025-05-26 at 11.52.36 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-52-36-am.png)
4. Input a unique number to associate with the camera in the Ext. Cam Number column. ![Screenshot 2025-05-26 at 11.53.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-11-53-51-am.png)
5. Repeat the process for your second panel. <p class="callout info">The camera select doesn't need to be in the same order, but the same number needs to be associated with each camera.</p>
6. Navigate to the Configuration Page.
7. Open the Configuration Tree and click on the Root Layer at the bottom.   
    ![Screenshot 2025-05-26 at 1.13.02 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-13-02-pm.png)
    
    ![Screenshot 2025-05-26 at 1.16.46 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-1-16-46-pm.png)
8. Create Variable called **ExternalCameraSelect** Exact name is needed as it is prebuilt into a Virtual Trigger.   
    ![Screenshot 2025-05-26 at 11.19.14 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/mJfscreenshot-2025-05-26-at-11-19-14-am.png)
9. Adjust the needed range of the Variable based on numbers used in the Camera Selector on the Home Page for the Ext. Cam Number. The range used should encompass all numbers you have defined. By default the range is 1-10, if that is all that is needed, then no adjustment is required. ![Screenshot 2025-05-26 at 12.27.42 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/screenshot-2025-05-26-at-12-27-42-pm.png)
10. Close the Configuration Tree but remain on the configuration page.
11. Click on any of the camera select buttons for the panel you want to trigger the external camera select from. This will open the details in the Inspector. ![Screenshot 2025-06-30 at 10.36.56 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-10-36-56-am.png)
12. In the Inspector, click on the first Show More to expand it.   
    ![Screenshot 2025-06-30 at 10.41.10 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-10-41-10-am.png)
13. Create another Action called **externalselect** ![Screenshot 2025-06-30 at 10.58.05 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-10-58-05-am.png)
14. Set up the action as follows:  
    ![Screenshot 2025-06-30 at 11.02.47 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-11-02-47-am.png)Action Type: Binary (Button)  
    Type (Press/Release): ActUp  
    Values to Set: Behavior:Const:ExtCamSelect   
    ![Screenshot 2025-06-30 at 11.02.07 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-11-02-07-am.png)Parameter: Var:ExternalCameraSelect
    
    ![Screenshot 2025-06-30 at 11.02.29 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-06/scaled-1680-/screenshot-2025-06-30-at-11-02-29-am.png)
15. If you would like to trigger the external camera select to go both ways, repeat steps 11-14 for additional panels.

</details>

# Fader custom curve

#### What is a fader curve

Fader movement from bottom to top has a range from 0-1000, and by default this is a straight line - or **linear**. But sometimes you want the fader to have more details - or 'throw' - in certain areas, on the cost of less details in other areas. This can be described with points on the line that bends it in different ways - we call this a fader curve.

See these examples:

<table border="1" id="bkmrk-linear-%28default%29-det" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 20%;"></col><col style="width: 20%;"></col><col style="width: 20%;"></col><col style="width: 20%;"></col><col style="width: 20%;"></col></colgroup><tbody><tr><td>[![linear.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/e2ylinear.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/e2ylinear.png)

Linear (default)

</td><td>[![flat-top.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/a5Hflat-top.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/a5Hflat-top.png)

Details in top

</td><td>[![flat-middle.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/LHNflat-middle.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/LHNflat-middle.png)

Details in middle

</td><td>[![no-top-bottom.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/OQsno-top-bottom.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/OQsno-top-bottom.png)

No top/bottom

</td><td>[![more-points.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/more-points.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/more-points.png)

More points = smooth

</td></tr></tbody></table>

This means: The more vertical the line is, the faster it moves past an area (less detailed). And opposite: The more horisontal the line is, the longer it stays in the same area (more detailed).

So, if you have an audio channel and want more fader accuracy in the loud end, you'd make a curve similar to example 2; 'Details in top'.


#### Access the curve editor

Reactor has a built-in graphic curve editor. It allows you to create any custom fader curve you want, including the examples above. You access it on the Configuration page by selecting a fader hardware component, and open the advanced settings within the Inpector. The curve editor is, of course, only available when selecting a 'fader' component, and not on buttons or knobs.

<table border="1" id="bkmrk-click-a-fader-to-sel" style="font-family: -apple-system, 'system-ui', 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 14px; width: 100%; border-collapse: collapse; border-width: 0px;"><colgroup><col style="width: 52.381%;"></col><col style="width: 47.619%;"></col></colgroup><tbody><tr><td style="border-width: 0px;">Guide to open the curve editor:

1. click a fader to select it in Inspector
2. select a parameter that uses a behavior for 'Change value on fader' (fx. Audio volume / Camera Iris / Hyperdeck PlaySpeed)
3. click 'Show more'
4. click the Action 'Change' to open it
5. click 'Show Advanced Action Options
6. in 'Static Value Mapping' select 'Coords'
7. next to 'Static Value Mapping Coords' click '+' to create curve, and click the small white 'curve' icon to open the curve editor

</td><td style="border-width: 0px;">[![access-curve-editor.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/cgBaccess-curve-editor.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/cgBaccess-curve-editor.png)

</td></tr></tbody></table>


#### Edit curve

<table border="1" id="bkmrk-in-the-curve-editor-" style="font-family: -apple-system, 'system-ui', 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 14px; width: 100%; border-collapse: collapse; border-width: 0px;"><colgroup><col style="width: 51.6072%;"></col><col style="width: 48.512%;"></col></colgroup><tbody><tr><td style="border-width: 0px;">In the curve editor you add points, and drag them in the 0-1000 grid (0,0 being bottom and 1000,1000 being top).

Here's a guide to the features:

1. click '+' or '-' to add or delete points.
2. adjust the grid size. For many uses 100x100 is fine.
3. drag points to adjust the curve. It always start in bottom left and ends in top right. Steeper vertical means less detail in this area - more horisontal means more detail in this area.
4. click the 'circle-arrow' icon to create an 'inverted feedback'. This can be vital to match return-values from the device you control, and avoid fader jumps.
5. hover mouse over 'brackets' icon to see all coordinates.
6. click 'Submit' to save the curve. Changes are applied immediately.

</td><td style="border-width: 0px;">[![curve-editor.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/scaled-1680-/nGocurve-editor.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-07/nGocurve-editor.png)

</td></tr></tbody></table>

#### Inverted feedback

Please know that often a SKAARHOJ panel **sends** values to a device - and then it **listens** for return-values from the device. So, you may move the motor-fader, but the fader position is actually updated by the return-value from the device.

In this case, having a custom curve on the data you send (the **Action**) - also makes it necessary to have an **inverted** version of the same curve on the data you listen for (the **Feedback**). This will prevent the fader from 'jumping' in strange ways.

As mentioned above (in line 5), you simply click the 'circle-arrow' icon to automatically create a feedback with an inverted curve. And do remember to click it again to update it, if you have edited the curve.

# IO References

<p class="callout warning">This documentation has moved, see here: [https://docs.skaarhoj.com/3\_configuration/ioreference.html](https://docs.skaarhoj.com/3_configuration/ioreference.html "Reactor Manual - IOReference")</p>

# Joystick Override / Hold Group guide

This is a guide on how to handle 'Joystick override' and 'Hold groups' for CCU operators - allowing automatic routing of cameras to a confidence monitor.

Imagine these operator steps:

1. CCU 1 presses the joystick :: Route cam 1 to monitor
2. CCU 4 presses the joystick :: Route cam 4 to monitor
3. CCU 2 presses the joystick :: Route cam 2 to monitor  
    ...
4. CCU 4 lets go of the joystick :: (nothing happens)
5. CCU 2 lets go of the joystick :: Return to route cam 1 to monitor
6. CCU 1 lets go of the joystick :: Return to original input for monitor

You can of course have more CCU's - and the order of who does what when is remembered by the system.

#### Prerequisite

This setup requires a 4 things:

- Blue Pill device --&gt; Is the brain, running the config and controlling both ETH-GPI Link and video switcher/router  
    For example 'Blue Pill Server' : [https://www.skaarhoj.com/product/blue-pill-server](https://www.skaarhoj.com/product/blue-pill-server)
- ETH-GPI Link --&gt; Handles the GP inputs from the CCU's  
    [https://www.skaarhoj.com/product/eth-gpi-link](https://www.skaarhoj.com/product/eth-gpi-link)
- A number of CCU's with GP output for joystick press
- A video switcher/router (for example; Aja Kumo, ATEM, Tricaster, vMix etc.)

<span style="color: rgb(224, 62, 45);">NOTE:</span> The Blue Pill device must have Reactor 2.2.3-pre10 or later installed. This is handled on the 'Packages' page.  
<span style="color: rgb(224, 62, 45);">NOTE:</span> The ETH-GPI Link must be in 'Blue Pill Mode', which means it's controlled by a Blue Pill device.

#### Configuration

1. Goto IP address of Blue Pill device to see Reactor, the configuration manager.
2. Click '**Add panel'** and select your ETH-GPI Link
3. Click '**Add device**' and select your routing device
4. In the ETH-GPI Link configuration drop-down menu, **select default configuration** 'Tally &amp; Routing'
5. Click '**Camera Selector**' to open settings -&gt; Add empty rows (by holding Shift) -&gt; Set route index \[1, 2, 3..\]  
    (these are the camera inputs on the switcher/router)
6. Click '**Routing Trigger**' to open settings -&gt; Select the output to route to
7. Click '**GPIO Input mapping**' to open settings -&gt; Change type from ‘Tally Program’ to ‘Route Index’
8. Click '**Config Variables**' to open settings -&gt; Select 'Press' or ‘Hold down’

Advanced step to share stack between multiple \[Blue Pill Inside\] RCP panels in the same configuration:

1. Goto Configuration page -&gt; click '&gt;&gt;' in window left/top top show Layer Tree
2. Find variable: HoldGroupState -&gt; right-click it and copy it
3. Scroll down to lowest Root layer -&gt; right-click it and paste variable here (variables here are shared by all panels)

#### Screenshots

Same as config steps above

2:  
[![2-add-panel.png](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/scaled-1680-/2-add-panel.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/2-add-panel.png)

5:  
![5-camera-selector.png](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/scaled-1680-/5-camera-selector.png)

6:  
![6-routing-trigger.png](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/scaled-1680-/6-routing-trigger.png)

7:  
![7-gpio-input-mapping.png](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/scaled-1680-/7-gpio-input-mapping.png)

8:![8-config-variables.png](https://wiki.skaarhoj.com/uploads/images/gallery/2026-03/scaled-1680-/8-config-variables.png)

# Page Layers

<p class="callout info">Please note: This video is made for Reactor 1.x  
We have since released Reactor 2.x - and the video is no longer up-to-date.</p>

This guide show you how to make Page Layers.

Say you wish control 8 parameters on a camera, but only have 4 encoders on your controller. In this case you make two 'Pages' - or layers - and assign different commands in each 'Page'. You then assign a button to toggle between the pages.

<div id="bkmrk-" style="padding: 75% 0 0 0; position: relative;"><iframe allowfullscreen="allowfullscreen" frameborder="0" src="https://player.vimeo.com/video/744552710?h=4e35e5dc54&badge=0&autopause=0&player_id=0&app_id=58479" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" title="Reactor - Page Layers guide.mov"></iframe>

</div>

# Pan/Tilt/Zoom Rocker Sensitivity and Curve Setup

For all our default PTZ configs we have pre-defined up to 4 variables for you to use to tune the feeling of the joystick and zoom rocker to fit the feeling between multiple cameras to your liking.

Before in time, you would find one param that would control all 3 axes on the joystick (L/R, U/D &amp; Rotate) as well as the Zoom rocker. This has now been split out by default to these for options that can be set pr. camera and that will remember their values between reboots, so you don't have to remember them.

The for new params are:

1. PT\_Speed -&gt; Controls the scale on U/D, L/R Joystick movements (Max Speed)
2. PT\_Curve -&gt; Controls the curve for U/D, L/R Joystick movements (Expo)
3. Z\_Speed -&gt; Controls the scale of the Zoom rocker and Joystick rotation (Max Speed)
4. Z\_Curve -&gt; Controls the curve of the Zoom rocker and Joystick rotation (Expo)

The two-speed variables are direct replacements for the old JoystickSens variable and they go just like the old variable from 1-10, with the default being 10. This correlates to a min setting of 10% of the max speed and up to the full 100% speed.  
So in short 1 = 10%, 2 = 20%, 5 = 50% and 10 = 100% speed on a fully deflected joystick/rocker.

Then we have the Two new curve variables that actually replace the old JoystickExpo variable. The chances of you having seen that variable in Reactor are very slim as it's not been part of the configs before, even though it has been set as an option in all configs.  
The new PT\_Curve and Z\_Curve replace this old variable with a name that makes more sense as well. What we control here is the amount of Expo we want on the joystick. These variables go from 0-25 giving us a wide selection from 0 = linear to 25 = 75% expo. The reason we have limited it by default to a max of 75% is that otherwise it gets so sharp that it's basically just an on/off behaviour. Adjusting this variable will give you more resolution in the middle of the joystick without losing max speed at the ends. combine this with the speed above to get the best feeling for you.

In order to visualise what the curve variables do, please take a look at this image, if you have the curve set to 0 then your joystick will follow the green curve, then as you move up towards 25 you will get closer and closer to the red curve. Thus giving you more resolution in the middle.

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/p1yimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/p1yimage.png)

Image showing these four variables mapped to the encoders in a config:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/TGCimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/TGCimage.png)

Example of the P/T Speed and P/T Curve variable setup (Note that they also have "Persistent" = true):

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/TXximage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/TXximage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/TWximage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/TWximage.png)

Here is the full definition of the 4 variables in their full JSON setup:  
This snippet is taken from the file: SKAARHOJ.Devices.Canon-XC.ProClass.Basic

```json
        "PT_Curve": {
            "Name": "P/T Curve",
            "Description": "Pan/Tilt Joystick Curve (0 = Linear, 25 = Exponential)",
            "MinMaxCenterValue": [
                0,
                25
            ],
            "Default": [
                "0"
            ],
            "Persistent": true
        },
        "PT_Speed": {
            "Name": "P/T Speed",
            "Description": "Pan/Tilt Joystick Max Speed (1 = 10%, 10 = 100%)",
            "MinMaxCenterValue": [
                1,
                10
            ],
            "Default": [
                "10"
            ],
            "Persistent": true
        },
        "Z_Curve": {
            "Name": "Z Curve",
            "Description": "Zoom Rocker Curve (0 = Linear, 25 = Exponential)",
            "MinMaxCenterValue": [
                0,
                25
            ],
            "Default": [
                "0"
            ],
            "Persistent": true
        },
        "Z_Speed": {
            "Name": "Z Speed",
            "Description": "Zoom Rocker Max Speed (1 = 10%, 10 = 100%)",
            "MinMaxCenterValue": [
                1,
                10
            ],
            "Default": [
                "10"
            ],
            "Persistent": true
        }

```

One thing you will notice when you go to look at a PTZ behaviour is that you cant find where these variables are actually used, as for the moment this is not visible in the UI, so, for now, you will have to add or change this via the JSON editor.

If we go take a look at where this would become visible at some point in the future, then that would be here inside the blue box, inside a part called "ValueMapping":

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/iyIimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/iyIimage.png)

If we then Click the "Show JSON" button then, we will see the full config for the Pan joystick setup for Canon XC:

```json
{
    "ParentID": "SKAARHOJ:SpeedControl",
    "Name": "Pan",
    "EventHandlers": {
        "value": {
            "ValueMapping": {
                "ScalingDivisor": 10,
                "ScalingIOReference": {
                    "Raw": "Var:PT_Speed"
                },
                "ExpoDivisor": 30,
                "ExpoIOReference": {
                    "Raw": "Var:PT_Curve"
                }
            },
            "InvertCondition": "Var:InvertPan == true"
        }
    },
    "IOReference": {
        "Raw": "DC:canon-xc/Var:DeviceIndex/panSpeed"
    }
}
```

What we look for is again the "ValueMapping" field where we can see a ScallingDivisor so that's how we get the 10% steps on the PT\_Speed variable 100%/10 = 10% step size

Then the same for the Curve, we have an ExpoDivisor that is set to 30 so 100%/30 = 3% expo pr step and by having our PT\_Curve variable limited to only 25 limits the max setting on the controller to 25 \* 3% = 75% expo. Thus preventing the curve from becoming unusably sharp.  
  
Don't hesitate to play around with these options to get the tunning fully right to your liking.

# Presets Functions

### Presets

\- Generally speaking, presets store and recall parameter values and triggers in Reactor  
\- The values to be stored can be predefined in a preset profile or they can be completely arbitrary (recording what changes)  
\- A preset profile can define values across device cores, device IDs and parameter dimensions - or they can be narrowed down  
\- With narrow preset profiles, there are inherent opportunities to use presets to copy/paste sets of values between devices and dimensions  
\- Reactor supports an infinite amount of preset profiles (re-)defined anywhere in the layer tree  
\- Storage and recall of a preset can work either instantaneously or played back over time  
\- When recorded and played back over time, values are organized in multiple segments. Each segment is essentially a time line and at the end of a timeline, playback will continue to the next segment either automatically or by user invocation (waiting for user input).  
\- Playback order of segments can be shuffled and waiting time between segments can be randomized. Playback for a timeline can be looped  
\- Recording and playback allows cancellation which will restore the state before recording or playback.  
\- Support for ganged recording and playback of multiple preset numbers, device ids, and dimensions (fairly exotic, honestly)  
\- Prepared for parameter animation (must be implemented in devicecollection)

### Commands:

**NextSegment (trigger)**  
During recording, this will end the segment and start a new one assuming there has been values added.  
During playback, this will skip to next segment

**AddUserWait (trigger)**  
Like NextSegment, but when used during recording it will insert a User Wait at the end and cap the segment length to the last added value.

**Play (trigger)**  
Starts playback

**PlayToggle (trigger)**  
Starts or stops playback

**PlayToggleNext (trigger)**  
Starts or stops playback, except if waiting in which case it will

**PlaySkip (trigger)**  
Starts playback, and skips to next segment if already playing (which may result in stopping altogether)

**PlayPause**  
Starts playback and toggles pause if already playing

**PlayPauseNext**  
Starts playback and toggles pause if already playing, unless at a user wait in which case it skips to next.

**Record (trigger)**  
Starts recording

**RecordToggle (trigger)**  
Starts or stops recording

**RecordNewSegment (trigger)**  
Starts recording, and creates new segment on second press

**RecordAddUserWait (trigger)**  
Starts recording, and creates new segment with user wait on second press

**Stop (trigger)**  
Stops recording or playing

**Delete (trigger)**  
Deletes preset if it is not recording or playing

**Cancel (trigger)**  
If recording, it will stop recording, recall the values from before recording and reinstate the previous content for the preset   
If playing, it will stop playing and recall the values from before playing.

**Recall (trigger)**  
Instantly recalls the final values of the first segment of a preset.

**RecallStateFromBeforeRecording (trigger)**  
Recalls the initially stored state of a given preset

**DurationRandomExtension (Integer value, ms)**  
Sets the Random extension value for a given recorded preset.

**Loop (bool)**  
Enable looping for a preset

**Shuffle (bool)**  
Enable shuffle for a preset

# RCP Pro / RCPv2 :: Control more than 8 cameras

#### Optimal control

For optimal control we suggest having a separate RCP panel for each camera.  
This is how camera control was intended, when Sony invented the RCP form factor in the beginning of time.

#### Default 'Camera Control' configuration

RCP Pro and RPCv2 panels have a feature rich pre-made default configuration called 'Camera Control'.  
It is selected on Home page in the configuration drop-down menu, right next to the panel icon.

This configuration allow you to add up to 8 cameras, even from different brands.  
And the 8 small buttons in the panel top are a perfect fit to use for 'Camera Select 1-8'.

[![rcp-pro-top.png](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/scaled-1680-/nDPrcp-pro-top.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2025-05/nDPrcp-pro-top.png)

#### Options for more cameras

If you need to control more cameras you can..

- purchase more RCP panels
- create your own custom configuration from scratch
- modify the 'Camera Control' configuration to handle more cameras

#### How to modify the 'Camera Control' configuration

This includes:

- increasing the allowed number of cameras on Home page
- create a variable to store 'current camera selector page'
- assign the variable to the Generator for camera select (to automatically create more pages)
- assign the variable to a button (to toggle pages)

You can watch a screen recording video (2min 24sec), that shows you how to modify the configuration step-by-step.  
Download the video here:  
[https://drive.google.com/file/d/1GC\_ap9sWij\_W8nkptEJa7tfiHDLgNYlp/view?usp=drive\_link](https://drive.google.com/file/d/1GC_ap9sWij_W8nkptEJa7tfiHDLgNYlp/view?usp=drive_link)

And here's a written guide on how to do it:

Add cameras  
• Home page  
• in window right, click ‘Add device’ -&gt; add all cameras  
• in window center, select ‘Camera Control’ in the configuration menu  
• click ‘+ icon’ -&gt; click ‘Add all supported devices’

Expand max number of cameras to more than 8 before the ‘+’ button disappears  
• goto Configuration page  
• click ‘&gt;&gt;’ icon to show Object Tree  
• in very bottom/right of page, click ‘cogwheel’ icon to open Settings -&gt; enable ‘Show IncludeLayers’  
• now you see the layer ‘Default RCP PRO Configurattion’ -&gt; click 'CameraSelector' to show it in Inspector  
• scroll down, click ‘Show more’ -&gt; edit ‘Max items’ from 8 to 16 (or how many you need)  
• goto Home page -&gt; add more cameras

Make sure the 8 buttons in panel top are used for ‘camera select’ - and not for ‘presets’  
• goto Simulator page / or press buttons on actual panel  
• press two buttons to open Engineering menu -&gt; set Cam-row to ‘Cameras’

Create new variable to store ‘Selected page’  
• goto Configuration page  
• click panel background to see variables -&gt; create new ‘CamSelectPage’ variable -&gt; click it to open it -&gt; set range max 2

Use variable in generator for 'Cam selectors' to automatically build more pages  
• in Object Tree, open layer RCP &gt; Camera Control &gt; Normal Operation -&gt; Cam 1-8  
• click any of the 8 Cam buttons to select the generator in Inspector -&gt; set ‘Paging Variable’ to the new ‘CamSelectPage’

Assign variable to button, to use for page-select  
• click ‘&lt;&lt;‘ icon to hide Object tree  
• click an available button, fx. X4  
• select System &gt; Change Variable &gt; select the new CamSelectPage -&gt; click Submit + confirm

Done.! The 8 camera select buttons in panel top now has 2 pages, and use button X4 to toggle between them.

# Separating Zoom Sensitivity from Pan and Tilt Sensitivity

<p class="callout warning">This page has been made obsolete in newer versions of Reactor. </p>

By default Pan, Tilt, and Zoom are all controlled by the setting Joystick Sensitivity. This is not ideal for some users who would like Zoom to be controllable at its own sensitivity. To separate this out it is necessary to dive into the configuration and the json editor, but don't worry, it isn't too difficult.

This example will be done on the PTZ Extreme but can be applied to all configurations.

Joystick sensitivity is not set for the whole controller, but per camera configuration based on device core. The configuration in this instance is different from the panel mapping. There will be a different configuration added for each device core used.

<p class="callout info">Different brands might use the same device core, example: BirdDog, NewTek, Marshall all use the Visca device core. </p>

<p class="callout info">This example was made on a Blue Pill running the following version:  
SkaarOS v1.0  
Reactor v1.0.5-pre11  
System Manager v1.0.1-pre1  
Hardware Manager v1.0.2-pre3  
Using earlier versions can affect the look of the interface causing it to appear different. We recommend using at least the indicated versions or newer. </p>

1\. Determine the number of PTZ configuration in your set up.   
In the set up example there are 3 different device cores used as indicated in the Devices section. All devices will be grouped by the used core in this section. ![Screenshot 2022-12-16 at 13.29.42.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-13-29-42.png)

2\. Navigate to the Configuration Tab.

![Screenshot 2022-12-16 at 13.46.26.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-13-46-26.png)

3\. Open the Tree to navigate to the Device Core Configurations. The tree expands from the bottom up, like a tree starting at the roots. (This is shown in a collapsed view)

![Screen Shot 2022-12-19 at 8.44.20 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screen-shot-2022-12-19-at-8-44-20-am.png)

4\. Navigate to the Joystick Sensitivity variable for a Device Core Configuration.

![Screenshot 2022-12-16 at 13.48.52.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-13-48-52.png)

5\. Open the Tree Layer with the Joystick Sensitivity Variable. When selected the layer will change color and you will see it open in the Inspector on the right side of the screen.

![Screenshot 2022-12-16 at 13.52.30.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-13-52-30.png)

6\. Create a new variable called **ZoomSens**. This could be named anything, but it is best to use something that will be easy to remember and type later.

![Screenshot 2022-12-16 at 13.58.04.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-13-58-04.png)

7\. Open the ZoomSens variable to edit the details. Use the same details as the JoystickSens variable.   
The name is however you would like it to display on the controller.   
The type is Range  
The Min is 1  
The Max is 10 (The scale should not exceed 10)  
Default value is 10

![Screenshot 2022-12-16 at 14.02.05.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-14-02-05.png)

8\. Go back to the Tree and select the JoyRot box in the same layer you are working in. This will open the joystick rotation (zoom) in the inspector.

![Screenshot 2022-12-16 at 14.08.36.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-14-08-36.png)

9\. DON'T PANIC

10\. Open Show JSON for the JoyROT component.

![Screenshot 2022-12-16 at 14.09.54.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-14-09-54.png)

11\. Select Format

![Screenshot 2022-12-16 at 14.11.57.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-14-11-57.png)

12\. Select Show Parent Behavior

![Screenshot 2022-12-16 at 17.56.39.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-17-56-39.png)

13\. In the Window the pops up, select Format again. This will expand the data to see the whole JSON text.

![Screen Shot 2022-12-19 at 8.55.43 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screen-shot-2022-12-19-at-8-55-43-am.png)

14\. Scroll down to the Joystick Sensitivity commands and copy the whole command set as seen below, every part is essential:

<div id="bkmrk-%22valuemapping%22%3A-%7B-%22s"><div><div><div>**"ValueMapping": {**</div><div>**"ScalingDivisor": 10,**</div><div>**"ScalingIOReference": {**</div><div>**"Raw": "Var:JoystickSens"**</div><div>**}**</div><div>**},**</div><div>  
</div></div></div></div>![Screen Shot 2022-12-19 at 8.57.39 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screen-shot-2022-12-19-at-8-57-39-am.png)

15\. Close this window.

16\. In the Inspector, find the BehaviorSetValues text in the JSON editor. Click after the comma and hit enter.

![Screenshot 2022-12-16 at 18.10.15.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-10-15.png)

17\. Paste in the text you copied from the Parent Behavior pop up.

![Screenshot 2022-12-16 at 18.12.52.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-12-52.png)

18\. Find the text in the pasted in command that say: **"Var:JoystickSens"**

![Screenshot 2022-12-16 at 18.14.17.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-14-17.png)

19\. Edit this text to say: **"Var:ZoomSens"** then press Save

 If you did not name the variable you created earlier ZoomSens, you will type the name you did create here after the **:**

![Screenshot 2022-12-16 at 18.16.20.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-16-20.png)

20\. If there is a Zoom Rocker, you will need to do steps 18 + 19 for that hardware component as well.

![Screenshot 2022-12-16 at 18.20.24.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-20-24.png)

21\. The variable and command have now both been set up. The last step is to assign control of the variable to an encoder.

22\. Go back to the tree view and navigate deeper in that device core configuration to the Camera Adjustment layer and open it. This will open the tree to see the different page layers of settings for the camera. They should be named based on the what they contain. [![Screenshot 2022-12-16 at 18.40.43.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-40-43.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/screenshot-2022-12-16-at-18-40-43.png)

23\. Navigate to and select the System layer, this is where the Joystick Sensitivity control is usually located but may also be on the Home page. This should be the same across all device core configurations. The number and names of layers will be different for each device core configuration. On each of them should be a Home and a System page.

![Screenshot 2022-12-16 at 18.50.52.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-50-52.png)

24\. Find one of the encoders that does not currently have something assigned to it, you can see this by going to that page on your physical panel and seeing where a good place to put the Zoom Sensitivity Control would be. In this example I am using Encoder 4 (from right to left on the physical panel).![Screenshot 2022-12-16 at 18.54.13.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-54-13.png)

25\. In the Inspector select Edit next to the Parameter.

![Screenshot 2022-12-16 at 18.56.14.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-56-14.png)

26\. In the pop up window, select Variable.

![Screenshot 2022-12-16 at 18.57.15.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-18-57-15.png)

27\. In the drop down next to Variable Name, select **ZoomSens** and press Submit.![Screenshot 2022-12-16 at 19.33.39.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-19-33-39.png)

28\. After submitting the Behavior should either suggest or auto-assign Step Change. This is the correct behavior.

![Screenshot 2022-12-16 at 19.34.48.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-19-34-48.png)

29\. You should now be able to control Zoom Sensitivity separately from Pan and Tilt.

![Screenshot 2022-12-16 at 19.36.29.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screenshot-2022-12-16-at-19-36-29.png)

30\. If you are combining cameras that use multiple device cores on your panel, you will need to go in and do the same in each device core configuration. In the example below there are 3 different configurations and we made the changes to the Canon configuration.

![Screen Shot 2022-12-19 at 9.00.26 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-12/scaled-1680-/screen-shot-2022-12-19-at-9-00-26-am.png)

# Switching Projects via a Button in Reactor

Reactor allows to switch the current project easily using a button.

<p class="callout warning">Please Note, changing the current project will disconnect controllers if they are not configured in the project that is being switched to. </p>

<p class="callout warning">Make sure to configure the projects to be switched between in each project. </p>

In the Project Manager, open the project details for the project you want to switch to. Copy the project's Filename exactly. It is necessary to toggle on Show Advanced to see the file name.

[![Screenshot 2023-11-08 at 1.54.39 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-08-at-1-54-39-pm.png) ](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-08-at-1-54-39-pm.png)

  
On the Configuration Page, select the button to configure. In the Inspector, select Switch Project under the System options.

[![Screenshot 2023-11-09 at 11.37.15.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-09-at-11-37-15.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-09-at-11-37-15.png)

In the Inspector box, the parameter should open with a preselected selected Settings Template.

![Screenshot 2023-11-09 at 12.18.57.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-09-at-12-18-57.png)

Fill in the Project Filename that was copied from the Project Manager into the Value field next to Project Filename. It is important that the file name is copied exactly as found in the Project Manager.

[![Screenshot 2023-11-09 at 12.19.47.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-09-at-12-19-47.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-09-at-12-19-47.png)

The project name should now appear on the display above the button (if the button does have an associated display).

<p class="callout info">Please Note, the switch is activated by a 1 second hold down of the button. </p>

[![Screenshot 2023-11-09 at 12.20.05.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-09-at-12-20-05.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-09-at-12-20-05.png)

Another way to do it without the 1 second hold down.

On the Configuration Page, select the button to configure. In the Inspector, select Choose Other Parameter under the System option.

[![Screenshot 2023-11-09 at 12.35.30.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-09-at-12-35-30.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-09-at-12-35-30.png)

In the dialog box that pops up select: Reactor/CurrentProject then Submit

[![projectswitch ioref.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-06/scaled-1680-/projectswitch-ioref.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-06/projectswitch-ioref.png)

Returning to the Inspector, select Show More if you do not see Settings Template available.

![Screenshot 2023-11-08 at 2.06.58 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-08-at-2-06-58-pm.png)

In the Settings Template, select Set Value Directly:

[![Screenshot 2023-11-08 at 2.07.21 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-08-at-2-07-21-pm.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-08-at-2-07-21-pm.png)

This should then give you the option to define the value needed.

The first box will contain the Project File Name as directly copied from the Project Details. The second box can contain any name you would like to be displayed on the hardware panel.

[![Screenshot 2023-11-08 at 2.08.03 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-08-at-2-08-03-pm.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-08-at-2-08-03-pm.png)

You should end up with a button like this:

[![Screenshot 2023-11-08 at 2.25.37 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/scaled-1680-/screenshot-2023-11-08-at-2-25-37-pm.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2023-11/screenshot-2023-11-08-at-2-25-37-pm.png)

# Switching Projects via external HTTP Request

Reactor allows to switch the current project via an external HTTP POST request.  
  
The endpoint used is: /reactorapi/selectproject

This request allows to use the skaarOS authentication via HTTP Basic Authentication (Use the latest version of system-manager to allow this (v1.0.1-pre1 and higher))

  
Curl example:  
curl --location --request POST '192.168.0.20/reactorapi/selectproject' \\  
\--header 'Authorization: Basic YWRtaW46c2thYXJob2o=' \\  
\--header 'Content-Type: application/json' \\  
\--data-raw '{"Filename":"MyProject"}'

# Understanding Flags

<p class="callout warning">This documentation might be outdated. Please consult the Reactor manual at [https://docs.skaarhoj.com/11\_advanced\_topics/flag-groups.html](https://docs.skaarhoj.com/11_advanced_topics/flag-groups.html)</p>

Inside reactor we have support for setting flags true or false. These flags are based around how TSL works to some extent and provides a list of true/false states with 4 "bits" per index.

Flags in reactor consists of 4 bits per index, that can be set true or false individually, each of these flag bits can be used for different things but you will mainly see them used for providing tally and routing support in configs as they are a great way to store the intermediate state that comes in from a GPI pin or from a device like an ATEM switcher. Then use the stored state to send the Tally to the cameras

The 4 "colors/bits" main use cases in the default configs for each color are:

<table border="1" id="bkmrk-red-mainly-used-for-" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 17.5927%;"></col><col style="width: 82.5309%;"></col></colgroup><tbody><tr><td>Red

</td><td>Mainly used for Program Tally</td></tr><tr><td>Green</td><td>Mainly used for Preview Tally </td></tr><tr><td>Blue</td><td>Not widely used in default configs yet</td></tr><tr><td>White</td><td>Mainly used for storing what camera to Route on a mixer/videohub</td></tr></tbody></table>

These are not limited to this use case, but this is the current convention we use internally.

#### Define flag groups and sync them up

When you use flags you will need to add them to your project as "Flaggroups" with a name and an Index.  
One Important note is that ANY config that you have loaded in the project that uses the same Group ID will be synced even if you have different names for them. This means that you can "sync" up tally or routing between 2 or more controllers running in the same reactor just by changing the flaggroup ID for "Tally" to be the same on both panels. This is also a very simple way to add a GPIO or Tally box to an existing system/setup.  
  
This also brings the problem of if you happen to set your Routing group to the same ID as your Tally group, funny stuff might happen. But since we are using different Bit's for it, you should be fine and not risk having "crosstalk" between them. For simplicity we have made sure to make them on different group ID's in all default configs.  
  
Here is an example from a PTZ Extreme about how these groups are defined on Index 10 and 11:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/image.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/image.png)

#### How to set a flag

The simplest way to set a flag is to use the normal "SKAARHOJ:HoldDown" behavior on a button/GPI pin or in a virtual trigger where you might use the tally status reported by your switcher.  
  
When setting flags we are looking at an IORefrence structure that looks like this:

**Flag:Tally/Red/Var:TallyIndex/**

So to break it down we have:

**Flag:\[Group Name\]/\[Color\]/\[Index\]** Often you will see us use a variable for the index. In most cases we use it together with a constant set where the user can fill in what routing input or tally index it should follow. For a mixer setup the tally index would correlate with what input number is active on the mixer.

##### Some examples of this in use

Here is a couple of examples of how these setups look, they are posted here in json format as it's the simplest way to get a condensed look at the setup:

**From an RCP using the GPI input to set the red tally flag on the selected camera:**

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/8xKimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/8xKimage.png)

```json
{
    "ParentID": "SKAARHOJ:HoldDown",
    "IOReference": {
        "Raw": "Flag:Tally/Red/Var:TallyIndex"
    }
}
```

**And here for the preview button (same as pressing the joystick) on the same RCP, that sets a Routing Flag instead:**

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/efZimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/efZimage.png)

```java
{
    "ParentID": "SKAARHOJ:HoldDown",
    "IOReference": {
        "Raw": "Flag:RoutingSource/White/Var:RouteIndex"
    },
    "FeedbackDefault": {
        "DisplayText": {
            "Title": "Preview"
        }
    }
}
```

**A more extreme setup of using a Virtual Trigger for setting the tally flags with tally status from an ATEM mixer:**

This is the file you load when you select a tally device in the constant set:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/sNnimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/sNnimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/dxrimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/dxrimage.png)  
Inside it has two Virtual Triggers that set the Program and Preview Tally and they do the same thing where they read the state of the tally parameter on the ATEM and store it into the flags on either the color red or green, depending on if it's the program or preview tigger.

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/4q6image.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/4q6image.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/XUqimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/XUqimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/lF9image.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/lF9image.png)

Full code for the ATEM Tally snippet:

```json
{
    "Name": "ATEM - Global Tally By Source Tally Flags",
    "MetaData": {
        "DeviceCoresInside": {
            "bmd-atem": []
        },
        "Priority": 150
    },
    "VirtualTriggers": [
        {
            "Name": "Set Program Tally",
            "ConstantSetReference": "CameraSelector",
            "Mode": "Binary",
            "BinaryActiveIf": "DC:bmd-atem/Var:TallyDeviceIndex/TallyBySourceTallyFlags/Behavior:Const:TallyIndex/1 == true",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:HoldDown",
                "IOReference": {
                    "Raw": "Flag:Tally/Red/Behavior:Const:TallyIndex"
                }
            }
        },
        {
            "Name": "Set Preview Tally",
            "ConstantSetReference": "CameraSelector",
            "Mode": "Binary",
            "BinaryActiveIf": "DC:bmd-atem/Var:TallyDeviceIndex/TallyBySourceTallyFlags/Behavior:Const:TallyIndex/2 == true",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:HoldDown",
                "IOReference": {
                    "Raw": "Flag:Tally/Green/Behavior:Const:TallyIndex"
                }
            }
        }
    ]
}
```

#### How to read a flag  


Reading a flag is very similar to setting a flag, but now we look at the feedback value of it instead and compare it against if it's true or false.

The simplest way to read a flag is to use the "SKAARHOJ:Output" behavior on a LED or GPO pin or in a virtual trigger where you might use the tally status reported by your switcher.

##### Some examples of this in use

Here is a couple of examples of how these setups look, they are posted here in json format as it's the simplest way to get a condensed look at the setup:  
  
**First the simplest way of reading it is for a GPO pin on an RCP for providing routing support externally:**

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/BONimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/BONimage.png)

```json
{
    "ParentID": "SKAARHOJ:Output",
    "IOReference": {
        "Raw": "Flag:RoutingSource/White/Var:RouteIndex"
    }
}
```

**Another use case for a Tally LED on a Blue Pill or RCP where you will see a setup like this, where it reads both the Red and Green Tally bit:**

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/Mlkimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/Mlkimage.png)

```json
{
    "Name": "Tally LED - Selected",
    "Description": "Show tally for selected tally index (in TallyIndex variable, using Tally Flag group)",
    "IOReference": {},
    "FeedbackDefault": {
        "Intensity": "Dimmed"
    },
    "FeedbackConditional": {
        "20": {
            "ActiveIf": "Flag:Tally/Green/Var:TallyIndex == true",
            "Color": {
                "ColorCode": "GREEN"
            },
            "Intensity": "On"
        },
        "30": {
            "ActiveIf": "Flag:Tally/Red/Var:TallyIndex == true",
            "Color": {
                "ColorCode": "RED"
            },
            "Intensity": "On"
        }
    }
}
```

**The last two main use cases that we will look at is reading a flag and then sending some command to a BMD Video hub for providing routing control, this is using virtual triggers:**

This is the file you load when you select a routing device in the constant set:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/L5Iimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/L5Iimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/xluimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/xluimage.png)

Inside it has virtual triggers that read the stored routing flag and sends the routing selected and sends it to the parameter on the Videohub.

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/bkMimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/bkMimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/norimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/norimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/GhVimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/GhVimage.png)

```json
{
    "Name": "Basic V-Trigger",
    "ActiveIf": "Var:UseHoldGroup:Current == false",
    "VirtualTriggers": [
        {
            "Name": "Set Routing Source",
            "ConstantSetReference": "CameraSelector",
            "Mode": "Binary",
            "BinaryActiveIf": "Flag:RoutingSource/White/Behavior:Const:RouteIndex == true",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:SetValue",
                "IOReference": {
                    "Raw": "DC:bmd-videohub/Var:RoutingDeviceIndex/routeInputToOutput/Var:RoutingBusSelect"
                },
                "EventHandlers": {
                    "trigger": {
                        "BinarySetValues": {
                            "Raw": "Behavior:Const:RouteIndex"
                        },
                        "IOReference": {}
                    }
                }
            }
        }
    ]
}
```

**The last main use case to show of here is doing the same as for routing but for forwarding the tally states directly to any camera connected. We will look at the setup for the Canon PTZ cameras in this example:** This example is taken from an ETH-GPIO Link, but it's the exact same code used on all PTZ controllers.  
Inside the Camera Selector you will have a field for the "Tally Forward Config", this should auto fill for you and look something like this:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/zmqimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/zmqimage.png)  
This will then load up like this inside the config, in something that should look familiar by now, as it's the same setup as for the tally and routing setups mentioned above.

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/l20image.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/l20image.png)

The big difference here is that this setup will very a lot depending on how the cameras handle tally, but one thing they will all have in common is that they have a trigger for disabling tally altogether, and that they all use the same flags, red and green for the tally feedback. On the Canon PTZ's you will see a total of 4 Virtual triggers. We will only look at the "Set Red" trigger.

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/9bOimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/9bOimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/vMWimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/vMWimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/scaled-1680-/FZ1image.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2022-10/FZ1image.png)

```json
{
    "Name": "Set Red Tally",
    "ActiveIf": "Var:TallyToCam == true",
    "Mode": "Binary",
    "BinaryActiveIf": "Flag:Tally/Red/Var:TallyIndex == true",
    "AnalogIOref": {},
    "HoldGroupFinalValue": {},
    "Behavior": {
        "ParentID": "SKAARHOJ:SetValue",
        "Constants": {
            "MatchValue": {
                "Values": [
                    "1"
                ]
            }
        },
        "IOReference": {
            "Raw": "DC:canon-xc/Var:DeviceIndex/f.tally.mode"
        }
    }
}
```

As seen above, it's basically the same thing the difference is only that here we have a "MatchValue" to select that it's the program we want to set on the Canon PTZ, if we want to swap the colors on the PTZ, then it's just a matter of changing this from a 1 to a number 2 and the reverse on the preview trigger. This is because of the options available on the camera, to look more at these option please refer to the parameter list for the Canon-XC core.  
  
Here is the full JSON for this layer with all 4 virtual triggers, in their current form:

```json
{
    "Name": "Canon XC - Tally",
    "MetaData": {
        "DeviceCoresInside": {
            "canon-xc": []
        },
        "Priority": 100
    },
    "VirtualTriggers": [
        {
            "Name": "Disable Tally To Cam",
            "Mode": "Binary",
            "BinaryActiveIf": "Var:TallyToCam == false",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:SetValue",
                "Constants": {
                    "MatchValue": {
                        "Values": [
                            "0"
                        ]
                    }
                },
                "IOReference": {
                    "Raw": "DC:canon-xc/Var:DeviceIndex/f.tally"
                }
            }
        },
        {
            "Name": "Toggle Tally lamp",
            "ActiveIf": "Var:TallyToCam == true",
            "Mode": "Binary",
            "BinaryActiveIf": "Flag:Tally/Red/Var:TallyIndex == true || Flag:Tally/Green/Var:TallyIndex == true",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:HoldDown",
                "IOReference": {
                    "Raw": "DC:canon-xc/Var:DeviceIndex/f.tally"
                }
            }
        },
        {
            "Name": "Set Red Tally",
            "ActiveIf": "Var:TallyToCam == true",
            "Mode": "Binary",
            "BinaryActiveIf": "Flag:Tally/Red/Var:TallyIndex == true",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:SetValue",
                "Constants": {
                    "MatchValue": {
                        "Values": [
                            "1"
                        ]
                    }
                },
                "IOReference": {
                    "Raw": "DC:canon-xc/Var:DeviceIndex/f.tally.mode"
                }
            }
        },
        {
            "Name": "Set Green Tally",
            "ActiveIf": "Var:TallyToCam == true",
            "Mode": "Binary",
            "BinaryActiveIf": "Flag:Tally/Green/Var:TallyIndex == true && Flag:Tally/Red/Var:TallyIndex == false",
            "AnalogIOref": {},
            "HoldGroupFinalValue": {},
            "Behavior": {
                "ParentID": "SKAARHOJ:SetValue",
                "Constants": {
                    "MatchValue": {
                        "Values": [
                            "0"
                        ]
                    }
                },
                "IOReference": {
                    "Raw": "DC:canon-xc/Var:DeviceIndex/f.tally.mode"
                }
            }
        }
    ]
}
```

### Flags used in Routing Triggers  


Routing Triggers in SKAARHOJ PTZ Controller configurations utilize a flag named "RoutingSource". This flag is used to communicate between the camera selector and a virtual trigger, providing information about the input source to be routed to a specific video switcher or hub when a camera is selected. The "RoutingSource" flag index varies across different controller configurations. For instance, the index for a PTZ Extreme is set to "11":

[![Screenshot 2024-01-24 at 10.23.16.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-24-at-10-23-16.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/screenshot-2024-01-24-at-10-23-16.png)

When managing multiple PTZ Extremes with the same configuration, a conflict arises as each controller's Routing Trigger setup uses the same index (11). This duplication can lead to operational issues. That same is true for other controllers and their configurations being shared.

**Solution to the Index Conflict**

The solution lies in creating a flag by the same name in the tree on a parent layer to the shared configuration. The "RoutingSource" flag (a "TreeDweller" property in the configuration tree) is not set with the "Always Define" flag. This allows for an alternate definition of "RoutingSource" on the parent layer of the configuration. When defined on this parent layer, it prevents the value inside the PTZ Extreme Configuration from overriding. Thus, for any additional configurations of similar controllers, you can assign a different index number to the "RoutingSource" flag by setting it on the parent layer. See below:

[![Screenshot 2024-01-24 at 10.29.02.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-24-at-10-29-02.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/screenshot-2024-01-24-at-10-29-02.png)

Adding a new flag is done from the tree by clicking the layer name and adding a flag in the Inspector:

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/CGUimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/CGUimage.png)

[![image.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/5qdimage.png)](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/5qdimage.png)

# Variables

<p class="callout warning">This documentation might be outdated. Please consult the Reactor manual at [https://docs.skaarhoj.com/3\_configuration/variables-conditions.html](https://docs.skaarhoj.com/3_configuration/variables-conditions.html)</p>

For increased flexibility in a configuration Variables are often applied. A variable works as an adjustable value which can be numerical or text based that can be used in place of a set value.

Variables live on the layers of the tree but are used in lots of different places and in different ways. It is on the layers that you can see what Variables are available, their names, and their current value. In the example below you can see how:

![Screenshot 2023-12-06 at 12.51.17 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2023-12/scaled-1680-/screenshot-2023-12-06-at-12-51-17-pm.png)

<p class="callout info">Please note, Variables in the tree are only accessible to the same layer they are created on or higher in the tree, unless defined otherwise in the variable set up. Additionally, layers limited by Active If conditions also set limits on the variable. </p>

There are two types of variables; range or options.

<details id="bkmrk-range-variables-name"><summary>Range Variables</summary>

  
![Screenshot 2024-01-17 at 12.40.48.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-17-at-12-40-48.png)

<table border="1" style="border-collapse: collapse; width: 83.5802%; height: 195.578px;"><colgroup><col style="width: 17.7998%;"></col><col style="width: 82.2002%;"></col></colgroup><tbody><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Name</td><td style="height: 29.7969px;">Variable's name</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Description</td><td class="align-center" style="height: 29.7969px;">Easy to understand description to help identify the variable's purpose</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Type</td><td style="height: 29.7969px;">Range or Options </td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Min</td><td style="height: 29.7969px;">Minimum value for the variable (must be lower than the max). Can be set to 0</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Max</td><td style="height: 29.7969px;">Maximum value for the variable (must be higher than the max)</td></tr><tr style="height: 46.5938px;"><td style="height: 46.5938px;">Center (or Default)</td><td style="height: 46.5938px;">Default value for the variable if not saved on panel reboot. </td></tr></tbody></table>

![Screenshot 2024-01-17 at 12.40.59.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-17-at-12-40-59.png)

<table border="1" style="border-collapse: collapse; width: 90.8642%;"><colgroup><col style="width: 21.4966%;"></col><col style="width: 78.5034%;"></col></colgroup><tbody><tr><td>Default to first</td><td>Sets default value to the first.</td></tr><tr><td>Default Value</td><td>Define the default value if not first.</td></tr><tr><td>Always define</td><td>Separates this instance of the variable from ones of the same name lower in the tree (overridden by Expand Scope).</td></tr><tr><td>Accept Any Value</td><td>Allows any value to be accepted during conformity check. </td></tr><tr><td>Expand Scope</td><td>Allows the variable to be used lower in the tree towards the root.</td></tr><tr><td>Capture</td><td>Allows a variable to capture any expanded-scope variable from a branch.</td></tr><tr><td>Persistent</td><td>Saves value between panel reboots.</td></tr><tr><td>Zero set Allow</td><td>Allows for the variable to be blank </td></tr><tr><td>Force value (test)</td><td>Force set a value for the variable, use for testing</td></tr></tbody></table>

**Variable Use Case**

Range variables are great for creating dynamic device parameters. In the example below, the variable is set within a parameter.

<p class="callout info">This is only a single example of the use of Options Variables. </p>

First looking at a breakdown of the parameter the variable is going to be added into: Atem Program Input Video Source

DC:bmd-atem/1/ProgramInputVideoSource/1/1

  
**DC** (DEVICE CORE) **:bmd-atem** (BMD-ATEM) **/1** (DEVICE ID 1) **/ProgramInputVideoSource** (Specified parameter)   
**/1** (M/E number) **/1** (Input Number)

A range variable would most naturally be put in place of numerical values, making Device ID, M/E Number, or Input Number great places use a variable. Using the variable in place of the Device ID will allow for switching instances of the Atem.   
It is possible to find the specific Device ID number of the Atems in the Device Details on the Home Page of Reactor.

![Screenshot 2024-02-06 at 10.33.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-02/scaled-1680-/screenshot-2024-02-06-at-10-33-51-am.png)

  
When creating the variable it is best to name is something easy to identify the place it should be used. ![Screenshot 2024-02-06 at 10.34.51 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-02/scaled-1680-/screenshot-2024-02-06-at-10-34-51-am.png)

Insetting that variable in the command would look like this:

 DC:bmd-atem/**Var:DeviceIndex**/ProgramInputVideoSource/1/1

<p class="callout info">Please note: Formatting is important for the variable name. </p>

 After setting the variable into a parameter it is important to set up a way to control the variable.

![Screenshot 2024-02-06 at 10.59.14 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-02/scaled-1680-/screenshot-2024-02-06-at-10-59-14-am.png)

The feedback will look like:

![Screenshot 2024-02-06 at 10.56.22 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-02/scaled-1680-/screenshot-2024-02-06-at-10-56-22-am.png)

Confirm the variable is changing properly in the tree:

![Screenshot 2024-02-06 at 10.56.41 AM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-02/scaled-1680-/screenshot-2024-02-06-at-10-56-41-am.png)

</details><details id="bkmrk-options-variable-nam"><summary>Options Variable</summary>

**Variable Set Up**![Screenshot 2024-01-17 at 12.41.28.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-17-at-12-41-28.png)

<table border="1" style="border-collapse: collapse; width: 83.5802%; height: 314.766px;"><colgroup><col style="width: 17.7517%;"></col><col style="width: 82.2495%;"></col></colgroup><tbody><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Name</td><td style="height: 29.7969px;">Variable's name</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Description</td><td class="align-left" style="height: 29.7969px;">Easy to understand description to help identify the variable's purpose</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Type</td><td style="height: 29.7969px;">Range or Options </td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Value</td><td style="height: 29.7969px;">Value string for the variable</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Label</td><td style="height: 29.7969px;">Easy to understand label used for feedback</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Flag</td><td style="height: 29.7969px;">Sets the option as the default value</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Trash</td><td style="height: 29.7969px;">Deletes the Option</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">Duplicate</td><td style="height: 29.7969px;">Duplicates the line</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">+1</td><td style="height: 29.7969px;">Increments the line by +1</td></tr><tr style="height: 46.5938px;"><td style="height: 46.5938px;">Add option</td><td style="height: 46.5938px;">Default value for the variable if not saved on panel reboot. </td></tr></tbody></table>

![Screenshot 2024-01-17 at 12.42.01.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-17-at-12-42-01.png)

<table border="1" style="border-collapse: collapse; width: 90.8642%;"><colgroup><col style="width: 21.4966%;"></col><col style="width: 78.5034%;"></col></colgroup><tbody><tr><td>Default to first</td><td>Sets default value to the first.</td></tr><tr><td>Default Value</td><td>Define the default value if not first.</td></tr><tr><td>Always define</td><td>Separates this instance of the variable from ones of the same name lower in the tree (overridden by Expand Scope).</td></tr><tr><td>Accept Any Value</td><td>Allows any value to be accepted during conformity check. </td></tr><tr><td>Expand Scope</td><td>Allows the variable to be used lower in the tree towards the root.</td></tr><tr><td>Capture</td><td>Allows a variable to capture any expanded-scope variable from a branch.</td></tr><tr><td>Persistent</td><td>Saves value between panel reboots.</td></tr><tr><td>Zero set Allow</td><td>Allows for the variable to be blank </td></tr><tr><td>Force value (test)</td><td>Force set a value for the variable, use for testing</td></tr></tbody></table>

**Variable Use Case**

Options variables are great for Active If conditions on layers of the tree. In the example below, the variable is set up to make active different page layers in the tree.

<p class="callout info">This is only a single example of the use of Options Variables. </p>

![Screenshot 2024-01-22 at 2.33.34 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-33-34-pm.png)

In the tree it would look like this. The blue line next to a layer indicates it is the active layer. In the layer where the variable lives, the variable also shows what its current value is.

![Screenshot 2024-01-22 at 2.33.54 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-33-54-pm.png)

On the page layer, the variable is set as the Active If conditions, meaning that need to be true for the layer to be the active layer.

![Screenshot 2024-01-22 at 2.36.04 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-36-04-pm.png)

 There are two main way to select the value of the parameter.

To set a specific value, mainly on key press or by trigger, select the variable as a parameter with the Settings Template as Set a Value Directly.

![Screenshot 2024-01-22 at 2.44.19 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-44-19-pm.png)

The feedback will look like this:

![Screenshot 2024-01-22 at 2.34.02 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-34-02-pm.png)

To cycle through the values, mainly on the pulse of an encoder, select the variable as a parameter with the Settings Template as Change Variable.

![Screenshot 2024-01-22 at 2.44.05 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-44-05-pm.png)

The feedback will look like this:

![Screenshot 2024-01-22 at 2.47.41 PM.png](https://wiki.skaarhoj.com/uploads/images/gallery/2024-01/scaled-1680-/screenshot-2024-01-22-at-2-47-41-pm.png)

</details>

# Virtual Triggers

<p class="callout warning">This documentation might be outdated. Please consult the Reactor manual at [https://docs.skaarhoj.com/3\_configuration/virtual-triggers.html](https://docs.skaarhoj.com/3_configuration/virtual-triggers.html)</p>

Sometimes you want to create interaction between devices using Reactor, or use the state of a device to change Variables in the system (eg changing the visible layer depending on the currently active camera)  
  
This is what Virtual Triggers are for, providing the ability to use Conditions and Values of Devicecores to change other values in the system or even on other devices  
  
  
**Virtual Triggers** in Reactor can be created on Layers in the Configurator and have 3 modes:

<table border="1" id="bkmrk-binary-analog-schedu" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 33.2919%;">**Binary**

</td><td style="width: 33.2919%;">**Analog**

</td><td style="width: 33.2928%;">**Schedule**

</td></tr><tr><td style="width: 33.2919%;">In Binary mode a condition will be interpreted like a Binary trigger (basically imitating a button).

While the condition is true the VirtualTrigger is "pressed" and while its false it is "released"

</td><td style="width: 33.2919%;">In Analog mode the selected parameter becomes an Analog Trigger (basically imitating a fader).

Everytime the value is changed a new Analog Value is sent to the defined Behavior

</td><td style="width: 33.2928%;">In Schedule mode you can configure a schedule of when your trigger will be executed using **cron** like syntax.

Everytime the specified time is reached the Virtual trigger will send a Binary trigger (basically a buttonpress) to the defined behavior

</td></tr></tbody></table>

---

### Cron explained

Cron is a UNIX utility that schedules a command or script on your server to run automatically at a specified time and date.

Not only does it allow for precise timing of unattended events, but it has a straightforward syntax

<table border="1" id="bkmrk-%2A-%2A-%2A-%2A-%2A-%2A-field-na" style="border-collapse: collapse; width: 100%; height: 169.578px;"><tbody><tr style="height: 29.7969px;"><td style="width: 14.3387%; height: 29.7969px;">  
</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">**\***</td></tr><tr style="height: 29.7969px;"><td style="width: 14.3387%; height: 29.7969px;">**Field name**</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Seconds</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Minutes</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Hours</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Day of month</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Month</td><td class="align-center" style="width: 14.3387%; height: 29.7969px;">Day of week </td></tr><tr style="height: 46.5938px;"><td style="width: 14.3387%; height: 46.5938px;">**Allowed values**</td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">0-59</td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">0-59</td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">0-23</td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">1-31 </td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">1-12 or   
JAN-DEC</td><td class="align-center" style="width: 14.3387%; height: 46.5938px;">0-6 or   
SUN-SAT</td></tr><tr style="height: 63.3906px;"><td style="width: 14.3387%; height: 63.3906px;">**Allowed special characters**</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , -</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , -</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , -</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , - ?</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , -</td><td class="align-center" style="width: 14.3387%; height: 63.3906px;">\* / , - ?</td></tr></tbody></table>

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

<table border="1" id="bkmrk-entry%C2%A0-description-e" style="border-collapse: collapse; width: 100%;"><tbody><tr><td style="width: 28.4326%;">**Entry** </td><td style="width: 38.3165%;">**Description**</td><td style="width: 33.3745%;">**Equivalent To**</td></tr><tr><td style="width: 28.4326%;">@yearly (or @annually)</td><td style="width: 38.3165%;">Run once a year, midnight, Jan. 1st</td><td style="width: 33.3745%;">0 0 0 1 1 \*</td></tr><tr><td style="width: 28.4326%;">@monthly</td><td style="width: 38.3165%;">Run once a month, midnight, first of month</td><td style="width: 33.3745%;">0 0 0 1 \* \*</td></tr><tr><td style="width: 28.4326%;">@weekly</td><td style="width: 38.3165%;">Run once a week, midnight between Sat/Sun</td><td style="width: 33.3745%;">0 0 0 \* \* 0</td></tr><tr><td style="width: 28.4326%;">@daily (or @midnight) </td><td style="width: 38.3165%;">Run once a day, midnight</td><td style="width: 33.3745%;">0 0 0 \* \* \*</td></tr><tr><td style="width: 28.4326%;">@hourly</td><td style="width: 38.3165%;">Run once an hour, beginning of hour </td><td style="width: 33.3745%;">0 0 \* \* \* \*</td></tr></tbody></table>

---

#### Videos

In these videos Kasper shows some examples of how to work with Virtual Triggers.  
  
<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/_NHMzD10Qzc" width="560"></iframe>

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/k-vT89Z5BUk" width="560"></iframe>

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/PELylIUdY4k?t=1095s" width="560"></iframe>