10.8. Setting Trigger Conditions

Each logging action can have up to four conditions that determine whether a row gets written to the database when the trigger fires.

Fill in the conditions according to the guidelines below. Check the box next to the condition to apply it. As you make entries, the corresponding Gamma code will appear in the display. The Gamma language is the DataHub program's built-in scripting language. The code that appears in the Expression box is the actual code that gets run by the Gamma engine. The order of precedence for "And" and "Or" operators (&& and ||) is first And, then Or.

Point Value Conditions

Point names can be entered on either or both sides of the comparison. They can be picked from the data tree list, or typed in. Each point name needs to have a dollar sign ($) in front of it to indicate to the Gamma engine that this is a DataHub point. You can put numerical values into either side of the comparison.

When you enter a point name in a condition field, the current value of the point will be used in the evaluation. For example, you could define a condition that states that whenever the trigger event occurs, the action will only be executed if another point value is within a certain range.

There are some automatic variables available for working with point values:

You can use these variables in any condition that is triggered by a data value change. For example, you could create some conditions like this:

Time Conditions

This provides an additional way to restrict the time, day, month, etc. when a message gets sent. In addition to the options on the triggers, here you have day-of-week condition statements which can give you more flexibility for events based on specific days of the week. These will work with any type of trigger event.

You can use the Gamma functions clock and localtime to specify particular days of the week. For example, these entries:

would create this Gamma code::

(localtime(clock()).wday > 0 && localtime(clock()).wday < 6)

which would cause data to be logged only Monday through Friday. The function localtime returns a class whose members contain information about the date, as follows:

.sec

The number of seconds after the minute (0 - 59).

.min

The number of minutes after the hour (0 - 59).

.hour

The number of hours past midnight (0 - 23).

.mday

The day of the month (1 - 31).

.mon

The number of months since January (0 - 11)

.year

The number of years since 1900.

.wday

The number of days since Sunday (0 - 6).

.yday

The number of days since January 1 (0 - 365)

.isdst 

1 if daylight saving time is in effect, 0 if not, and a negative number if the information is not available.

[Note]

The year and month are entered differently here than for Time of Day trigger conditions, as explained in Section 10.7, “Assigning a Trigger”.

There are two automatic variables available for working with time values:

Custom Conditions

If the conditions you need to meet are beyond the scope of this interface, you can use a Gamma function to express virtually any condition you need. Then you can insert the function into one of the condition boxes, and set a condition based on the return value of the function.

To do this is you can create a DataHub script (.g file) that contains only the functions you will be using for conditions, without any classes or methods. For example, here is the complete contents of such a file, named MyConditions.g:

function MyFunction ()
{
    myvalue = $DataSim:Sine;
    princ("Value when the trigger fired: ", myvalue, "\n");
    myvalue;
}

This function prints the value of the DataSim:Sine point, and returns its value. We can use this function as a condition by calling it from one of the condition boxes in the interface, like this:

When the trigger fires, MyFunction is called, and the return value gets checked to see if it is less than .4. If so, the data gets logged.

Below are two practical examples demonstrating custom functions. The first creates an automatically resetting trigger, and the second lets you test for changed values before logging a point, which is useful if you are logging based on a timer.

An Auto-Resetting Trigger

This script can turn any DataHub point into a trigger that automatically resets. To use it, you first need to load and run the TriggerFunctions.g script (shown below). Then, if you put this formula:

HighWithReset($TriggerPoint)!= nil

into the condition boxes, whenever the TriggerPoint changes to a non-zero number in the DataHub instance, your trigger will fire. The script waits for a millisecond, then resets the TriggerPoint back to zero. The second function works similarly, but triggers on a change to zero, instead of a change to a non-zero number.

TriggerFunctions.g

/*
 * This file contains handy functions to perform more complex
 * condition handling in the Condition tab of the data logging
 * and email interfaces.
 */

/*
 * Test a trigger point for a non-zero value.  If the point is
 * non-zero, create a delayed event to reset the point to zero,
 * and return true, indicating that the condition has succeeded
 * and the action should proceed. If the value is 0, then simply
 * return nil indicating that the action should not proceed.  We
 * need to test for zero because when we reset the trigger point
 * to zero a second data change event will occur.
 *
 * The argument is unevaluated, so the condition should look
 * like this:
 *    HighWithReset($default:TriggerPoint) != nil
 */

function HighWithReset(!triggerpoint)
{
    local   value;
    if (!undefined_p(value = eval(triggerpoint)) && value != 0)
    {
        after(0.001, `setq(@triggerpoint, 0));
        t;
    }
    else
    {
        nil;
    }
}

/*
 * This is the inverse of HighWithReset (see above).  If the trigger
 * point is zero, perform the action and set the trigger point to 1.
 * If the trigger point is non-zero do nothing and return nil.
 */
function LowWithSet(!triggerpoint)
{
    local   value;
    if (!undefined_p(value = eval(triggerpoint)) && value == 0)
    {
        after(0.001, `setq(@triggerpoint, 1));
        t;
    }
    else
    {
        nil;
    }
}


Test for Changed Values Before Logging

If you are logging data based on a timer, you can use this script to check the previously logged value, and only log a new row in the database if the value has changed. To use the script, you first need to load and run the LogFunctions.g script (shown below and included in the installation archive). Then, if you put this formula:

HasValueChanged(#$TestPoint)!= nil

into the condition boxes, when the TestPoint has not changed, the data for that row will not be logged.

The call to HasValueChanged uses the syntax #$pointname to specify the point. If you select the point from the tree to the right and press the + button, it will not include the # symbol. You need to manually add it. You can see the complete condition expression in the Expression: line beneath the condition selectors, like this:

LogFunctions.g

/*
 * Functions that can be used by the Condition section of a Data
 * Logging configuration to filter whether data is actually written
 * to the database when a trigger occurs.
 */

// Change this to nil to silence the debugging statements that will
// be written to the script log.
LogFunctionDebug = t;
 
 /*
  * Track the previous value of a DataHub point and only allow the
  * logging action if the DataHub point value has changed since the
  * last time we logged it.
  *
  * Takes a single argument that is either a point symbol or a point
  * name as a string.
  *    e.g., "DataPid:PID1.Mv"
  *          #$DataPid:PID1.Mv
  *
  * Notice that a point symbol must be specified with the # operator
  * before the symbol to ensure that the symbol is passed, not the
  * value of the point.
  */

function HasValueChanged(point_symbol)
{
    local ptsym = symbol(point_symbol);
    local oldvalue = getprop(ptsym, #last_log_value);
    local curvalue;
    local result = nil;
    
    if (!undefined_p(curvalue = eval(ptsym)))
    {
        if (LogFunctionDebug)
            princ("Checking value of ",
		  ptsym, ": previous = ", oldvalue,
                  ", current = ", curvalue, "\n"); 
        if (oldvalue != curvalue)
            result = t;
        setprop(ptsym, #last_log_value, curvalue);
    }
    else
    {
        if (LogFunctionDebug)
            princ("Log condition: value of ",
		  ptsym, " is undefined\n");
    }
    result;
}