void NTNDArrayConverter::fromAttributes (NDArray *src) { PVStructureArrayPtr dest(m_array->getAttribute()); NDAttributeList *srcList = src->pAttributeList; NDAttribute *attr = NULL; StructureConstPtr structure(dest->getStructureArray()->getStructure()); PVStructureArray::svector destVec(dest->reuse()); destVec.resize(srcList->count()); size_t i = 0; while((attr = srcList->next(attr))) { if(!destVec[i].get() || !destVec[i].unique()) destVec[i] = PVDC->createPVStructure(structure); PVStructurePtr pvAttr(destVec[i]); pvAttr->getSubField<PVString>("name")->put(attr->getName()); pvAttr->getSubField<PVString>("descriptor")->put(attr->getDescription()); pvAttr->getSubField<PVString>("source")->put(attr->getSource()); NDAttrSource_t sourceType; attr->getSourceInfo(&sourceType); pvAttr->getSubField<PVInt>("sourceType")->put(sourceType); switch(attr->getDataType()) { case NDAttrInt8: fromAttribute <PVByte, int8_t> (pvAttr, attr); break; case NDAttrUInt8: fromAttribute <PVUByte, uint8_t> (pvAttr, attr); break; case NDAttrInt16: fromAttribute <PVShort, int16_t> (pvAttr, attr); break; case NDAttrUInt16: fromAttribute <PVUShort, uint16_t>(pvAttr, attr); break; case NDAttrInt32: fromAttribute <PVInt, int32_t> (pvAttr, attr); break; case NDAttrUInt32: fromAttribute <PVUInt, uint32_t>(pvAttr, attr); break; case NDAttrFloat32: fromAttribute <PVFloat, float> (pvAttr, attr); break; case NDAttrFloat64: fromAttribute <PVDouble, double> (pvAttr, attr); break; case NDAttrString: fromStringAttribute(pvAttr, attr); break; case NDAttrUndefined: fromUndefinedAttribute(pvAttr); break; default: throw std::runtime_error("invalid attribute data type"); } ++i; } dest->replace(freeze(destVec)); }
/** * \param[in] pArray The NDArray from the callback. */ void NDPluginAttribute::processCallbacks(NDArray *pArray) { /* * This function is called with the mutex already locked. It unlocks it during long calculations when private * structures don't need to be protected. */ int status = 0; int currentTSPoint; int numTSPoints; int TSAcquiring; double valueSum; int i; char attrName[MAX_ATTR_NAME_] = {0}; NDAttribute *pAttribute = NULL; NDAttributeList *pAttrList = NULL; epicsFloat64 attrValue = 0.0; static const char *functionName = "NDPluginAttribute::processCallbacks"; /* Call the base class method */ NDPluginDriver::beginProcessCallbacks(pArray); /* Get the attributes for this driver */ pAttrList = pArray->pAttributeList; getIntegerParam(NDPluginAttributeTSCurrentPoint, ¤tTSPoint); getIntegerParam(NDPluginAttributeTSNumPoints, &numTSPoints); getIntegerParam(NDPluginAttributeTSAcquiring, &TSAcquiring); for (i=0; i<maxAttributes_; i++) { getStringParam(i, NDPluginAttributeAttrName, MAX_ATTR_NAME_, attrName); asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Finding the attribute %s\n", attrName); if (strcmp(attrName, UNIQUE_ID_NAME_) == 0) { attrValue = (epicsFloat64) pArray->uniqueId; } else if (strcmp(attrName, TIMESTAMP_NAME_) == 0) { attrValue = pArray->timeStamp; } else if (strcmp(attrName, EPICS_TS_SEC_NAME_) == 0) { attrValue = (epicsFloat64)pArray->epicsTS.secPastEpoch; } else if (strcmp(attrName, EPICS_TS_NSEC_NAME_) == 0) { attrValue = (epicsFloat64)pArray->epicsTS.nsec; } else { pAttribute = pAttrList->find(attrName); if (pAttribute) { status = pAttribute->getValue(NDAttrFloat64, &attrValue); if (status != asynSuccess) { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s: Error reading value for NDAttribute %s. \n", functionName, attrName); continue; } asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Attribute %s value is %f\n", attrName, attrValue); } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s: Error finding NDAttribute %s. \n", functionName, attrName); continue; } } setDoubleParam(i, NDPluginAttributeVal, attrValue); getDoubleParam(i, NDPluginAttributeValSum, &valueSum); valueSum += attrValue; setDoubleParam(i, NDPluginAttributeValSum, valueSum); if (TSAcquiring) { pTSArray_[i][currentTSPoint] = attrValue; } callParamCallbacks(i); } if (TSAcquiring) { currentTSPoint++; setIntegerParam(NDPluginAttributeTSCurrentPoint, currentTSPoint); if (currentTSPoint >= numTSPoints) { doTimeSeriesCallbacks(); setIntegerParam(NDPluginAttributeTSAcquiring, 0); } } }
/** * \param[in] pArray The NDArray from the callback. */ void NDPluginAttribute::processCallbacks(NDArray *pArray) { /* * This function is called with the mutex already locked. It unlocks it during long calculations when private * structures don't need to be protected. */ int status = 0; int dataType; char attrName[MAX_ATTR_NAME_] = {0}; NDAttribute *pAttribute = NULL; NDAttributeList *pAttrList = NULL; epicsFloat64 attrValue = 0.0; epicsFloat64 updatePeriod = 0.0; static const char *functionName = "NDPluginAttribute::processCallbacks"; asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Starting %s. currentPoint_: %d\n", functionName, currentPoint_); /* Get the time and decide if we update the array.*/ getDoubleParam(NDPluginAttributeUpdatePeriod, &updatePeriod); epicsTimeGetCurrent(&nowTime_); nowTimeSecs_ = nowTime_.secPastEpoch + (nowTime_.nsec / 1.e9); if ((nowTimeSecs_ - lastTimeSecs_) < (updatePeriod / 1000.0)) { arrayUpdate_ = 0; } else { arrayUpdate_ = 1; lastTimeSecs_ = nowTimeSecs_; } /* Get all parameters while we have the mutex */ getIntegerParam(NDPluginAttributeDataType, &dataType); /* Call the base class method */ NDPluginDriver::processCallbacks(pArray); /* Get the attributes for this driver */ pAttrList = pArray->pAttributeList; getStringParam(NDPluginAttributeAttrName, MAX_ATTR_NAME_, attrName); asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Finding the attribute %s\n", attrName); pAttribute = pAttrList->find(attrName); if (pAttribute) { status = pAttribute->getValue(NDAttrFloat64, &attrValue); asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "Attribute %s is %f\n", attrName, attrValue); if (status == asynSuccess) { setDoubleParam(NDPluginAttributeVal, attrValue); valueSum_ = valueSum_ + attrValue; setDoubleParam(NDPluginAttributeValSum, valueSum_); if (currentPoint_ < maxTimeSeries_) { pTimeSeries_[currentPoint_] = attrValue; ++currentPoint_; } } callParamCallbacks(); if (arrayUpdate_) { doCallbacksFloat64Array(this->pTimeSeries_, currentPoint_, NDPluginAttributeArray, 0); } } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s: Error reading NDAttribute %s. \n", functionName, attrName); } }