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 one of these locations: C:\Program Files\Cogent\OPC DataHub\scripts\ C:\Program Files\Cogent\Cascade DataHub\scripts\ 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);
Copyright © 1995-2010 by Cogent Real-Time Systems, Inc. All rights reserved.