add numericRecord, removeRecordRegister, traceRecordRegister

This commit is contained in:
mrkraimer
2019-06-01 06:59:23 -04:00
parent ecdf70d858
commit 247839b94d
11 changed files with 466 additions and 16 deletions

View File

@ -14,6 +14,7 @@ INC += pv/channelProviderLocal.h
INC += pv/pvDatabase.h
INC += pv/traceRecord.h
INC += pv/removeRecord.h
INC += pv/numericRecord.h
include $(PVDATABASE_SRC)/copy/Makefile
include $(PVDATABASE_SRC)/database/Makefile

View File

@ -10,11 +10,12 @@
*/
#include <epicsGuard.h>
#include <epicsThread.h>
#include <pv/convert.h>
#include <pv/pvStructureCopy.h>
#include <pv/pvData.h>
#define epicsExportSharedSymbols
#include <pv/pvDatabase.h>
#include <pv/pvStructureCopy.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
@ -101,20 +102,6 @@ PVRecord::~PVRecord()
void PVRecord::remove()
{
#ifdef XXX
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(traceLevel>0) {
cout << "PVRecord::remove() " << recordName
<< " isDestroyed " << (isDestroyed ? "true" : "false")
<< endl;
}
if(isDestroyed) {
return;
}
isDestroyed = true;
}
#endif
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
pvTimeStamp.detach();

70
src/pv/numericRecord.h Normal file
View File

@ -0,0 +1,70 @@
/* numericRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2019.06.01
*/
#ifndef NUMERICRECORD_H
#define NUMERICRECORD_H
#include <shareLib.h>
#include <pv/channelProviderLocal.h>
namespace epics { namespace pvDatabase {
class NumericRecord;
typedef std::tr1::shared_ptr<NumericRecord> NumericRecordPtr;
/**
* @brief support for control and valueAlarm for a numeric scalar record
*
* This is support for a record with a top level field that has type scalar.
* It provides support for control and valueAlarm
*/
class epicsShareClass NumericRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(NumericRecord);
/**
* Factory methods to create NumericRecord.
* @param recordName The name for the NumericRecord.
* @param scalarType The scalar type. It must be a numeric type.
* @return A shared pointer to NumericRecord..
*/
static NumericRecordPtr create(
std::string const & recordName,epics::pvData::ScalarType scalarType);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Remove the record specified by recordName.
*/
virtual void process();
~NumericRecord();
private:
NumericRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVScalarPtr pvValue;
epics::pvData::PVStructurePtr pvControl;
epics::pvData::PVStructurePtr pvValueAlarm;
epics::pvData::PVDoublePtr pvLimitLow;
epics::pvData::PVDoublePtr pvLimitHigh;
epics::pvData::PVDoublePtr pvMinStep;
double requestedValue;
double currentValue;
bool isMinStep;
};
}}
#endif /* NUMERICRECORD_H */

View File

@ -4,3 +4,12 @@ SRC_DIRS += $(PVDATABASE_SRC)/special
LIBSRCS += traceRecord.cpp
LIBSRCS += removeRecord.cpp
LIBSRCS += numericRecord.cpp
DBD += traceRecordRegister.dbd
DBD += removeRecordRegister.dbd
DBD += numericRecordRegister.dbd
LIBSRCS += traceRecordRegister.cpp
LIBSRCS += removeRecordRegister.cpp
LIBSRCS += numericRecordRegister.cpp

View File

