Adapt to DBR_AMSG/DBR_UTAG

This commit is contained in:
Michael Davidsaver
2020-12-02 15:12:46 -08:00
parent 122e9bdbb4
commit 5a81763fb8
2 changed files with 53 additions and 13 deletions

View File

@ -205,16 +205,20 @@ struct pvArray : public pvCommon {
struct metaTIME { struct metaTIME {
DBRstatus DBRstatus
DBRamsg
DBRtime DBRtime
DBRutag
enum {mask = DBR_STATUS | DBR_TIME}; enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG};
}; };
struct metaDOUBLE { struct metaDOUBLE {
DBRstatus DBRstatus
DBRamsg
DBRunits DBRunits
DBRprecision DBRprecision
DBRtime DBRtime
DBRutag
DBRgrDouble DBRgrDouble
DBRctrlDouble DBRctrlDouble
DBRalDouble DBRalDouble
@ -222,12 +226,14 @@ struct metaDOUBLE {
// similar junk // similar junk
DBRenumStrs DBRenumStrs
enum {mask = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_TIME | DBR_GR_DOUBLE | DBR_CTRL_DOUBLE | DBR_AL_DOUBLE}; enum {mask = DBR_STATUS | DBR_AMSG | DBR_UNITS | DBR_PRECISION | DBR_TIME | DBR_UTAG | DBR_GR_DOUBLE | DBR_CTRL_DOUBLE | DBR_AL_DOUBLE};
}; };
struct metaENUM { struct metaENUM {
DBRstatus DBRstatus
DBRamsg
DBRtime DBRtime
DBRutag
DBRenumStrs DBRenumStrs
// similar junk // similar junk
@ -237,12 +243,14 @@ struct metaENUM {
DBRctrlDouble DBRctrlDouble
DBRalDouble DBRalDouble
enum {mask = DBR_STATUS | DBR_TIME | DBR_ENUM_STRS}; enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG | DBR_ENUM_STRS};
}; };
struct metaSTRING { struct metaSTRING {
DBRstatus DBRstatus
DBRamsg
DBRtime DBRtime
DBRutag
// similar junk // similar junk
DBRenumStrs DBRenumStrs
@ -252,7 +260,7 @@ struct metaSTRING {
DBRctrlDouble DBRctrlDouble
DBRalDouble DBRalDouble
enum {mask = DBR_STATUS | DBR_TIME}; enum {mask = DBR_STATUS | DBR_AMSG | DBR_TIME | DBR_UTAG};
}; };
void attachTime(pvTimeAlarm& pvm, const pvd::PVStructurePtr& pv) void attachTime(pvTimeAlarm& pvm, const pvd::PVStructurePtr& pv)
@ -264,6 +272,9 @@ void attachTime(pvTimeAlarm& pvm, const pvd::PVStructurePtr& pv)
FMAP(message, PVString, "alarm.message", ALARM); FMAP(message, PVString, "alarm.message", ALARM);
FMAP(sec, PVLong, "timeStamp.secondsPastEpoch", ALWAYS); FMAP(sec, PVLong, "timeStamp.secondsPastEpoch", ALWAYS);
FMAP(nsec, PVInt, "timeStamp.nanoseconds", ALWAYS); FMAP(nsec, PVInt, "timeStamp.nanoseconds", ALWAYS);
#ifdef HAVE_UTAG
FMAP(userTag, PVInt, "timeStamp.userTag", ALWAYS);
#endif
#undef FMAP #undef FMAP
} }
@ -328,16 +339,22 @@ void attachAll(PVX& pvm, const pvd::PVStructurePtr& pv)
attachMeta(pvm, pv); attachMeta(pvm, pv);
} }
void mapStatus(unsigned code, pvd::PVInt* status, pvd::PVString* message) template<typename Meta>
void mapStatus(const Meta& meta, pvd::PVInt* status, pvd::PVString* message)
{ {
if(code<ALARM_NSTATUS) #ifdef HAVE_UTAG
message->put(epicsAlarmConditionStrings[code]); if(meta.amsg[0]!='\0') {
message->put(meta.amsg);
} else
#endif
if(meta.status<ALARM_NSTATUS)
message->put(epicsAlarmConditionStrings[meta.status]);
else else
message->put("???"); message->put("???");
// Arbitrary mapping from DB status codes // Arbitrary mapping from DB status codes
unsigned out; unsigned out;
switch(code) { switch(meta.status) {
case NO_ALARM: case NO_ALARM:
out = 0; out = 0;
break; break;
@ -385,6 +402,10 @@ void putMetaImpl(const pvTimeAlarm& pv, const META& meta)
if(pv.nsecMask) { if(pv.nsecMask) {
pv.userTag->put(nsec&pv.nsecMask); pv.userTag->put(nsec&pv.nsecMask);
nsec &= ~pv.nsecMask; nsec &= ~pv.nsecMask;
#ifdef HAVE_UTAG
} else {
pv.userTag->put(meta.utag);
#endif
} }
pv.nsec->put(nsec); pv.sec->put(meta.time.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH); pv.nsec->put(nsec); pv.sec->put(meta.time.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH);
} }
@ -400,7 +421,7 @@ void putTime(const pvTimeAlarm& pv, unsigned dbe, db_field_log *pfl)
putMetaImpl(pv, meta); putMetaImpl(pv, meta);
if(dbe&DBE_ALARM) { if(dbe&DBE_ALARM) {
mapStatus(meta.status, pv.status.get(), pv.message.get()); mapStatus(meta, pv.status.get(), pv.message.get());
pv.severity->put(meta.severity); pv.severity->put(meta.severity);
} }
} }
@ -546,7 +567,7 @@ void putMeta(const pvCommon& pv, unsigned dbe, db_field_log *pfl)
putMetaImpl(pv, meta); putMetaImpl(pv, meta);
#define FMAP(MNAME, FNAME) pv.MNAME->put(meta.FNAME) #define FMAP(MNAME, FNAME) pv.MNAME->put(meta.FNAME)
if(dbe&DBE_ALARM) { if(dbe&DBE_ALARM) {
mapStatus(meta.status, pv.status.get(), pv.message.get()); mapStatus(meta, pv.status.get(), pv.message.get());
FMAP(severity, severity); FMAP(severity, severity);
} }
if(dbe&DBE_PROPERTY) { if(dbe&DBE_PROPERTY) {
@ -774,6 +795,16 @@ short PVD2DBR(pvd::ScalarType pvt)
return -1; return -1;
} }
static
pvd::StructureConstPtr buildTimeStamp()
{
return pvd::FieldBuilder::begin()
->add("secondsPastEpoch", pvd::pvLong)
->add("nanoseconds", pvd::pvInt)
->add("userTag", pvd::pvInt)
->createStructure();
}
epics::pvData::FieldConstPtr epics::pvData::FieldConstPtr
ScalarBuilder::dtype() ScalarBuilder::dtype()
{ {
@ -808,7 +839,7 @@ ScalarBuilder::dtype()
->addArray("value", pvt); ->addArray("value", pvt);
builder = builder->add("alarm", standard->alarm()) builder = builder->add("alarm", standard->alarm())
->add("timeStamp", standard->timeStamp()); ->add("timeStamp", buildTimeStamp());
if(dbr!=DBR_ENUM) { if(dbr!=DBR_ENUM) {
builder = builder->addNestedStructure("display") builder = builder->addNestedStructure("display")
@ -1108,11 +1139,11 @@ struct MetaBuilder : public PVIFBuilder
pvd::StandardFieldPtr std(pvd::getStandardField()); pvd::StandardFieldPtr std(pvd::getStandardField());
if(fld.empty()) { if(fld.empty()) {
return builder->add("alarm", std->alarm()) return builder->add("alarm", std->alarm())
->add("timeStamp", std->timeStamp()); ->add("timeStamp", buildTimeStamp());
} else { } else {
return builder->addNestedStructure(fld) return builder->addNestedStructure(fld)
->add("alarm", std->alarm()) ->add("alarm", std->alarm())
->add("timeStamp", std->timeStamp()) ->add("timeStamp", buildTimeStamp())
->endNested(); ->endNested();
} }
} }

View File

@ -30,6 +30,15 @@
# define USE_MULTILOCK # define USE_MULTILOCK
#endif #endif
#ifndef DBRutag
# define DBR_AMSG 0
# define DBR_UTAG 0
# define DBRamsg
# define DBRutag
#else
# define HAVE_UTAG
#endif
namespace epics { namespace epics {
namespace pvAccess { namespace pvAccess {
class ChannelRequester; class ChannelRequester;