Add deadband plugin (client defined monitor deadband)
This commit is contained in:
@@ -85,4 +85,5 @@ dbCore_SRCS += dbIocRegister.c
|
||||
dbCore_SRCS += chfPlugin.c
|
||||
|
||||
LIB_SRCS += ts.c
|
||||
LIB_SRCS += dbnd.c
|
||||
|
||||
|
||||
141
src/ioc/db/filters/dbnd.c
Normal file
141
src/ioc/db/filters/dbnd.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven National Laboratory.
|
||||
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
|
||||
* fuer Materialien und Energie GmbH.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Ralph Lange <Ralph.Lange@bessy.de>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <epicsExport.h>
|
||||
#include <epicsMath.h>
|
||||
#include <freeList.h>
|
||||
#include <dbConvertFast.h>
|
||||
#include <chfPlugin.h>
|
||||
#include <db_field_log.h>
|
||||
|
||||
typedef struct myStruct {
|
||||
int mode;
|
||||
double cval;
|
||||
double hyst;
|
||||
double last;
|
||||
} myStruct;
|
||||
|
||||
static void *myStructFreeList;
|
||||
|
||||
static const
|
||||
chfPluginEnumType modeEnum[] = { {"abs", 0}, {"rel", 1}, {NULL,0} };
|
||||
|
||||
static const
|
||||
chfPluginArgDef opts[] = {
|
||||
chfDouble (myStruct, cval, "d", 0, 1),
|
||||
chfEnum (myStruct, mode, "m", 0, 1, modeEnum),
|
||||
chfPluginArgEnd
|
||||
};
|
||||
|
||||
void * allocPvt(void)
|
||||
{
|
||||
return freeListCalloc(myStructFreeList);
|
||||
}
|
||||
|
||||
void freePvt(void *pvt)
|
||||
{
|
||||
freeListFree(myStructFreeList, pvt);
|
||||
}
|
||||
|
||||
int parse_ok(void *pvt)
|
||||
{
|
||||
myStruct *my = (myStruct*) pvt;
|
||||
my->hyst = my->cval;
|
||||
my->last = epicsNAN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void shiftval (myStruct *my, double val) {
|
||||
my->last = val;
|
||||
if (my->mode == 1)
|
||||
my->hyst = val * my->cval/100.;
|
||||
}
|
||||
|
||||
static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
|
||||
myStruct *my = (myStruct*) pvt;
|
||||
long status;
|
||||
double val, delta;
|
||||
short drop = 0;
|
||||
|
||||
/*
|
||||
* Only scalar values supported - strings, arrays, and conversion errors
|
||||
* are just passed on
|
||||
*/
|
||||
if (pfl->type == dbfl_type_val) {
|
||||
DBADDR localAddr = chan->addr; /* Structure copy */
|
||||
localAddr.field_type = pfl->field_type;
|
||||
localAddr.field_size = pfl->field_size;
|
||||
localAddr.no_elements = pfl->no_elements;
|
||||
localAddr.pfield = (char *) &pfl->u.v.field;
|
||||
status = dbFastGetConvertRoutine[pfl->field_type][DBR_DOUBLE]
|
||||
(localAddr.pfield, (void*) &val, &localAddr);
|
||||
if (!status) {
|
||||
if (isnan(my->last)) {
|
||||
shiftval(my, val);
|
||||
} else {
|
||||
delta = fabs(my->last - val);
|
||||
if (delta <= my->hyst) {
|
||||
drop = 1;
|
||||
} else {
|
||||
shiftval(my, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drop) return NULL;
|
||||
else return pfl;
|
||||
}
|
||||
|
||||
static void channelRegisterPre(dbChannel *chan, void *pvt,
|
||||
chPostEventFunc **cb_out, void **arg_out, db_field_log *probe)
|
||||
{
|
||||
*cb_out = filter;
|
||||
*arg_out = pvt;
|
||||
}
|
||||
|
||||
static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent)
|
||||
{
|
||||
myStruct *my = (myStruct*) pvt;
|
||||
printf("%*s plugin dbnd, mode=%s, delta=%g%s\n", indent, "",
|
||||
chfPluginEnumString(modeEnum, my->mode, "n/a"), my->cval,
|
||||
my->mode == 1 ? "%" : "");
|
||||
}
|
||||
|
||||
static chfPluginIf pif = {
|
||||
allocPvt,
|
||||
freePvt,
|
||||
|
||||
NULL, /* parse_error, */
|
||||
parse_ok,
|
||||
|
||||
NULL, /* channel_open, */
|
||||
channelRegisterPre,
|
||||
NULL, /* channelRegisterPost, */
|
||||
channel_report,
|
||||
NULL /* channel_close */
|
||||
};
|
||||
|
||||
static void dbndInitialize(void)
|
||||
{
|
||||
static int firstTime = 1;
|
||||
|
||||
if (!firstTime) return;
|
||||
firstTime = 0;
|
||||
|
||||
if (!myStructFreeList)
|
||||
freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
|
||||
|
||||
chfPluginRegister("dbnd", &pif, opts);
|
||||
}
|
||||
|
||||
epicsExportRegistrar(dbndInitialize);
|
||||
@@ -1 +1,2 @@
|
||||
registrar(tsInitialize)
|
||||
registrar(dbndInitialize)
|
||||
|
||||
Reference in New Issue
Block a user