add support
This commit is contained in:
@ -15,11 +15,13 @@ INC += pv/pvDatabase.h
|
||||
INC += pv/traceRecord.h
|
||||
INC += pv/removeRecord.h
|
||||
INC += pv/numericRecord.h
|
||||
|
||||
INC += pv/pvSupport.h
|
||||
INC += pv/controlSupport.h
|
||||
include $(PVDATABASE_SRC)/copy/Makefile
|
||||
include $(PVDATABASE_SRC)/database/Makefile
|
||||
include $(PVDATABASE_SRC)/pvAccess/Makefile
|
||||
include $(PVDATABASE_SRC)/special/Makefile
|
||||
include $(PVDATABASE_SRC)/support/Makefile
|
||||
|
||||
pvDatabase_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
|
||||
pvDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||
|
82
src/pv/controlSupport.h
Normal file
82
src/pv/controlSupport.h
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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 CONTROLSUPPORT_H
|
||||
#define CONTROLSUPPORT_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define pvdatabaseEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/pvSupport.h>
|
||||
|
||||
#ifdef pvdatabaseEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef pvdatabaseEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <shareLib.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class ControlSupport;
|
||||
typedef std::tr1::shared_ptr<ControlSupport> ControlSupportPtr;
|
||||
|
||||
/**
|
||||
* @brief Base interface for a ControlSupport.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass ControlSupport :
|
||||
PVSupport
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ControlSupport);
|
||||
/**
|
||||
* The Destructor.
|
||||
*/
|
||||
virtual ~ControlSupport();
|
||||
/**
|
||||
* @brief Optional initialization method.
|
||||
*
|
||||
* A derived method <b>Must</b> call initControlSupport.
|
||||
* @return <b>true</b> for success and <b>false</b> for failure.
|
||||
*/
|
||||
virtual bool init();
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
*
|
||||
*/
|
||||
virtual void process();
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
*/
|
||||
virtual void reset();
|
||||
static ControlSupportPtr create(PVRecordPtr const & pvRecord);
|
||||
private:
|
||||
ControlSupport(PVRecordPtr const & pvRecord);
|
||||
PVRecordPtr pvRecord;
|
||||
epics::pvData::PVScalarPtr pvValue;
|
||||
epics::pvData::PVStructurePtr pvControl;
|
||||
epics::pvData::PVDoublePtr pvLimitLow;
|
||||
epics::pvData::PVDoublePtr pvLimitHigh;
|
||||
epics::pvData::PVDoublePtr pvMinStep;
|
||||
double requestedValue;
|
||||
double currentValue;
|
||||
bool isMinStep;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* CONTROLSUPPORT_H */
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <shareLib.h>
|
||||
|
||||
#include <pv/channelProviderLocal.h>
|
||||
#include <pv/controlSupport.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
@ -54,15 +55,8 @@ 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;
|
||||
ControlSupportPtr controlSupport;
|
||||
epics::pvData::PVBooleanPtr pvReset;
|
||||
};
|
||||
|
||||
}}
|
||||
|
84
src/pv/pvSupport.h
Normal file
84
src/pv/pvSupport.h
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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 PVSUPPORT_H
|
||||
#define PVSUPPORT_H
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define pvdatabaseEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/rpcService.h>
|
||||
|
||||
|
||||
#ifdef pvdatabaseEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef pvdatabaseEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <shareLib.h>
|
||||
#include <pv/pvStructureCopy.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class PVSupport;
|
||||
typedef std::tr1::shared_ptr<PVSupport> PVSupportPtr;
|
||||
|
||||
/**
|
||||
* @brief Base interface for a PVSupport.
|
||||
*
|
||||
*/
|
||||
class epicsShareClass PVSupport
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVSupport);
|
||||
/**
|
||||
* The Destructor.
|
||||
*/
|
||||
virtual ~PVSupport(){}
|
||||
/**
|
||||
* @brief Optional initialization method.
|
||||
*
|
||||
* A derived method <b>Must</b> call initPVSupport.
|
||||
* @return <b>true</b> for success and <b>false</b> for failure.
|
||||
*/
|
||||
virtual bool init() {return true;}
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
* It is called before record is added to database.
|
||||
*/
|
||||
virtual void start() {}
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
* It is the method that makes a record smart.
|
||||
* If it encounters errors it should raise alarms and/or
|
||||
* call the <b>message</b> method provided by the base class.
|
||||
* If the pvStructure has a top level timeStamp,
|
||||
* the base class sets the timeStamp to the current time.
|
||||
*/
|
||||
virtual void process() = 0;
|
||||
/**
|
||||
* @brief Optional method for derived class.
|
||||
*
|
||||
*/
|
||||
virtual void reset() {};
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* PVSUPPORT_H */
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/controlSupport.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
@ -36,6 +37,7 @@ NumericRecordPtr NumericRecord::create(
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
|
||||
add("value",scalarType) ->
|
||||
add("reset",pvBoolean) ->
|
||||
add("alarm",standardField->alarm()) ->
|
||||
add("timeStamp",standardField->timeStamp()) ->
|
||||
add("display",standardField->display()) ->
|
||||
@ -59,82 +61,22 @@ NumericRecord::NumericRecord(
|
||||
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");
|
||||
PVRecordPtr pvRecord = shared_from_this();
|
||||
controlSupport = ControlSupport::create(pvRecord);
|
||||
bool result = controlSupport->init();
|
||||
if(!result) return false;
|
||||
pvReset = getPVStructure()->getSubField<PVBoolean>("reset");
|
||||
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(pvReset->get()==true) {
|
||||
pvReset->put(false);
|
||||
controlSupport->reset();
|
||||
} else {
|
||||
controlSupport->process();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
5
src/support/Makefile
Normal file
5
src/support/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATABASE_SRC)/support
|
||||
|
||||
LIBSRCS += controlSupport.cpp
|
125
src/support/controlSupport.cpp
Normal file
125
src/support/controlSupport.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/* controlSupport.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/pvSupport.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <pv/controlSupport.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
ControlSupport::~ControlSupport()
|
||||
{
|
||||
cout << "ControlSupport::~ControlSupport()\n";
|
||||
}
|
||||
|
||||
ControlSupportPtr ControlSupport::create(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
ControlSupportPtr support(new ControlSupport(pvRecord));
|
||||
return support;
|
||||
}
|
||||
|
||||
ControlSupport::ControlSupport(PVRecordPtr const & pvRecord)
|
||||
: pvRecord(pvRecord)
|
||||
{}
|
||||
|
||||
bool ControlSupport::init()
|
||||
{
|
||||
PVStructurePtr pvStructure = pvRecord->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 << "ControlSupport for record " << pvRecord->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");
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControlSupport::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) 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);
|
||||
}
|
||||
|
||||
void ControlSupport::reset()
|
||||
{
|
||||
isMinStep = false;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
Reference in New Issue
Block a user