SimpleAverage.g — computes average point values over a period of time.
![]() | |
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. |
/*
* Compute simple averages for points over a selected time period.
* Write the average to a new data point continuously or
* periodically as the input changes, resetting the average at
* the end of the period.
*/
require ("Application");
require ("ModelSupport");
class SimpleAverage Application
{
// One of "day", "hour", "minute", "10sec"
period = "10sec";
// A pattern containing %s where the point name is inserted to
// create the average point name
outputPattern = "%sAvg";
// Select running average (constant updating) or write at the
// end of period. Use t for running average, or nil for update
// at the end of the period.
isRunningAverage = t;
// Do not edit this
accumulators = new Dictionary();
model = new ModelEmitter();
}
/*
* This is the start-up method. Add code here to monitor other data
* points by calling .monitor for each point, or by iterating through
* all points to monitor those that you want.
*/
method SimpleAverage.constructor ()
{
.monitor("DataPid:PID1.Mv");
// After setting up the monitored points, emit the model to place
// the points into the point heirarchy, then start the timer to
// reset the average periodically.
.model.Emit();
.startResetTimer();
}
/* -------------- Implementation starts here ----------------- */
class Accumulator
{
point;
sum = 0;
count = 0;
}
method Accumulator.getAverage()
{
.count > 0 ? .sum / .count : 0;
}
method Accumulator.reset()
{
.sum = .count = 0;
}
method SimpleAverage.update (pointSym, value)
{
local accumulator = .accumulators[pointSym];
if (!accumulator)
{
accumulator = new Accumulator();
accumulator.point = pointSym;
.accumulators[pointSym] = accumulator;
}
accumulator.count++;
accumulator.sum += number(value);
if (.isRunningAverage)
.writeAverage(accumulator);
}
method SimpleAverage.writeAverage(accumulator)
{
local avgName = format(.outputPattern, string(accumulator.point));
local value = accumulator.getAverage();
//princ (avgName, " = ", value, "\n");
datahub_write(avgName, value, t);
}
method SimpleAverage.monitor(pointName)
{
local sym = symbol(pointName);
local current;
.OnChange(sym, `(@self).update(this, value));
if (!undefined_p(current = eval(sym)))
.update(sym, current);
local avgName = format(.outputPattern, pointName);
.model.MapPoint(avgName, ".", "R8", "r");
}
method SimpleAverage.reset()
{
//princ ("Reset\n");
with accumulator in .accumulators.values do
{
if (!.isRunningAverage)
.writeAverage(accumulator);
accumulator.reset();
}
}
method SimpleAverage.startResetTimer()
{
if (.period == "10sec")
{
.TimerAt(nil, nil, nil, nil, nil, list(0, 10, 20, 30, 40, 50),
`(@self).reset());
}
else if (.period == "minute")
{
.TimerAt(nil, nil, nil, nil, nil, 0, `(@self).reset());
}
else if (.period == "hour")
{
.TimerAt(nil, nil, nil, nil, 0, 0, `(@self).reset());
}
else if (.period == "day")
{
.TimerAt(nil, nil, nil, 0, 0, 0, `(@self).reset());
}
else
{
princ ("No period set - will average over all time\n");
}
}
/* Start the program by instantiating the class. */
ApplicationSingleton (SimpleAverage);