From 5dd76f2ca7c65564f84fc207f0c4a5205eda1d51 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Thu, 30 May 2013 21:05:33 +0200 Subject: [PATCH] ca: get support for all double DBR types --- pvAccessApp/ca/caChannel.cpp | 147 +++++++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 13 deletions(-) diff --git a/pvAccessApp/ca/caChannel.cpp b/pvAccessApp/ca/caChannel.cpp index 9644b55..2c66cae 100644 --- a/pvAccessApp/ca/caChannel.cpp +++ b/pvAccessApp/ca/caChannel.cpp @@ -84,9 +84,9 @@ static PVStructure::shared_pointer createPVStructure(CAChannel::shared_pointer c // TODO value is always there String properties; if (dbrType >= DBR_CTRL_STRING) // 28 - properties = "value,alarm,display,control"; + properties = "value,alarm,display,valueAlarm,control"; else if (dbrType >= DBR_GR_STRING) // 21 - properties = "value,alarm,display"; + properties = "value,alarm,display,valueAlarm"; else if (dbrType >= DBR_TIME_STRING) // 14 properties = "value,timeStamp"; else if (dbrType >= DBR_STS_STRING) // 7 @@ -105,10 +105,11 @@ void CAChannel::connected() elementCount = ca_element_count(channelID); channelType = ca_field_type(channelID); - String allProperties("value,timeStamp,alarm,display,control"); + String allProperties("value,timeStamp,alarm,display,valueAlarm,control"); PVStructure::shared_pointer pvStructure = createPVStructure(shared_from_this(), allProperties); // TODO thread sync + // TODO we need only Structure here this->pvStructure = pvStructure; // TODO call channelCreated if structure has changed @@ -423,8 +424,8 @@ static chtype getDBRType(PVStructure::shared_pointer const & pvRequest, chtype n fieldStructure->getField("control")) return static_cast(static_cast(nativeType) + DBR_CTRL_STRING); - // display -> DBR_GR_ - if (fieldStructure->getField("display")) + // display/valueAlarm -> DBR_GR_ + if (fieldStructure->getField("display") || fieldStructure->getField("valueAlarm")) return static_cast(static_cast(nativeType) + DBR_GR_STRING); // alarm -> DBR_STS_ @@ -487,6 +488,127 @@ void copy_DBR_DOUBLE(const void * dbr, unsigned count, PVStructure::shared_point } } +static String dbrStatus2alarmMessage[] = { + "NO_ALARM", // 0 .. + "READ_ALARM", + "WRITE_ALARM", + "HIHI_ALARM", + "HIGH_ALARM", + "LOLO_ALARM", + "LOW_ALARM", + "STATE_ALARM", + "COS_ALARM", + "COMM_ALARM", + "TIMEOUT_ALARM", + "HW_LIMIT_ALARM", + "CALC_ALARM", + "SCAN_ALARM", + "LINK_ALARM", + "SOFT_ALARM", + "BAD_SUB_ALARM", + "UDF_ALARM", + "DISABLE_ALARM", + "SIMM_ALARM", + "READ_ACCESS_ALARM", + "WRITE_ACCESS_ALARM" // .. 21 +}; + +void copy_DBR_STS_DOUBLE(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) +{ + const dbr_sts_double* data = static_cast(dbr); + + PVStructure::shared_pointer alarm = pvStructure->getStructureField("alarm"); + // TODO any mapping + alarm->getIntField("status")->put(0); + alarm->getIntField("severity")->put(data->severity); + alarm->getStringField("message")->put(dbrStatus2alarmMessage[data->status]); + + copy_DBR_DOUBLE(&data->value, count, pvStructure); +} + +void copy_DBR_TIME_DOUBLE(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) +{ + const dbr_time_double* data = static_cast(dbr); + + PVStructure::shared_pointer ts = pvStructure->getStructureField("timeStamp"); + epics::pvData::int64 spe = data->stamp.secPastEpoch; + spe += 7305*86400; + ts->getLongField("secondsPastEpoch")->put(spe); + ts->getIntField("nanoSeconds")->put(data->stamp.nsec); + + copy_DBR_DOUBLE(&data->value, count, pvStructure); +} + +void copy_DBR_GR_DOUBLE(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) +{ + const dbr_gr_double* data = static_cast(dbr); + + PVStructure::shared_pointer alarm = pvStructure->getStructureField("alarm"); + alarm->getIntField("status")->put(0); + alarm->getIntField("severity")->put(data->severity); + alarm->getStringField("message")->put(dbrStatus2alarmMessage[data->status]); + + PVStructure::shared_pointer disp = pvStructure->getStructureField("display"); + disp->getStringField("units")->put(String(data->units)); + disp->getDoubleField("limitHigh")->put(data->upper_disp_limit); + disp->getDoubleField("limitLow")->put(data->lower_disp_limit); + if (data->precision) + { + char fmt[16]; + sprintf(fmt, "%%.%df", data->precision); + disp->getStringField("format")->put(String(fmt)); + } + else + { + disp->getStringField("format")->put("%f"); + } + + PVStructure::shared_pointer va = pvStructure->getStructureField("valueAlarm"); + va->getDoubleField("highAlarmLimit")->put(data->upper_alarm_limit); + va->getDoubleField("highWarningLimit")->put(data->upper_warning_limit); + va->getDoubleField("lowWarningLimit")->put(data->lower_warning_limit); + va->getDoubleField("lowAlarmLimit")->put(data->lower_alarm_limit); + + copy_DBR_DOUBLE(&data->value, count, pvStructure); +} + +void copy_DBR_CTRL_DOUBLE(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) +{ + const dbr_ctrl_double* data = static_cast(dbr); + + PVStructure::shared_pointer alarm = pvStructure->getStructureField("alarm"); + alarm->getIntField("status")->put(0); + alarm->getIntField("severity")->put(data->severity); + alarm->getStringField("message")->put(dbrStatus2alarmMessage[data->status]); + + PVStructure::shared_pointer disp = pvStructure->getStructureField("display"); + disp->getStringField("units")->put(String(data->units)); + disp->getDoubleField("limitHigh")->put(data->upper_disp_limit); + disp->getDoubleField("limitLow")->put(data->lower_disp_limit); + if (data->precision) + { + char fmt[16]; + sprintf(fmt, "%%.%df", data->precision); + disp->getStringField("format")->put(String(fmt)); + } + else + { + disp->getStringField("format")->put("%f"); + } + + PVStructure::shared_pointer va = pvStructure->getStructureField("valueAlarm"); + va->getDoubleField("highAlarmLimit")->put(data->upper_alarm_limit); + va->getDoubleField("highWarningLimit")->put(data->upper_warning_limit); + va->getDoubleField("lowWarningLimit")->put(data->lower_warning_limit); + va->getDoubleField("lowAlarmLimit")->put(data->lower_alarm_limit); + + PVStructure::shared_pointer ctrl = pvStructure->getStructureField("control"); + ctrl->getDoubleField("limitHigh")->put(data->upper_ctrl_limit); + ctrl->getDoubleField("limitLow")->put(data->lower_ctrl_limit); + + copy_DBR_DOUBLE(&data->value, count, pvStructure); +} + static copyDBRtoPVStructure copyFuncTable[] = { 0, // DBR_STRING @@ -503,7 +625,7 @@ static copyDBRtoPVStructure copyFuncTable[] = 0, // DBR_STS_ENUM 0, // DBR_STS_CHAR 0, // DBR_STS_LONG - 0, // DBR_STS_DOUBLE + copy_DBR_STS_DOUBLE, // DBR_STS_DOUBLE 0, // DBR_TIME_STRING 0, // DBR_TIME_INT, DBR_TIME_SHORT @@ -511,7 +633,7 @@ static copyDBRtoPVStructure copyFuncTable[] = 0, // DBR_TIME_ENUM 0, // DBR_TIME_CHAR 0, // DBR_TIME_LONG - 0, // DBR_TIME_DOUBLE + copy_DBR_TIME_DOUBLE, // DBR_TIME_DOUBLE 0, // DBR_GR_STRING 0, // DBR_GR_INT, DBR_GR_SHORT @@ -519,7 +641,7 @@ static copyDBRtoPVStructure copyFuncTable[] = 0, // DBR_GR_ENUM 0, // DBR_GR_CHAR 0, // DBR_GR_LONG - 0, // DBR_GR_DOUBLE + copy_DBR_GR_DOUBLE, // DBR_GR_DOUBLE 0, // DBR_CTRL_STRING 0, // DBR_CTRL_INT, DBR_CTRL_SHORT @@ -527,16 +649,13 @@ static copyDBRtoPVStructure copyFuncTable[] = 0, // DBR_CTRL_ENUM 0, // DBR_CTRL_CHAR 0, // DBR_CTRL_LONG - 0 // DBR_CTRL_DOUBLE + copy_DBR_CTRL_DOUBLE // DBR_CTRL_DOUBLE }; void CAChannelGet::getDone(struct event_handler_args &args) { if (args.status == ECA_NORMAL) { - // TODO - EXCEPTION_GUARD(channelGetRequester->getDone(Status::Ok)); - copyDBRtoPVStructure copyFunc = copyFuncTable[getType]; if (copyFunc) copyFunc(args.dbr, args.count, pvStructure); @@ -546,6 +665,8 @@ void CAChannelGet::getDone(struct event_handler_args &args) std::cout << "no copy func implemented" << std::endl; } + // TODO + EXCEPTION_GUARD(channelGetRequester->getDone(Status::Ok)); } else { @@ -559,7 +680,7 @@ void CAChannelGet::getDone(struct event_handler_args &args) void CAChannelGet::get(bool lastRequest) { // TODO error handling - int result = ca_array_get_callback(channel->getNativeType(), channel->getElementCount(), + int result = ca_array_get_callback(getType, channel->getElementCount(), channel->getChannelID(), ca_get_handler, this); if (result == ECA_NORMAL) {