@ -0,0 +1,143 @@
/* numericRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2019.06.01
*/
#include <pv/pvDatabase.h>
#include <pv/convert.h>
#include <pv/standardField.h>
#define epicsExportSharedSymbols
#include <pv/numericRecord.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
NumericRecord::~NumericRecord()
{
cout << "NumericRecord::~NumericRecord()\n";
}
NumericRecordPtr NumericRecord::create(
std::string const & recordName,epics::pvData::ScalarType scalarType)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StandardFieldPtr standardField = getStandardField();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
add("value",scalarType) ->
add("alarm",standardField->alarm()) ->
add("timeStamp",standardField->timeStamp()) ->
add("display",standardField->display()) ->
add("control",standardField->control()) ->
add("valueAlarm",standardField->doubleAlarm()) ->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
NumericRecordPtr pvRecord(
new NumericRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
NumericRecord::NumericRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool NumericRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pv(pvStructure->getSubField("value"));
if(pv) {
if(pv->getField()->getType()==epics::pvData::scalar) {
ScalarConstPtr s = static_pointer_cast<const Scalar>(pv->getField());
if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
pvValue = static_pointer_cast<PVScalar>(pv);
}
}
}
if(!pvValue) {
cout << "create record " << getRecordName()
<< " failed because not numeric scalar\n";
return false;
}
ConvertPtr convert = getConvert();
requestedValue = convert->toDouble(pvValue);
currentValue = requestedValue;
isMinStep = false;
pvControl = pvStructure->getSubField<PVStructure>("control");
pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
pvMinStep = pvControl->getSubField<PVDouble>("minStep");
pvValueAlarm = pvStructure->getSubField<PVStructure>("valueAlarm");
return true;
}
void NumericRecord::process()
{
ConvertPtr convert = getConvert();
double value = convert->toDouble(pvValue);
cout << "value " << value
<< " requestedValue " << requestedValue
<< " currentValue " << currentValue
<< " isMinStep " << (isMinStep ? "true" : "false")
<< "\n";
if(value==requestedValue&&value==currentValue) {
PVRecord::process();
return;
}
if(!isMinStep) requestedValue = value;
double limitLow = pvLimitLow->get();
double limitHigh = pvLimitHigh->get();
double minStep = pvMinStep->get();
if(limitHigh>limitLow) {
if(value>limitHigh) value = limitHigh;
if(value<limitLow) value = limitLow;
if(!isMinStep) {
if(requestedValue>limitHigh) requestedValue = limitHigh;
if(requestedValue<limitLow) requestedValue = limitLow;
}
}
if(minStep>0.0) {
double diff = requestedValue - currentValue;
if(diff<0.0) {
value = currentValue - minStep;
isMinStep = true;
if(value<requestedValue) {
value = requestedValue;
isMinStep = false;
}
} else {
value = currentValue + minStep;
isMinStep = true;
if(value>requestedValue) {
value = requestedValue;
isMinStep = false;
}
}
cout << "diff " << diff
<< " value " << value
<< " isMinStep " << (isMinStep ? "true" : "false")
<< "\n";
}
currentValue = value;
convert->fromDouble(pvValue,value);
PVRecord::process();
}
}}

View File

@ -0,0 +1,99 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <pv/numericRecord.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg testArg1 = { "scalarType", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0,&testArg1};
static const iocshFuncDef numericRecordFuncDef = {"numericRecordCreate", 2,testArgs};
static void numericRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("numericRecordCreate invalid number of arguments");
}
char *stype = args[1].sval;
epics::pvData::ScalarType scalarType = epics::pvData::pvDouble;
if(stype) {
string val(stype);
if(val.compare("pvByte")==0) {
scalarType = epics::pvData::pvByte;
} else if(val.compare("pvShort")==0) {
scalarType = epics::pvData::pvShort;
} else if(val.compare("pvInt")==0) {
scalarType = epics::pvData::pvInt;
} else if(val.compare("pvLong")==0) {
scalarType = epics::pvData::pvLong;
} else if(val.compare("pvFloat")==0) {
scalarType = epics::pvData::pvFloat;
} else if(val.compare("pvDouble")==0) {
scalarType = epics::pvData::pvDouble;
} else if(val.compare("pvUByte")==0) {
scalarType = epics::pvData::pvUByte;
} else if(val.compare("pvUShort")==0) {
scalarType = epics::pvData::pvUShort;
} else if(val.compare("pvUInt")==0) {
scalarType = epics::pvData::pvUInt;
} else if(val.compare("pvULong")==0) {
scalarType = epics::pvData::pvULong;
} else {
cout << val << " is not a numeric scalar type\n";
return;
}
}
NumericRecordPtr record = NumericRecord::create(recordName,scalarType);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void numericRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&numericRecordFuncDef, numericRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(numericRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("numericRecordRegister")

View File

@ -0,0 +1,69 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <pv/removeRecord.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef removeRecordFuncDef = {"removeRecordCreate", 1,testArgs};
static void removeRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("removeRecordCreate invalid number of arguments");
}
RemoveRecordPtr record = RemoveRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void removeRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&removeRecordFuncDef, removeRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(removeRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("removeRecordRegister")

View File

@ -0,0 +1,69 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAccess.h>
#include <pv/pvDatabase.h>
#include <epicsExport.h>
#include <pv/traceRecord.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef traceRecordFuncDef = {"traceRecordCreate", 1,testArgs};
static void traceRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("traceRecordCreate invalid number of arguments");
}
TraceRecordPtr record = TraceRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void traceRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&traceRecordFuncDef, traceRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(traceRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("traceRecordRegister")