PowerSupplyRecordPtr PowerSupplyRecord::create(
    string const & recordName)
{
    FieldCreatePtr fieldCreate = getFieldCreate();
    StandardFieldPtr standardField = getStandardField();
    PVDataCreatePtr pvDataCreate = getPVDataCreate();

    StructureConstPtr  topStructure = fieldCreate->createFieldBuilder()->
            add("alarm",standardField->alarm()) ->
            add("timeStamp",standardField->timeStamp()) ->
            addNestedStructure("power") ->
               add("value",pvDouble) ->
               endNested()->
            addNestedStructure("voltage") ->
               add("value",pvDouble) ->
               endNested()->
            addNestedStructure("current") ->
               add("value",pvDouble) ->
               endNested()->
            createStructure();
    PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
    PowerSupplyRecordPtr pvRecord(
        new PowerSupplyRecord(recordName,pvStructure));
    if(!pvRecord->init()) pvRecord.reset();
    return pvRecord;
}
Beispiel #2
0
void DbPv::init()
{
    // this requires valid existance of dbPv::shared_pointer instance
    StandardFieldPtr standardField = getStandardField();
    ScalarType scalarType = pvBoolean;
    switch(dbChannelFinalFieldType(dbChan)) {
        case DBF_CHAR:
            scalarType = pvByte; break;
        case DBF_UCHAR:
            scalarType = pvUByte; break;
        case DBF_SHORT:
            scalarType = pvShort; break;
        case DBF_USHORT:
            scalarType = pvUShort; break;
        case DBF_LONG:
            scalarType = pvInt; break;
        case DBF_ULONG:
            scalarType = pvUInt; break;
        case DBF_FLOAT:
            scalarType = pvFloat; break;
        case DBF_DOUBLE:
            scalarType = pvDouble; break;
        case DBF_STRING:
            scalarType = pvString; break;

        case DBF_ENUM:
        case DBF_MENU:
        case DBF_DEVICE:
            recordField = standardField->enumerated("value,timeStamp,alarm");
            return;
        case DBF_INLINK:
        case DBF_OUTLINK:
        case DBF_FWDLINK:
            scalarType = pvString; break;
        default:
          break;
    }
    bool isArray = (dbChannelFinalElements(dbChan) > 1) ? true : false;
    if(scalarType==pvString) {  
        if(isArray) {
            recordField = standardField->scalarArray(scalarType,
                "value,timeStamp,alarm");
        } else {
            recordField = standardField->scalar(scalarType,
                "value,timeStamp,alarm");
        }
    }
    else if(scalarType!=pvBoolean) {
        if(isArray) {
            recordField = standardField->scalarArray(scalarType,
                "value,timeStamp,alarm,display");
        } else {
            recordField = standardField->scalar(scalarType,
                "value,timeStamp,alarm,display,control,valueAlarm");
        }
    }
}
ExampleHelloPtr ExampleHello::create(
    string const & recordName)
{
    StandardFieldPtr standardField = getStandardField();
    FieldCreatePtr fieldCreate = getFieldCreate();
    PVDataCreatePtr pvDataCreate = getPVDataCreate();
    StructureConstPtr  topStructure = fieldCreate->createFieldBuilder()->
        addNestedStructure("argument")->
            add("value",pvString)->
            endNested()->
        addNestedStructure("result") ->
            add("value",pvString) ->
            add("timeStamp",standardField->timeStamp()) ->
            endNested()->
        createStructure();
    PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);

    ExampleHelloPtr pvRecord(
        new ExampleHello(recordName,pvStructure));
    if(!pvRecord->init()) pvRecord.reset();
    return pvRecord;
}
PVStructurePtr createPowerSupply()
{
    FieldCreatePtr fieldCreate = getFieldCreate();
    StandardFieldPtr standardField = getStandardField();
    PVDataCreatePtr pvDataCreate = getPVDataCreate();

    return pvDataCreate->createPVStructure(
        fieldCreate->createFieldBuilder()->
            add("alarm",standardField->alarm()) ->
            add("timeStamp",standardField->timeStamp()) ->
            addNestedStructure("power") ->
               add("value",pvDouble) ->
               add("alarm",standardField->alarm()) ->
               endNested()->
            addNestedStructure("voltage") ->
               add("value",pvDouble) ->
               add("alarm",standardField->alarm()) ->
               endNested()->
            addNestedStructure("current") ->
               add("value",pvDouble) ->
               add("alarm",standardField->alarm()) ->
               endNested()->
            createStructure());
}
StructureConstPtr NTMultiChannelBuilder::createStructure()
{
    StandardFieldPtr standardField = getStandardField();
    size_t nfields = 3;
    size_t extraCount = extraFieldNames.size();
    nfields += extraCount;
    if(descriptor) ++nfields;
    if(alarm) ++nfields;
    if(timeStamp) ++nfields;
    if(severity) ++nfields;
    if(status) ++nfields;
    if(message) ++nfields;
    if(secondsPastEpoch) ++nfields;
    if(nanoseconds) ++nfields;
    if(userTag) ++nfields;
    FieldConstPtrArray fields(nfields);
    StringArray names(nfields);
    size_t ind = 0;
    names[ind] = "value";
    if(valueType) {
        fields[ind++] =  fieldCreate->createUnionArray(valueType);
    } else {
        fields[ind++] =  fieldCreate->createVariantUnionArray();
    }
    names[ind] = "channelName";
    fields[ind++] =  fieldCreate->createScalarArray(pvString);
    names[ind] = "isConnected";
    fields[ind++] =  fieldCreate->createScalarArray(pvBoolean);
    if(timeStamp) {
        names[ind] = "timeStamp";
        fields[ind++] = standardField->timeStamp();
    }
    if(alarm) {
        names[ind] = "alarm";
        fields[ind++] = standardField->alarm();
    }
    if(descriptor) {
        names[ind] = "descriptor";
        fields[ind++] = fieldCreate->createScalar(pvString);
    }
    if(severity) {
        names[ind] = "severity";
        fields[ind++] = fieldCreate->createScalarArray(pvInt);
    }
    if(status) {
        names[ind] = "status";
        fields[ind++] = fieldCreate->createScalarArray(pvInt);
    }
    if(message) {
        names[ind] = "message";
        fields[ind++] = fieldCreate->createScalarArray(pvString);
    }
    if(secondsPastEpoch) {
        names[ind] = "secondsPastEpoch";
        fields[ind++] = fieldCreate->createScalarArray(pvLong);
    }
    if(nanoseconds) {
        names[ind] = "nanoseconds";
        fields[ind++] = fieldCreate->createScalarArray(pvInt);
    }
    if(userTag) {
        names[ind] = "userTag";
        fields[ind++] = fieldCreate->createScalarArray(pvInt);
    }
    for (size_t i = 0; i< extraCount; i++) {
        names[ind] = extraFieldNames[i];
        fields[ind++] = extraFields[i];
    }

    StructureConstPtr st = fieldCreate->createStructure(NTMultiChannel::URI,names,fields);
    reset();
    return st;
}
Beispiel #6
0
StandardPVField::StandardPVField()
: standardField(getStandardField()),
  fieldCreate(getFieldCreate()),
  pvDataCreate(getPVDataCreate()),
  notImplemented("not implemented")
{}
namespace epics { namespace pvaClient { 

static ConvertPtr convert = getConvert();
static FieldCreatePtr fieldCreate = getFieldCreate();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static StandardFieldPtr standardField = getStandardField();


PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create(
    PvaClientMultiChannelPtr const &pvaMultiChannel,
    PvaClientChannelArray const &pvaClientChannelArray)
{
    PvaClientMultiMonitorDoublePtr pvaClientMultiMonitorDouble(
         new PvaClientMultiMonitorDouble(pvaMultiChannel,pvaClientChannelArray));
    return pvaClientMultiMonitorDouble;
}

PvaClientMultiMonitorDouble::PvaClientMultiMonitorDouble(
     PvaClientMultiChannelPtr const &pvaClientMultiChannel,
     PvaClientChannelArray const &pvaClientChannelArray)
: pvaClientMultiChannel(pvaClientMultiChannel),
  pvaClientChannelArray(pvaClientChannelArray),
  nchannel(pvaClientChannelArray.size()),
  doubleValue(shared_vector<double>(nchannel,epicsNAN)),
  pvaClientMonitor(std::vector<PvaClientMonitorPtr>(nchannel,PvaClientMonitorPtr())),
  isMonitorConnected(false),
  isDestroyed(false)
{
}

PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble()
{
    destroy();
}

void PvaClientMultiMonitorDouble::destroy()
{
    {
        Lock xx(mutex);
        if(isDestroyed) return;
        isDestroyed = true;
    }
    pvaClientChannelArray.clear();
}

void PvaClientMultiMonitorDouble::connect()
{
    shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
    string request = "value";
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
               pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request);
               pvaClientMonitor[i]->issueConnect();
         }
    }
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
               Status status = pvaClientMonitor[i]->waitConnect();
               if(status.isOK()) continue;
               string message = string("channel ") + pvaClientChannelArray[i]->getChannelName()
                   + " PvaChannelMonitor::waitConnect " + status.getMessage();
               throw std::runtime_error(message);
         }
    }
     for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) pvaClientMonitor[i]->start();
    }
    isMonitorConnected = true;
}

