Closed HongYi-Shern closed 2 years ago
I don't know if anything like these ever made into the Java API, but the C/C++ API for Channel Access has a series of macros (in db_access.h) for doing type checks and conversions like that:
/*----------------------------------------------------------------------------
* repository for some useful PV database constants and utilities
*
* type checking macros -- return non-zero if condition is true, zero otherwise
*
* int dbf_type_is_valid(type) type is a valid DBF_xxx
* int dbr_type_is_valid(type) type is a valid DBR_xxx
* int dbr_type_is_plain(type) type is a valid plain DBR_xxx
* int dbr_type_is_STS(type) type is a valid DBR_STS_xxx
* int dbr_type_is_TIME(type) type is a valid DBR_TIME_xxx
* int dbr_type_is_GR(type) type is a valid DBR_GR_xxx
* int dbr_type_is_CTRL(type) type is a valid DBR_CTRL_xxx
* int dbr_type_is_STRING(type) type is a valid DBR_STRING_xxx
* int dbr_type_is_SHORT(type) type is a valid DBR_SHORT_xxx
* int dbr_type_is_FLOAT(type) type is a valid DBR_FLOAT_xxx
* int dbr_type_is_ENUM(type) type is a valid DBR_ENUM_xxx
* int dbr_type_is_CHAR(type) type is a valid DBR_CHAR_xxx
* int dbr_type_is_LONG(type) type is a valid DBR_LONG_xxx
* int dbr_type_is_DOUBLE(type) type is a valid DBR_DOUBLE_xxx
*
* type conversion macros
*
* char *dbf_type_to_text(type) returns text matching DBF_xxx
* void dbf_text_to_type(text, type) finds DBF_xxx matching text
* int dbf_type_to_DBR(type) returns DBR_xxx matching DBF_xxx
* int dbf_type_to_DBR_TIME(type) returns DBR_TIME_xxx matching DBF_xxx
* int dbf_type_to_DBR_GR(type) returns DBR_GR_xxx matching DBF_xxx
* int dbf_type_to_DBR_CTRL(type) returns DBR_CTRL_xxx matching DBF_xxx
* char *dbr_type_to_text(type) returns text matching DBR_xxx
* void dbr_text_to_type(text, type) finds DBR_xxx matching text
*---------------------------------------------------------------------------*/
and for finding the value from the structure:
/*
* ptr to value given a pointer to the structure and the DBR type
*/
#define dbr_value_ptr(PDBR, DBR_TYPE)
Following up, Ryan's example above shows how to check the original data type and get the associated ..TIME.. type. When you then receive a monitor value, it shows how to extract the value, and you can fundamentally fetch the time like this:
if (dbr.isTIME())
{
TimeStamp epics_time = ((TIME)dbr).getTimeStamp();
// Convert to a more convenient Java time stamp,
// translate from EPICS epoch of 1990
Instant instant = Instant.ofEpochSecond(epics_time.secPastEpoch() + 631152000L,
(int) epics_time.nsec());
System.out.println("Time is " + instant);
}
You might want to make the code more robust by checking for epics_time == null
and also for epics_time.secPastEpoch() == 0
, which can happen when the record was never processed and doesn't have a valid time stamp.
Can we close this issue?
Short answer: you have to write a ton of code.
Long answer: You must set the type explicitly in order to obtain TIME DBR types from JCA (the default is base types). For example, if using a monitor and the base type is unknown you'll need to create a lookup method to map base types to TIME types. Like so:
where lookup method (probably should be part of JCA lib) is something like:
Now you'll have to do some casting and type checking on monitor update. Probably need another method that should be built-in: