TagMonitor.g — monitors DataHub points for changes in quality or failure to change value.
![]() | |
The code for this and other example scripts can be found in the DataHub distribution archive, typically at this location:
Please refer to Section 3.1, “How to Run a Script” for more information on using scripts. |
/*
* This script monitors tags (or DataHub points) for two conditions:
*
* 1) change of quality
* 2) failure to change within a time period
*
* For each of these, the script creates synthetic points
* (the "target") that hold the result of monitoring the watch points.
* Email and * database events can then be triggered from the
* synthetic points.
*
* You can modify the constructor function in this script to change
* the point names, or to add additional watch conditions as needed.
*/
require ("Application");
class TagMonitor Application
{
}
/*
* Set up a watch tag and a target tag such that the quality of the
* watch tag is copied into the value of the target tag.
*/
method TagMonitor.copyQuality(poll_seconds, watch, target)
{
// Ensure that the input and output tags exist.
datahub_command(format("(create %s 1)", stringc(watch)), 1);
datahub_command(format("(create %s 1)", stringc(target)), 1);
// Periodically copy the quality of the watch point into
// the value of the target
.TimerEvery(poll_seconds,
`set(#@target, PointMetadata(#@watch).quality));
}
/*
* Set up a watch tag, a target tag and a time such that the target
* tag will be set to 1 if the watch tag has changed within the timer
* period, or zero if the watch tag has not changed within the time
* period. The time period is specified by dead_seconds, which may
* be fractional.
*/
method TagMonitor.copyChangeStatus(dead_seconds, watch, target)
{
// Ensure that the input and output tags exist.
datahub_command(format("(create %s 1)", stringc(watch)), 1);
datahub_command(format("(create %s 1)", stringc(target)), 1);
// Start the watch point off as having changed
setprop(watch, #has_changed, t);
// Whenever the watch point changes, set its property
// "has_changed" to t.
.OnChange(watch, `(@self).watchHasChanged(#@watch, #@target));
.TimerEvery(dead_seconds,
`(@self).checkChange(#@watch, #@target));
}
/*
* A callback function that checks for a change in a point and puts
* a 1 or 0 into the target. Reset the changed flag to zero.
*/
method TagMonitor.checkChange(watch, target)
{
set(target, getprop(watch, #has_changed) ? 1 : 0);
setprop(watch, #has_changed, nil);
}
/*
* A callback whenever a change watch point changes. We use this to
* change from 0 to 1 as soon as we see a change in a watch point
* instead of waiting for the poll delay.
*/
method TagMonitor.watchHasChanged(watch, target)
{
setprop(watch, #has_changed, t);
set(target, 1);
}
/* Write the 'main line' of the program here.
*
* As written, the points to watch for quality and change, as well as
* the target points to modify, are all in the "default" domain,
* as follows:
*
* Point to watch for quality: default:quality_watch
* Point to watch for change: default:change_watch
* Target point for quality: default:quality_target
* Target point for change: default:change_target
*
* You can change these to different domain and point names. Also,
* you can add any number of other points to monitor quality and
* change, following the same syntax.
*
* The first argument of .copyQuality is the poll rate in seconds on
* the quality of the point. The first argument of .copyChangeStatus
* is the number of "dead" seconds to wait for a change, before
* notifiying of a failure.
*/
method TagMonitor.constructor ()
{
.copyQuality(1, #$default:quality_watch,
#$default:quality_target);
.copyChangeStatus(5, #$default:change_watch,
#$default:change_target);
}
/* Any code to be run when the program gets shut down. */
method TagMonitor.destructor ()
{
}
/* Start the program by instantiating the class. If your
* constructor code does not create a persistent reference to
* the instance (self), then it will be destroyed by the
* garbage collector soon after creation. If you do not want
* this to happen, assign the instance to a global variable, or
* create a static data member in your class to which you assign
* 'self' during the construction process. ApplicationSingleton()
* does this for you automatically. */
ApplicationSingleton (TagMonitor);