bool PvaClientMultiMonitorDouble::poll()
{
    if(!isMonitorConnected){
         connect();
         epicsThreadSleep(.01);
    }
    bool result = false;
    shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
              if(pvaClientMonitor[i]->poll()) {
                   doubleValue[i] = pvaClientMonitor[i]->getData()->getDouble();
                   pvaClientMonitor[i]->releaseEvent();
                   result = true;
              }
         }
    }
    return result;
}

bool PvaClientMultiMonitorDouble::waitEvent(double waitForEvent)
{
    if(poll()) return true;
    TimeStamp start;
    start.getCurrent();
    TimeStamp now;
    while(true) {
          epicsThreadSleep(.1);
          if(poll()) return true;
          now.getCurrent();
          double diff = TimeStamp::diff(now,start);
          if(diff>=waitForEvent) break;
    }
    return false;
}

epics::pvData::shared_vector<double> PvaClientMultiMonitorDouble::get()
{
    return doubleValue;
}


}}
StructureConstPtr NTNDArrayBuilder::createStructure()
{
    enum
    {
        DISCRIPTOR_INDEX,
        TIMESTAMP_INDEX,
        ALARM_INDEX,
        DISPLAY_INDEX
    };

    const size_t NUMBER_OF_INDICES = DISPLAY_INDEX+1;
    const size_t NUMBER_OF_STRUCTURES = 1 << NUMBER_OF_INDICES;

    Lock xx(mutex);

    static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES];
    static UnionConstPtr valueType;
    static StructureConstPtr codecStruc;
    static StructureConstPtr dimensionStruc;
    static StructureConstPtr attributeStruc;

    StructureConstPtr returnedStruc;

    size_t index = 0;
    if (descriptor) index  |= 1 << DISCRIPTOR_INDEX;
    if (timeStamp)  index  |= 1 << TIMESTAMP_INDEX;
    if (alarm)      index  |= 1 << ALARM_INDEX;
    if (display)    index  |= 1 << DISPLAY_INDEX;

    bool isExtended = !extraFieldNames.empty();

    if (isExtended || !ntndarrayStruc[index])
    {
        StandardFieldPtr standardField = getStandardField();
        FieldBuilderPtr fb = fieldCreate->createFieldBuilder();

        if (!valueType)
        {
            for (int i = pvBoolean; i < pvString; ++i)
            {
                ScalarType st = static_cast<ScalarType>(i);
                fb->addArray(std::string(ScalarTypeFunc::name(st)) + "Value", st);
            }
            valueType = fb->createUnion();                
        }

        if (!codecStruc)
        {
            codecStruc = fb->setId("codec_t")->
                add("name", pvString)->
                add("parameters", fieldCreate->createVariantUnion())->
                createStructure();
        }

        if (!dimensionStruc)
        {
            dimensionStruc = fb->setId("dimension_t")->
                add("size", pvInt)->
                add("offset",  pvInt)->
                add("fullSize",  pvInt)->
                add("binning",  pvInt)->
                add("reverse",  pvBoolean)->
                createStructure();
        }

        if (!attributeStruc)
        {
            attributeStruc = NTNDArrayAttribute::createBuilder()->createStructure();
        }

        fb->setId(NTNDArray::URI)->
            add("value", valueType)->
            add("codec", codecStruc)->
            add("compressedSize", pvLong)->
            add("uncompressedSize", pvLong)->
            addArray("dimension", dimensionStruc)->
            add("uniqueId", pvInt)->
            add("dataTimeStamp", standardField->timeStamp())->
            addArray("attribute", attributeStruc);

        if (descriptor)
            fb->add("descriptor", pvString);

        if (alarm)
            fb->add("alarm", standardField->alarm());

        if (timeStamp)
            fb->add("timeStamp", standardField->timeStamp());

        if (display)
            fb->add("display", standardField->display());

        size_t extraCount = extraFieldNames.size();
        for (size_t i = 0; i< extraCount; i++)
            fb->add(extraFieldNames[i], extraFields[i]);

        returnedStruc = fb->createStructure();

        if (!isExtended)
            ntndarrayStruc[index] = returnedStruc; 
    }
    else
    {
        return ntndarrayStruc[index];
    }

    return returnedStruc;
}
namespace epics { namespace pvaClient { 

static ConvertPtr convert = getConvert();
static FieldCreatePtr fieldCreate = getFieldCreate();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
static StandardFieldPtr standardField = getStandardField();
static CreateRequest::shared_pointer  createRequest = CreateRequest::create();


PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create(
    PvaClientMultiChannelPtr const &pvaMultiChannel,
    PvaClientChannelArray const &pvaClientChannelArray)
{
    PvaClientMultiPutDoublePtr pvaClientMultiPutDouble(
         new PvaClientMultiPutDouble(pvaMultiChannel,pvaClientChannelArray));
    return pvaClientMultiPutDouble;
}

PvaClientMultiPutDouble::PvaClientMultiPutDouble(
     PvaClientMultiChannelPtr const &pvaClientMultiChannel,
     PvaClientChannelArray const &pvaClientChannelArray)
: pvaClientMultiChannel(pvaClientMultiChannel),
  pvaClientChannelArray(pvaClientChannelArray),
  nchannel(pvaClientChannelArray.size()),
  pvaClientPut(std::vector<PvaClientPutPtr>(nchannel,PvaClientPutPtr())),
  isPutConnected(false),
  isDestroyed(false)
{
}



PvaClientMultiPutDouble::~PvaClientMultiPutDouble()
{
    destroy();
}

void PvaClientMultiPutDouble::destroy()
{
    {
        Lock xx(mutex);
        if(isDestroyed) return;
        isDestroyed = true;
    }
    pvaClientChannelArray.clear();
}

void PvaClientMultiPutDouble::connect()
{
    shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
               pvaClientPut[i] = pvaClientChannelArray[i]->createPut();
               pvaClientPut[i]->issueConnect();
         }
    }
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
               Status status = pvaClientPut[i]->waitConnect();
               if(status.isOK()) continue;
               string message = string("channel ") + pvaClientChannelArray[i]->getChannelName()
                   + " PvaChannelPut::waitConnect " + status.getMessage();
               throw std::runtime_error(message);
         }
    }
    isPutConnected = true;
}

void PvaClientMultiPutDouble::put(epics::pvData::shared_vector<double> const &data)
{
    if(!isPutConnected) connect();
    if(data.size()!=nchannel) {
         throw std::runtime_error("data has wrong size");
    }
    shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
    for(size_t i=0; i<nchannel; ++i)
    {
         if(isConnected[i]) {
               PVStructurePtr pvTop = pvaClientPut[i]->getData()->getPVStructure();
               PVScalarPtr pvValue = pvTop->getSubField<PVScalar>("value");
               convert->fromDouble(pvValue,data[i]);
               pvaClientPut[i]->issuePut();
         }
         if(isConnected[i]) {
              Status status = pvaClientPut[i]->waitPut();
              if(status.isOK())  continue;
              string message = string("channel ") + pvaClientChannelArray[i]->getChannelName()
                   + " PvaChannelPut::waitPut " + status.getMessage();
              throw std::runtime_error(message);
         }
    }
}

}}