From 0cfe224f47ecc69ee61425cc479402d494c273bc Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 27 Apr 2012 13:22:01 -0400 Subject: [PATCH] Add deadband plugin (client defined monitor deadband) --- src/ioc/db/Makefile | 1 + src/ioc/db/filters/dbnd.c | 141 +++++++++++++++++++++++++++++++++ src/ioc/db/filters/filters.dbd | 1 + 3 files changed, 143 insertions(+) create mode 100644 src/ioc/db/filters/dbnd.c diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile index ad3d2fe91..ed8b36f6e 100644 --- a/src/ioc/db/Makefile +++ b/src/ioc/db/Makefile @@ -85,4 +85,5 @@ dbCore_SRCS += dbIocRegister.c dbCore_SRCS += chfPlugin.c LIB_SRCS += ts.c +LIB_SRCS += dbnd.c diff --git a/src/ioc/db/filters/dbnd.c b/src/ioc/db/filters/dbnd.c new file mode 100644 index 000000000..e9d517ba1 --- /dev/null +++ b/src/ioc/db/filters/dbnd.c @@ -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 + */ +#include + +#include +#include +#include +#include +#include +#include + +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); diff --git a/src/ioc/db/filters/filters.dbd b/src/ioc/db/filters/filters.dbd index bc84b4568..c859f0f40 100644 --- a/src/ioc/db/filters/filters.dbd +++ b/src/ioc/db/filters/filters.dbd @@ -1 +1,2 @@ registrar(tsInitialize) +registrar(dbndInitialize)