Setting a Countdown Timer with a User State Variable
Overview
The following document provides an explanation of how to utilize User-defined State Variables within RacePoint Blueprint, along with Custom Workflows and State Triggers, to measure whether a change in a state variable's value persists for a given time. This can then be used to trigger a selected system action. Some common use cases for this type of programming include:
Triggering an action (such as sending an email alert, or turning off an HVAC service,) when a security system state holds a given value for a set time
Adding a condition to a projector lift trigger which prevents the lift from activating during a cooling off period, retracting the projector only if its power state stays off for a set time.
Using a GPIO motion-sensor to trigger lighting actions, shutting the light(s) off only if the motion sensor remains inactive for a certain set time
While the above use-cases are some of the most common, the same general programming logic described below can be used in any other situation where it is desirable to monitor a change in state value for persistence and trigger some action if it persists for a given time. A wide variety of potential applications are possible.
Other Methods of Delaying Triggered Actions and How they Differ
There are a number of available methods of delaying a triggered action from being executed, such as the "After Delay" option in the State Trigger window, or the "Delay (seconds)" option on a Send Service Request action within Automator for a custom workflow. These can be useful for a variety of applications, however they do not enable the monitoring of state persistence in the way the process described in this Application Note does. Standard methods of delaying an action will send that action after the delay, regardless of any other events; while the User-defined State Variable method laid out in this document will send the action only if the triggering state change holds its value for the set time. The USV-method monitors whether a state changes to a given value and stays changed to that value for a given amount of time. This allows a much more granular degree of control over the conditions for the triggered action in situations where this is needed.
*Note: There is also a Pause action available within Automator which can be added to a workflow. Use of this action should be avoided whenever possible, because the Automator Pause is a full system stop. This means that rather than halting the workflow for the selected time before going on to the next action, an Automator Pause halts all system action entirely for the set time. This can potentially interrupt a wide range of other functionalities and processes, resulting in unexpected system issues. A good alternative to using an Automator Pause is to create separate workflows for any actions which need to be followed with a pause, then using the Send Service Request action with the Delay (seconds) option enabled to send them together with a nested workflow or "super-workflow". For further detail, refer to Automator Best Practices: RacePoint Blueprint Programming Guide
Basic Elements
The main elements of this method of measuring whether a state variable holds its value over a given time are:
User-defined State Variable: Created in RacePoint Blueprint under Tools > Review > User State Variables. This should be either a string or date type variable, with no initial value.
Custom Workflows: Created under General Programmable Service Requests within the View Services window for a selected Zone. Two workflows should be added, each using a Savant State Setter action: one which sets the value of the USV to Current Time plus a certain value, (the number of seconds desired for the delay/state persistence measurement), and one to set the USV to some null, non-Date/Time value, (in the example below, a string type with a value of _ will be used). A third workflow to run the desired resulting action should be configured as well if needed.
State Triggers: Created under Tools > Review > State Triggers, or from the Review Triggers clock icon in the main RacePoint Blueprint toolbar menu. Two to three State Triggers should be created or modified: one which sets the USV to the timer state, (Date type, CurrentTime + persistence timer value in seconds,) when the monitored state changes to the target value, one which sets the USV to a null state when the monitored state changes to a value other than the target value, and one which runs the desired action if the timer expires, (USV value matches CurrentTime). Depending on the circumstances and the particular monitored state, it may be possible to combine the first two trigger actions, which set and nullify the USV value, into a single State Trigger using the Else field rather than a separate second trigger.
Note: All custom RacePoint Blueprint programming of this type should be configured during the final stages of system deployment, after all standard services have been implemented and tested. When configuring any state triggers, it is best to begin planning while access to the live system is available, so that conditional state variables can be chosen after testing to confirm that they change reliably in the expected way. This will ensure a stable foundation on which to build more complex custom programming.
Specific Use Case Example:
Triggering Actions Based on a Persisting Security System State Value
With integrated security systems, it is often desirable to take some system action based on a change in the state of a particular security zone, such as sending an email alert to the user, or shutting down HVAC services to avoid wasting energy when a faulted zone indicates that a door or window is open. However, if these events are set to be triggered every time the security zone becomes faulted or tripped, they would likely fire too frequently, causing inconvenience for the user. In this example, a USV-based state trigger will be configured to run these actions only if a security zone is faulted and remains faulted for 5 minutes, (300 seconds).
Desired Functionality: Send an email alert to the end user, and set the HVAC Mode for the thermostat at address 1 to Off if security zone 4 ("LR South Window") stays faulted for more than 300 seconds.
Note: This example process requires that the current RacePoint Blueprint configuration contain a completed, functional security system integration. If possible, it is best to perform the steps below while access to the live system is available.
Steps:
Navigate to Tools > Review > User State Variables and create a new User State Variable with the "String" type. The "Date" type could also be used, as the value type will be set to one or the other under different conditions using custom workflows. After adding a name and type, Save the User Defined State Variable.
Next, custom workflows will be added to write the necessary values to the User-defined State Variable. Under General Programmable Service Requests in the View Services window for a selected zone, click the + icon to add a Custom Workflow to act as the Set Timer Action. Open the workflow in Automator by double-clicking it, and add a Savant State Setter action which sets the USV to a value of Current Time plus the number of seconds the state value should persist for in order to trigger the desired result action. In this example the value will be 300 seconds, as shown below:
Note that the State Name must match the name given to the USV exactly. Once all fields are populated correctly, manually save the workflow (File > Save,) before exiting the Automator window.
Note: For specific details on Custom Workflow configuration, refer to the Knowledge Base article: Custom Workflow Development: RacePoint Blueprint Programming Guide. For more information on using Automator in general, refer to Automator Best Practices: RacePoint Blueprint Programming Guide
Add another Custom Workflow to General Programmable Service Requests which will be used as a Clear Timer action. Open it in Automator, and add a Savant State Setter action which sets the User State Variable to a null, non-Date/Time value. In this example, a String State Value Type with a State Value of _ (underscore) will be used: Once configured as above, save the workflow manually (File > Save,) before exiting Automator.
There should now be two new Custom Workflows added under General Programmable Service Requests:
Add any other Custom Workflows which may be needed to perform the desired result actions, (the things which ultimately should happen if the monitored state does persist for the set time). In this example, a workflow will be added to send an email alert to the end user indicating that the Living Room South Window has been open for over 5 minutes:
This example configuration will also include a triggered action to set the HVAC mode to "Off" for the Thermostat at address 1, but this is an existing action, for which a default service request already exists, so there is no need to add it as a custom workflow.
Note: For specific details on how to send an email/SMS text alert, refer to the Knowledge Base article: How to Send an Email/SMS Text Notification from a Triggered Workflow
Now that the USV, the workflows used to set its value, and the workflows needed to perform the desired result actions have all been configured, the next step is to begin creating State Triggers to run the actions automatically under the relevant system conditions. Navigate to Tools > Review > State Triggers, or click the Review Triggers icon in the main RacePoint Blueprint menu bar to open the State Trigger window. Add a new trigger using the "+" button and name it.
Open the SRS Window using the ▷ icon at the bottom right, and locate the state which will be used as the trigger condition to start the timer. In this example, the state being used is CurrentZoneStatus_4 for the Security System service, found under the Component tab of the SRS window.
Drag the selected state into the if (rules) section of the state trigger. It will auto-populate into the When any of these states change value, evaluate the Rules section, (referred to through the rest of this document as the Monitored States section). Set the value for the state exactly as it appears in State Center (System Monitor > System State) under the conditions which should start the timer. This will vary greatly from case to case, depending on the state, the desired function, the components involved, and a number of other factors. It is important to be sure to copy the desired value exactly as it appears in State Center when adding it to the value field of a state trigger. If possible, it is always best to drag the state value out from the SRS window rather than typing it in manually. In this example, the state value which should start the timer is "faulted". the timer should only be engaged when this value is matched exactly, so the default Test Condition value of "is equal" should remain.
Once the if (rules)section has been populated, return to the SRS window, switch to the Services tab, and locate the Set Timer workflow created under General Programmable Service Requests in step 2 above. Drag the workflow into the then section of the State Trigger.
The logic of the resulting trigger breaks down as follows:
If the state value for Security.system CurrentZoneStatus_4 changes and becomes "faulted", set the Timer for 300 seconds;
If the state value for Security.system CurrentZoneStatus_4 changes and becomes anything other than "faulted", nullify the timer.
In this example, because the state being used as the main trigger condition, CurrentZoneStatus_4 is the only state being monitored for the timer, the else window can be used to send the workflow which nullifies the USV timer, (as opposed to evaluating based on two states such as "triggerIsHigh" and "triggerIsLow" for a GPIO sense trigger for example, which would require a separate state trigger). Drag the Clear Timer workflow created in step 3 above from the Services tab of the SRS window into the else section of the trigger as shown below:
Save the first trigger, then add a second one using the "+" icon next to the first trigger's name. This second trigger will be used to send the workflow created in step 2 if the USV timer runs out without being nullified.
In the SRS Window under Other > User Defined, locate the USV created in step 1 :
Drag the Timer USV into the if (rules) section of Trigger 2:
In the top Monitored States section, highlight the USV, which will populate in this field automatically when added to the if (rules) section, and click the "-" icon to remove it.
A value must now be added for the USV in the if (rules) section, in the form of a time value for this example. According to the logic in Trigger 1, when Zone 4 is faulted, the USV's value is set to the current time + 300 seconds. After 300 seconds, if CurrentZoneStatus_4 has not changed again, (which would trigger the Clear Timer workflow and make the USV's value "_",) the (global)CurrentTime state and the Security 4 Execute Time USV will have the same values, so CurrentTime should be added as the conditional value of the USV under the if (rules) statement of this trigger. In the SRS window, locate CurrentTime under Other > Time and Date and then drag it into the Value field of the if (rules) section of Trigger 2.
CurrentTime will automatically populate in the top Monitored States field when added to the value field of theif (rules) field. This is now a functional set of trigger statements, meaning that if the Then section were populated, the action in it would run if the CurrentZoneStatus_4 state were to change to a value of faulted and stay faulted for 5 minutes. However, setting any state trigger to evaluate based on changes in CurrentTime is not recommended by Savant, and should be avoided if possible, as it places an extremely heavy strain on Host resources by requiring that the trigger be evaluated every second on the second.
In this example, there is no need for exact precision down to the second, and the trade-off in excessive use of Host resources is too great, so rather than evaluate Trigger 2 based on changes to CurrentTime, the CurrentMinute state will be used. This means that if CurrentZoneStatus_4 remains faulted for over 300 seconds, the trigger will execute on the next change of CurrentMinute, so rather than five minutes exactly, it could be anywhere from 5 minutes to 5 minutes 59 seconds. Locate CurrentMinute in the SRS window and drag the variable into the Monitored States section of Trigger 2.
Both CurrentTime and CurrentMinute should now show in the top Monitored States section of the trigger. Click to highlight the CurrentTime state, then click the " - " to remove it.
Adjust the Test Condition in the if (rules) section to be less than or equal. While the trigger will now evaluate based on changes in CurrentMinute, the value variable for the if (rules) section should remain CurrentTime. The resulting logic should be as follows:
Whenever CurrentMinute changes, check the value of Security 4 Execute Time (USV).
If that value is less than or equal to the value of CurrentTime, run [Actions populated in the Then section].
Add the desired result actions to the Then section of Trigger 2. For this example, the previously configured email alert custom workflow will be added, as well as an HVAC service request to set the HVAC Mode to "Off" for the thermostat which covers the Living Room zone, (address 1). In the SRS window, under the Services tab, navigate to the part of the list covering services for the Living Room Zone. Under General Programmable Service Requests, drag the Security 4 Alert workflow created in step 5 above from the Requests tab into the Then section of Trigger 2. Then, under the HVAC Service, locate the request for SetHVACModeOff and drag it to the Then section of the trigger as well.
Click the disclosure triangle for the SetHVACModeOff service request within the trigger Then section and add the correct thermostat address to target, which is 1 in this example.
In the SRS window, return to General Programmable Service Requests for the Living Room Zone, and drag the Security 4 Clear Timer action used to set the USV value to "_" into the Then section. This will prevent the trigger from firing repeatedly every minute. Depending on individual system conditions, it may be necessary to add a slight delay to the clear action using the After Delay field. When complete, Trigger 2 should essentially match the image below:
Save trigger 2, ensure that both triggers are enabled, then save the RacePoint Blueprint configuration as a test copy. Clear the existing configuration from the Host and upload the test copy and verify that the timer is working as intended.
Trigger and Service Request Delay options use the logic:
The USV-based method described here uses the logic:
IF: [state] changes to [value], THEN: [after "X" amount of time] run ["Y" action]
IF: [state] changes to [value] AND that value does not change for ["X" amount of time], THEN: run ["Y" action]
The state variable CurrentTime should only be used as a monitored state within a State Trigger in cases where absolute, second-by-second accuracy is required, and in such cases it should be understood that the heavy use of Host processing resources required to support this configuration could potentially cause other issues.