Download presentation
Presentation is loading. Please wait.
Published byJocelyn Berry Modified over 9 years ago
1
EPICS Access from Python Geoff Savage DØ Workshop Thursday June 22, 2000
2
6/22/00DZero Workshop2 Game Plan Discuss EPICS channel access (CA) u C library u High level discussion Provide examples from CaChannel u Python class that wraps CA library u Wrap = provide python interface u Delve further into CA functionality
3
6/22/00DZero Workshop3 EPICS Channel Access Role in EPICS architecture Architecture Services Library functionality
4
6/22/00DZero Workshop4 Role in EPICS Architecture IOC Host IOC Network Transfer information between host and IOC
5
6/22/00DZero Workshop5 CA Architecture Client-server architecture u IOC = server u Host application = client Client makes requests to server Channel = client-server connection u Connection between client and PV u All channel creation requests made by name Host and IOC must be on network
6
6/22/00DZero Workshop6 CA Services Dynamic channel creation Automatic reconnect Read/Write Monitoring u Events u Access control u Connection Data type conversions Composite data structures
7
6/22/00DZero Workshop7 Channel Creation IOC Host Who has channel ‘XXXX’? (broadcast) IOC Host I have channel ‘XXXX’. IOC Host Negotiate connection. (point-to-point)
8
6/22/00DZero Workshop8 CA Library Messages Connection Synchronous Asynchronous Group
9
6/22/00DZero Workshop9 CA Messages All CA requests are buffered in host u Connect, get, put, … u Increased efficiency Buffer is sent when full or upon user request PV get/put requests can’t be in same message as connection request
10
6/22/00DZero Workshop10 Connection (CA Lib) “Establish and maintain a virtual circuit between application and PV in a CA server” Connection must be made before accessing PV Network transparency (by name) Callback on connection status change
11
6/22/00DZero Workshop11 Synchronous (CA Lib) Make requests Flush request buffer into message Wait until all requests in message have been completed or timeout occurs Return control to application
12
6/22/00DZero Workshop12 Asynchronous (CA Lib) Make requests and specify callback Flush request buffer into message Return control to application You are notified of completion through execution of callback at a later time Synchronous and Asynchronous requests can be in the same message
13
6/22/00DZero Workshop13 Group (CA Lib) “Guarantee that a set of CA requests have completed” Synchronous (no callback) Create Get/put Block waiting for completion (timeout) Test for completion Remove uncompleted requests
14
6/22/00DZero Workshop14 EPICS CA Summary High level discussion Role = transfer information Architecture = client-server Services - Covered in more detail during CaChannel discussion Library functionality u Buffering for efficiency, Connections, Synchronous, Asynchronous, Group
15
6/22/00DZero Workshop15 CaChannel Architecture Simple examples Data types Synchronous I/O Asynchronous I/O Monitoring Use with Tkinter
16
6/22/00DZero Workshop16 CaChannel Architecture EPICS channel access C library Collection of C functions Distributed with EPICS caPython Python wrapper around the C library Collection of python functions CaChannel Python class Calls caPython functions Move from C function to Python class interface.
17
6/22/00DZero Workshop17 setup d0python python Python 1.5.2 (#6, May 10 1999, 21:44:32) [C] on osf1V4 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> from CaChannel import * >>> ch = CaChannel() >>> ch.searchw('catest') >>> ch.putw(123.456) >>> ch.getw() 123.456 Simple Interpreter Example Each method performs one synchronous request. connect write read
18
6/22/00DZero Workshop18 Simple Script Example #! /bin/env python # from CaChannel import * def main(): try: catest = CaChannel() catest.searchw('catest') catest.putw(123.456) print catest.getw() except CaChannelException, status: print ca.message(status) main()
19
6/22/00DZero Workshop19 Data Types … Each PV has a native type Different data types can be requested Requests using native type most efficient >>> ch.getw() 123.456 >>> ch.getw(ca.DBR_INT) 123 >>> ch.getw(ca.DBR_STRING) '123' >>> ch.field_type() 6 >>> ca.dbr_text(ch.field_type()) 'DBR_DOUBLE‘ >>> Not all caPython functions implemented as methods.
20
6/22/00DZero Workshop20 … Data Types … >>> scan = CaChannel() >>> scan.searchw('catest.SCAN') >>> scan.getw() 6 >>> scan.getw(ca.DBR_STRING) '1 second' >>> scan.putw(5) >>> scan.getw(ca.DBR_STRING) '2 second‘ >>> ca.dbr_text(scan.field_type()) 'DBR_ENUM' >>>
21
6/22/00DZero Workshop21 … Data Types >>> scan.putw('1 second') Traceback (innermost last): File " ", line 1, in ? File "/d0usr/products/d0python/OSF1/v02_03/lib/CaChannel.py", line 383, in putw count, pval = self.__setup_put(value, req_type) File "/d0usr/products/d0python/OSF1/v02_03/lib/CaChannel.py", line 131, in __setup_put CaChannel.dbr_d[req_type]['convert'](value), ValueError: invalid literal for int(): 1 second >>> scan.putw('1 second', ca.DBR_STRING) >>> scan.getw(ca.DBR_STRING) '1 second'
22
6/22/00DZero Workshop22 Request Data Types Request typePython typeComments DBR_STRINGString DBR_ENUMIntegerEnumerated DBR_CHARInteger8 bits DBR_INTInteger16 bits DBR_LONGInteger32 bits DBR_FLOATFloat DBR_DOUBLEFloat Array of DBRList of type
23
6/22/00DZero Workshop23 Synchronous I/O … pend_io = flush request buffer and wait for CA requests to complete pend_io affects requests from all CaChannel instances Only one request buffer for all CaChannel instances
24
6/22/00DZero Workshop24 … Synchronous I/O … Multiple requests can be issued before each pend_io All connections must be made before get or put On a get a value is not valid until pend_io has returned with no errors >>> >>> ch.search('catest') >>> ch.pend_io() >>> >>> ch.array_put(123.456) >>> ch.pend_io() >>> >>> ch.array_get() >>> ch.pend_io() >>> ch.getValue() 123.456
25
6/22/00DZero Workshop25 … Synchronous I/O catest.array_get() cawave.array_get() scan.array_get() ca.pend_io(1.0) print catest.getValue() print cawave.getValue() print scan.getValue() except CaChannelException,status: print ca.message(status) try: catest = CaChannel() cawave = CaChannel() scan = CaChannel() catest.search('catest') cawave.search('cawave') scan.search('catest.SCAN') catest.pend_io() t=(0,1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19) catest.array_put(123.456) cawave.array_put(t) scan.array_put("1 second“, ca.DBR_STRING) cawave.pend_io()
26
6/22/00DZero Workshop26 Asynchronous I/O … No waiting for CA requests to complete A user specified callback function is executed when the request has completed ca_pend_event = flush the request buffer and wait for timeout seconds or until all CA background activity is processed ca_flush_io = flush the request buffer
27
6/22/00DZero Workshop27 … Asynchronous I/O … Asynchronous callbacks do not preempt the main thread Instead ca_pend_io, ca_pend_event, or ca_poll must be called at least every 15 seconds to allow background activity to process ca_poll = ca_pend_event with short (0.001 second) timeout
28
6/22/00DZero Workshop28 … Asynchronous I/O … try: chan = CaChannel() chan.search_and_connect('catest', connectCb) chan.flush_io() for i in range(20): chan.pend_event() chan.array_put_callback(3.3, None, None, putCb) chan.flush_io() for i in range(20): chan.pend_event() chan.array_get_callback(None, None, getCb1) chan.flush_io() for i in range(20): chan.pend_event() chan.array_get_callback(ca.dbf_type_to_DBR_STS( chan.field_type()), None,getCb2) chan.flush_io() for i in range(20): chan.pend_event() except CaChannelException, status: print ca.message(status)
29
6/22/00DZero Workshop29 Compound Data Types Only supported in asynchronous mode Extra information with the value u Status – alarm values u Time – status + timestamp u Graphics – status + alarm limits + display limits u Control – graphics + control limits Routines are provided to convert DBR type to compound type
30
6/22/00DZero Workshop30 Connection Callback epics_args = 2 element tuple t[1] = channel identifier, used to get the channels name t[2] = connection state u CA_OP_CONN_UP u CA_OP_CONN_DOWN user_args = tuple containing all python objects specified after the callback in the method def connectCb(epics_args, user_args): print epics_args print user_args
31
6/22/00DZero Workshop31 Put Callback chid = channel identifier type = request type (DBR_XXXX) count = element count status = CA status code from server def putCb(epics_args, user_args): print ca.name(epics_args['chid']) print ca.dbr_text(epics_args['type']) print epics_args['count'] print ca.message(epics_args['status']) print user_args
32
6/22/00DZero Workshop32 Get Callback value(s) = data returned by the server. Multiple data elements are returned in a tuple. def getCb1(epics_args, user_args): print "pvName = ", ca.name(epics_args['chid']) print "type = ", ca.dbr_text(epics_args['type']) print "count = ", epics_args['count'] print "status = ", ca.message(epics_args['status']) print "user args = ", user_args print "value(s) = ", epics_args['pv_value']
33
6/22/00DZero Workshop33 Get Callback with Status pv_severity = alarm severity pv_status = alarm status def getCb2(epics_args, user_args): print "pvName = ", ca.name(epics_args['chid']) print "type = ", ca.dbr_text(epics_args['type']) print "count = ", epics_args['count'] print "status = ", ca.message(epics_args['status']) print "user args = ", user_args print "value(s) = ", epics_args['pv_value'] print ca.alarmSeverityString(epics_args['pv_severity']) print ca.alarmStatusString(epics_args['pv_status'])
34
6/22/00DZero Workshop34 Asynchronous I/O Usage Tip To obtain the CaChannel instance to which the callback corresponds use the name Create a dictionary whose keys are names and contents are the CaChannel instances
35
6/22/00DZero Workshop35 … Asynchronous I/O Callbacks implemented for u Time u Graphics u Control
36
6/22/00DZero Workshop36 Monitoring … Access rights Connection For technical reasons neither of these are in the CaChannel interface They can be implemented as a C function
37
6/22/00DZero Workshop37 … Monitoring … Asynchronous I/O originated at the server Client requests notification from the server when u the channel’s value changes by more than the value dead band or alarm dead band u the channel’s alarm state changes Callbacks match those described under asynchronous I/O
38
6/22/00DZero Workshop38 … Monitoring … def eventCb(epics_args, user_args): print ca.message(epics_args['status']) print "new value = ", epics_args['pv_value'] print ca.alarmSeverityString(epics_args['pv_severity']) print ca.alarmStatusString(epics_args['pv_status']) try: chan = CaChannel() chan.searchw('catest') chan.add_masked_array_event( ca.dbf_type_to_DBR_STS(chan.field_type()), None, ca.DBE_VALUE | ca.DBE_ALARM, eventCb) except CaChannelException, status: print ca.message(status)
39
6/22/00DZero Workshop39 … Monitoring Monitor maskNotification condition ca.DBE_VALUE when the channel’s value changes by more than MDEL ca.DBE_LOG when the channel’s value changes by more than MDEL ca.DBE_ALARM when the channel’s alarm state changes
40
6/22/00DZero Workshop40 Tkinter and CaChannel EPICS CA is not thread safe All CaChannel activity must be performed in the main thread Use the Tkinter after method to interrupt the mainloop at regular intervals to allow CA backgroud activity to execute Execute CaChannel calls from the update function called by after
41
6/22/00DZero Workshop41 CaChannel Summary Architecture = Python wrapper around C library Data types = native types most efficient, extended types Synchronous I/O = interpreter or scripts, easy to use Asynchronous I/O and monitoring u Callbacks u Background activity
42
6/22/00DZero Workshop42 Documentation In the doc directory of the d0python package CaChannel Guide caPython Guide Working on getting up to date u Time, graphic, and control return types u Timeouts (pend_io, pend_event)
43
6/22/00DZero Workshop43 CaChannel Internals Constructor searchw() – connect putw() - write getw() - read
44
6/22/00DZero Workshop44 CaChannel Constructor def __init__(self): # Un-initialized channel id structure self.__chid = ca.new_chid() # Monitor event id self.__evid = None self.__timeout = None # override class timeout
45
6/22/00DZero Workshop45 searchw() def searchw(self, pvName): status = ca.search(pvName, self.__chid) if (ca.ECA_NORMAL != status): raise CaChannelException, status if self.__timeout is None: timeout = CaChannel.ca_timeout else: timeout = self.__timeout status = ca.pend_io(timeout) if (ca.ECA_NORMAL != status): raise CaChannelException, status
46
6/22/00DZero Workshop46 putw() def putw(self, value, req_type=None): if(None == req_type): req_type = self.field_type() count, pval = self.__setup_put(value, req_type) status = ca.array_put(req_type, count, self.__chid, pval) if (ca.ECA_NORMAL != status): ca.ptrfree(pval) raise CaChannelException, status if self.__timeout is None: timeout = CaChannel.ca_timeout else: timeout = self.__timeout status = ca.pend_io(timeout) if (ca.ECA_NORMAL != status): ca.ptrfree(pval) raise CaChannelException, status ca.ptrfree(pval)
47
6/22/00DZero Workshop47 getw() … def getw(self, req_type=None): if(None == req_type): req_type = ca.field_type(self.__chid) count, pval = self.__setup_get(req_type) status = ca.array_get(req_type, count, self.__chid, pval) if (ca.ECA_NORMAL != status): ca.ptrfree(pval) raise CaChannelException, status if self.__timeout is None: timeout = CaChannel.ca_timeout else: timeout = self.__timeout status = ca.pend_io(timeout)
48
6/22/00DZero Workshop48 … getw() if (ca.ECA_NORMAL != status): ca.ptrfree(pval) raise CaChannelException, status if(1 == count): value = ca.ptrvalue(pval) else: value = self.__build_list(pval, count) ca.ptrfree(pval) return value
49
6/22/00DZero Workshop49 Simple C Example … /*caExample.c*/ #include main(int argc,char **argv) { struct dbr_ctrl_enum data; int ndx; int status; chid mychid;
50
6/22/00DZero Workshop50 … Simple C Example SEVCHK(ca_task_initialize(),"ca_task_initialize"); SEVCHK(ca_search(argv[1],&mychid),"ca_search failure"); SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); SEVCHK(ca_get(DBR_CTRL_ENUM,mychid,(void *)&data),"ca_get failure"); SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); printf("status: %d, severity: %d, count: %d\n", data.status, data.severity, data.no_str); for (ndx = 0; ndx < data.no_str; ndx += 1) printf(" %2d %s\n", ndx, data.strs[ndx]); return(0); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.