get link field time and alarms

This commit is contained in:
Michael Davidsaver
2013-04-14 11:06:33 -04:00
parent a834e4974d
commit 4f00b841cc
3 changed files with 70 additions and 7 deletions

View File

@ -50,14 +50,15 @@ static int pyField_Init(pyField *self, PyObject *args, PyObject *kws)
return -1; return -1;
} }
if(self->addr.field_type > DBF_MENU) {
PyErr_Format(PyExc_TypeError, "%s: Access to field type %d is not supported",
pvname, self->addr.field_type);
return -1;
}
return 0; return 0;
} }
static void exc_wrong_ftype(pyField *self)
{
PyErr_Format(PyExc_TypeError, "Operation on field type %d is not supported",
self->addr.field_type);
}
static PyObject* pyField_name(pyField *self) static PyObject* pyField_name(pyField *self)
{ {
return Py_BuildValue("ss", return Py_BuildValue("ss",
@ -92,7 +93,7 @@ static PyObject* pyField_getval(pyField *self)
case DBF_STRING: case DBF_STRING:
return PyString_FromString((char*)self->addr.pfield); return PyString_FromString((char*)self->addr.pfield);
default: default:
PyErr_SetNone(PyExc_TypeError); exc_wrong_ftype(self);
return NULL; return NULL;
} }
} }
@ -137,7 +138,7 @@ static PyObject* pyField_putval(pyField *self, PyObject* args)
break; break;
} }
default: default:
PyErr_SetNone(PyExc_TypeError); exc_wrong_ftype(self);
return NULL; return NULL;
} }
Py_RETURN_NONE; Py_RETURN_NONE;
@ -167,6 +168,49 @@ static PyObject *pyField_getarray(pyField *self)
#endif #endif
} }
static PyObject* pyField_getTime(pyField *self)
{
DBLINK *plink = self->addr.pfield;
epicsTimeStamp ret;
long sts, sec, nsec;
if(self->addr.field_type!=DBF_INLINK) {
PyErr_SetString(PyExc_TypeError, "getTime can only be used on DBF_INLINK fields");
return NULL;
}
sts = dbGetTimeStamp(plink, &ret);
if(sts) {
PyErr_SetString(PyExc_TypeError, "getTime failed");
return NULL;
}
sec = ret.secPastEpoch + POSIX_TIME_AT_EPICS_EPOCH;
nsec = ret.nsec;
return Py_BuildValue("ll", sec, nsec);
}
static PyObject* pyField_getAlarm(pyField *self)
{
DBLINK *plink = self->addr.pfield;
long sts;
epicsEnum16 stat, sevr;
if(self->addr.field_type!=DBF_INLINK) {
PyErr_SetString(PyExc_TypeError, "getAlarm can only be used on DBF_INLINK fields");
return NULL;
}
sts = dbGetAlarm(plink, &stat, &sevr);
if(sts) {
PyErr_SetString(PyExc_TypeError, "getAlarm failed");
return NULL;
}
return Py_BuildValue("ll", (long)sevr, (long)stat);
}
static PyMethodDef pyField_methods[] = { static PyMethodDef pyField_methods[] = {
{"name", (PyCFunction)pyField_name, METH_NOARGS, {"name", (PyCFunction)pyField_name, METH_NOARGS,
"Return Names (\"record\",\"field\")"}, "Return Names (\"record\",\"field\")"},
@ -178,6 +222,10 @@ static PyMethodDef pyField_methods[] = {
"Sets field value from a scalar"}, "Sets field value from a scalar"},
{"getarray", (PyCFunction)pyField_getarray, METH_NOARGS, {"getarray", (PyCFunction)pyField_getarray, METH_NOARGS,
"Return a numpy ndarray refering to this field for in-place operations."}, "Return a numpy ndarray refering to this field for in-place operations."},
{"getTime", (PyCFunction)pyField_getTime, METH_NOARGS,
"Return link target timestamp as a tuple (sec, nsec)."},
{"getAlarm", (PyCFunction)pyField_getAlarm, METH_NOARGS,
"Return link target alarm condtions as a tuple (severity, status)."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View File

@ -170,4 +170,10 @@ class _Field(object):
lock is held (ie withing :meth:`process <DeviceSupport.process>`). lock is held (ie withing :meth:`process <DeviceSupport.process>`).
""" """
def getAlarm(self):
"""Returns a tuple (severity, status) with the condtion of the linked field.
Only works for fields of type DBF_INLINK.
"""
_hooks = {} _hooks = {}

View File

@ -288,6 +288,15 @@ class Field(_dbapi._Field):
self._record = getRecord(rec) self._record = getRecord(rec)
return self._record return self._record
def getTime(self):
"""Get timestamp of link target.
Only works for DBF_INLINK fields.
Returns the time in seconds since the posix epoch.
:rtype: float
"""
def __cmp__(self, B): def __cmp__(self, B):
if isinstance(B, Field): if isinstance(B, Field):
B=B.getval() B=B.getval()