Presentation is loading. Please wait.

Presentation is loading. Please wait.

EPICS Access from Python Geoff Savage DØ Workshop Thursday June 22, 2000.

Similar presentations


Presentation on theme: "EPICS Access from Python Geoff Savage DØ Workshop Thursday June 22, 2000."— Presentation transcript:

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); }


Download ppt "EPICS Access from Python Geoff Savage DØ Workshop Thursday June 22, 2000."

Similar presentations


Ads by Google