In the SNL global entry block, which is called once, when the sequencer starts up, I do all the Python bindings:
For example, I initialise my "handle" structure members (such as "PyObject * pFuncText "):
// pFuncText is also a borrowed reference
elogbook->pFuncText = PyDict_GetItemString(elogbook->pDict, (char*)"createOlogEntry");
//pClient would be null if the Python syntax is wrong, for example
if (elogbook->pFuncText == NULL) {
if (PyErr_Occurred()) {
PyErr_Print();
elogbook->initialised = 0;
log_error("Failed to get logbook createOlogEntry function");
log_python_error();
return -3;
}
}
Then, in the API that is re-used by the SNL (i.e. in a particular state "entry" block), I use the structures created:
/*
* Write a text message to the logbook handle.
*
* Parameters:
* log_handle = handle from call to elogbook_open.
*
* Returns 0 on success.
* -1 = input parameter error
* -2 = invalid handle
* -3 = handle not initialised.
* -4 = Other Python error
*/
int elogbook_log_text (int log_handle, const char *text){
// sanity checking - allow to be called with invalid handle.
.. snip ..
PyObject *pArgs, *pValue, *pText;
//Build a tuple to hold my arguments
pText = PyString_FromString(text);
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, elogbook->pObjLogbook);
PyTuple_SetItem(pArgs, 1, pText);
//Call createOlogEntry function, passing it the input text
pValue = PyObject_CallObject(elogbook->pFuncText, pArgs);
if (pValue == NULL) {
if (PyErr_Occurred()) {
PyErr_Print();
log_error("Call to createOlogEntry from elogbook_log_text failed");
log_python_error();
return -4;
}
log_error("Call to createOlogEntry returned NULL instead of return code");
result = -4;
} else {
result = (int)PyLong_AsLong(pValue);
Py_DECREF(pValue);
}
return result;
}
I don't use any such context calls. The Python in question just does things like:
import epics
... snip ...
''' Create a new entry in the logbook from SUP POS status'''
def createOlogPOSPulseEndEntry(logbook, status, write_elog=1):
Id = epics.caget('CTRL:PULSE-ID', as_string=True)
StartTime = epics.caget('CTRL-SUP-TIME:T0-HR', as_string=True)
EndTime = epics.caget('CTRL-SUP-TIME:TEND-HR', as_string=True)
..snip...
Should I be doing anything different with ca contexts in the Python code??
Good question: I will look into that...
Well, my SNL is generated from Enterprise Architect XMI via an XSLT .. I *could* craft an XMI to Python XSLT, too!! :D
Regards,
Kevin
--
Kevin Meyer
Cosylab, Ljubljana, Slovenia
Telephone: +386-(0)1-320-47-82 Mobile: +386-(0)70-260-321