diff --git a/.appveyor.yml b/.appveyor.yml index 2b42845..1720729 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -11,9 +11,15 @@ cache: #---------------------------------# install: -# for the sequencer - - cinst re2c - - cmd: git submodule update --init --recursive + + - powershell -Command "Invoke-WebRequest https://www.python.org/ftp/python/3.10.9/python-3.10.9-amd64.exe -OutFile python-install.exe" + - start /wait python-install.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 + - refreshenv + - python -m pip install --upgrade pip setuptools + + # For the sequencer + - choco install re2c -y + - git submodule update --init --recursive #---------------------------------# # repository cloning # diff --git a/pdbApp/pvif.cpp b/pdbApp/pvif.cpp index 6f26d9c..047be11 100644 --- a/pdbApp/pvif.cpp +++ b/pdbApp/pvif.cpp @@ -27,6 +27,10 @@ #include +#ifdef HAVE_UTAG +#define CUSTOM_ALARM_MSG +#endif + #ifdef EPICS_VERSION_INT # if EPICS_VERSION_INT>=VERSION_INT(3,16,1,0) # define USE_INT64 @@ -344,18 +348,32 @@ void attachAll(PVX& pvm, const pvd::PVStructurePtr& pv) } template +#ifdef CUSTOM_ALARM_MSG +void mapStatus(const Meta& meta, pvd::PVInt* status, pvd::PVString* message, dbChannel *chan) +#else void mapStatus(const Meta& meta, pvd::PVInt* status, pvd::PVString* message) +#endif { +#ifdef CUSTOM_ALARM_MSG + pdbRecordIterator info(chan); + const char *userMsg = info.info("Q:alarm:msg"); +#endif #ifdef HAVE_UTAG if(meta.amsg[0]!='\0') { message->put(meta.amsg); } else #endif +#ifdef CUSTOM_ALARM_MSG + if(userMsg != NULL && meta.status > NO_ALARM) { + message->put(userMsg); + } else +#endif + { if(meta.statusput(epicsAlarmConditionStrings[meta.status]); else message->put("???"); - + } // Arbitrary mapping from DB status codes unsigned out; switch(meta.status) { @@ -425,7 +443,11 @@ void putTime(const pvTimeAlarm& pv, unsigned dbe, db_field_log *pfl) putMetaImpl(pv, meta); if(dbe&DBE_ALARM) { + #ifdef CUSTOM_ALARM_MSG + mapStatus(meta, pv.status.get(), pv.message.get(), pv.chan); + #else mapStatus(meta, pv.status.get(), pv.message.get()); + #endif pv.severity->put(meta.severity); } } @@ -571,7 +593,11 @@ void putMeta(const pvCommon& pv, unsigned dbe, db_field_log *pfl) putMetaImpl(pv, meta); #define FMAP(MNAME, FNAME) pv.MNAME->put(meta.FNAME) if(dbe&DBE_ALARM) { + #ifdef CUSTOM_ALARM_MSG + mapStatus(meta, pv.status.get(), pv.message.get(), pv.chan); + #else mapStatus(meta, pv.status.get(), pv.message.get()); + #endif FMAP(severity, severity); } if(dbe&DBE_PROPERTY) { diff --git a/testApp/test_custom_alarm.db b/testApp/test_custom_alarm.db new file mode 100644 index 0000000..9ca8751 --- /dev/null +++ b/testApp/test_custom_alarm.db @@ -0,0 +1,10 @@ +record(ai, "custom:ai") { + field(DESC, "Custom Analog Input for Alarm Test") + field(DTYP, "Soft Channel") + field(SCAN, "Passive") + field(HIHI, "50.0") + field(HIGH, "40.0") + field(HHSV, "MAJOR") + field(HSV, "MINOR") + info(Q:alarm:msg, "Custom Msg Alarm AI!") +} \ No newline at end of file diff --git a/testApp/testpvif.cpp b/testApp/testpvif.cpp index df0b609..5b3799f 100644 --- a/testApp/testpvif.cpp +++ b/testApp/testpvif.cpp @@ -20,6 +20,11 @@ #include "pvif.h" #include "utilities.h" + +#ifdef HAVE_UTAG +#define CUSTOM_ALARM_MSG +#endif + namespace pvd = epics::pvData; extern "C" @@ -637,12 +642,70 @@ void testFilters() testFieldEqual(root, "dut.value", expected); #endif // >= 7.0 } +#ifdef CUSTOM_ALARM_MSG +void testCustomAlarmMessage() +{ + testDiag("testCustomAlarmMessage"); + + TestIOC IOC; + + testdbReadDatabase("p2pTestIoc.dbd", NULL, NULL); + p2pTestIoc_registerRecordDeviceDriver(pdbbase); + testdbReadDatabase("test_custom_alarm.db", NULL, NULL); + + aiRecord *prec_custom_ai = (aiRecord*)testdbRecordPtr("custom:ai"); + testTrue(prec_custom_ai != NULL); + + IOC.init(); + + DBCH chan_ai("custom:ai"); + + pvd::PVStructurePtr root; + p2p::auto_ptr pvif_ai; + { + ScalarBuilder builder_ai(chan_ai); + + pvd::StructureConstPtr dtype_root(pvd::getFieldCreate()->createFieldBuilder() + ->add("custom_ai", builder_ai.dtype()) + ->createStructure()); + root = pvd::getPVDataCreate()->createPVStructure(dtype_root); + pvif_ai.reset(builder_ai.attach(root, FieldName("custom_ai"))); + } + + pvd::BitSet mask; + + dbScanLock((dbCommon*)prec_custom_ai); + prec_custom_ai->val = 55.0; + dbProcess((dbCommon*)prec_custom_ai); + dbScanUnlock((dbCommon*)prec_custom_ai); + + pvif_ai->put(mask, DBE_ALARM|DBE_PROPERTY, NULL); + + testFieldEqual(root, "custom_ai.alarm.message", "Custom Msg Alarm AI!"); + testFieldEqual(root, "custom_ai.alarm.severity", 2); + testFieldEqual(root, "custom_ai.alarm.status", 1); + + dbScanLock((dbCommon*)prec_custom_ai); + prec_custom_ai->val = 25.0; + dbProcess((dbCommon*)prec_custom_ai); + dbScanUnlock((dbCommon*)prec_custom_ai); + pvif_ai->put(mask, DBE_ALARM|DBE_PROPERTY, NULL); + + testFieldEqual(root, "custom_ai.alarm.message", "NO_ALARM"); + testFieldEqual(root, "custom_ai.alarm.severity", 0); + testFieldEqual(root, "custom_ai.alarm.status", 0); +} +#endif // CUSTOM_ALARM_MSG } // namespace MAIN(testpvif) { +#ifdef CUSTOM_ALARM_MSG + testPlan(105); +#else testPlan(98); +#endif #ifdef USE_INT64 testDiag("Testing of 64-bit field access"); #else @@ -651,5 +714,8 @@ MAIN(testpvif) testScalar(); testPlain(); testFilters(); +#ifdef CUSTOM_ALARM_MSG + testCustomAlarmMessage(); +#endif return testDone(); }