EpicsCA.PV = class PV
    == pv: The Process Variable
    
    A pv encapsulates an Epics Process Variable (aka a 'channel').
   
    The primary interface methods for a pv are to get() and put() its value:
      >>>p = PV(pv_name)    # create a pv object given a pv name
      >>>p.get()            # get pv value
      >>>p.put(val)         # set pv to specified value. 
 
    Additional important attributes include:
      >>>p.pvname           # name of pv
      >>>p.value            # pv value (can be set or get)
      >>>p.char_value       # string representation of pv value
      >>>p.count            # number of elements in array pvs
      >>>p.type             # EPICS data type: 'string','double','enum','long',....
 
    A pv uses Channel Access monitors to improve efficiency and minimize
    network traffic, so that calls to get() fetches the cached value,
    which is automatically updated. 
 
    Note that it is important to periodically call poll() or pend_event()
    to make sure that the pv values are up to date.
    
== Initialization, Connection, time-outs:
 
   On creating a pv [pv = EpicsCA.PV()], the following optional arguments can be given:
       pvname            name of pv                                          [None]
       callback          user-specified callback function (see below)        [None]
       connect           indicate whether or not to connect                  [False]
       use_numpy         use numpy arrays for array data                     [True]
       use_control       use full Control Epics Data Type                    [False]
       connect_time      maximum time (in sec) for connection                [1.0]
       use_char_changes  run user-defined callbacks only when the
                        'char_value' changes, ignoring trivial changes       [True]
 
   A PV can be created without a pvname and assigned a pvname later.
 
   In order to communicate with the corresponding channel on the IOC, a PV needs to
   "connect".  This creates a dedicated connection to the IOC on which the PV lives,
   and creates resources for the PV.   A Python PV object cannot actually do anything
   to the PV on the IOC until it is connected.
 
   Connection is a two-step process.  First a local PV is "created" in local memory.
   This happens very quickly, and happens automatically when a PV is initialized (and
   has a pvname).
 
   Second, connection is completed with network communication to the IOC.  This is
   necessary to determine the PV "type" (that is, integer, double, string, enum, etc)
   and "count" (that is, whether it holds an array of values) that are needed to
   allocate resources on the client machine.  Again, this connection must happen
   before you can do anything useful with the PV.
 
   When done as a single step, the creation and connection process takes 30msec.  This
   is a feature of Channel Access.   In normal use this is fast enough, but for cases
   where you know that you're going to use many PVs, this connection time can add up.
   In this case, it turns out (again, a Channel Access feature) that it is much faster
   to create many PVs without connecting to them, and then connect to all of them.
   
   Because of this, a Python PV is created with "connect=False" by default.  This
   delays complete connection until it is needed.  That is, doing a .get() or .put()
   will automatically connect to the PV.  Generally this is good, as it reduces
   average connection time, but there is an important caveat:
      an unconnected PV will not respond to changes.
 
   That means, you cannot create a bunch of PVs with  x = PV(pvname) and then
   poll() for changes -- you won't see any changes until the PVs are connected.
   
 
   A convienent way to deal with this is to run EpicsCA.connect_all() prior to polling
   for changes.  This function will complet the connection of all unconnected PVs.
            
   The 'connected' attribute reflects wether the pv is successfully connected.
 
   >>> p = PV()
   >>> p.connected
   False
   >>> p
   <pv: unnamed>
 
   >>> p.pvname = 'XXX:m1.VAL'
   >>> p.connected
   True
 
   >>> p
   <pv: 'XXX:m1.VAL', count=1, type=double, access=read/write>
 
   If a pv cannot connect in the connect_time, an EpicsCAError will be raised.
   
== Information about a pv
 
   In addition to 'value', 'char_value', and 'connected' discussed above, a pv has the
   following attributes:
       count         element count: 1 for scalars, number of array elements for arrays.
       precision     precision (number of values past decimal point) for floating point values
       
       host          name of host providing pv
       access        string describing read/write access
       ctype         integer containing EPICS type (int, long, enum, etc)
       type          string describing EPICS type
       enum_strings  list of strings for Enumeration States for enum variables
 
       status        integer status  (1 means OK, apparantly)
       severity      EPICS severity  (0 means OK, apparantly)
 
       info          text paragraph of 'status report' listing most of all attributes.
 
   The following additional 'Control Type' information can also be obtained for pvs:
       units         string containing units, if applicable (else None)
       hlim          control high limit
       llim          control low limit
       display_llim  display high limit
       display_hlim  display low limit
   To get this information, you must create the PV with the optional 'use_control=True'
   argument to PV():
 
   >>> p = PV('XXX:m1.VAL', use_control=True)
   >>> print p.units
   'mm'
 
   PV representation:
       
       At the python command prompt, typing the name of the PV object will print a short
   description of the PVs connection status and type.  Some examples:
   >>> p = EpicsCA.PV()
   >>> p
   <PV: unnamed>
   >>> p = EpicsCA.PV('xxx',connect=False)
   >>> p, p.connected
   (<PV: 'xxx': unconnected>, False)
   >>> p.get()
   >>> p, p.connected
   (<PV: 'xxx', count=1, type=double, access=read/write>, False)
 
 
== PV Values, String representations
 
   The 'value' attribute holds the PVs value and can be gotten or set either with .get()/.set()
   methods or simply by accessing/assigning to the 'value':
 
   >>> print p.value
   1.000
   >>> p.value = 2.0     # (PV processes, motor moves, etc)
 
   Or, with methods:
   
   >>> print p.get()
   2.000
   >>> p.put(1.0)
 
   The 'char_value' attribute holds a string representation of the value.  For floating point
   numbers and integers, this is simply an appropriately formatted string (using the precision).
   For ENUM variables, this contains the 'enum string' name.
 
   The char_value attribute cannot be set.
 
== Getting and Putting PVs
 
   get() can retrieve either the 'raw' value or a string representation -- the 'char_value'.
   That is,  pv.get() and pv.value will return the 'raw' value, which may be of several data
   types (int, float, array, string).
 
   To get the string representation for a PV, use pv.get(use_char=True) or pv.char_value.
   What the 'char_value' holds depends on the data type, but it will always be a python string.
   For string PV data, the char_value is the same as the raw value. For integers, it is
   pretty straightforward.  For floats/doubles, the char_value is formatted according to the
   PVs precision.  For enum PVs, the char_value hold the value description.  For arrays, the
   char_value will be '<array(size=N, type=I)>' where N is the length of the array, and the
   type will tell the data type of each array member.
 
   With put(), you simply provide the value (the raw value, not the char_value) that you
   want to set the value to.  These are equivalent.
   >>> p.put(1.0)
   >>> p.value = 1.0
 
   It is often desirable to know when the put has completes (eg, when a motor is done 
   moving, when a counter is done counting, or more generally when a record and its forward
   links have fully processed).   There are two ways to do this:
 
   First, you can use the the 'wait=True' option in put():
   
   >>> put(1.0, wait=True, timeout=60.0)
   
   This will block until the put is complete or until the timeout (in seconds, and which
   has a default value of 3600.0) has expired.
      
   An alternative is to not block, but to poll from python until the PVs 'put_complete'
   attribute is set to True.
 
   >>> p.put(1.0,user_wait=True)
   >>> while not p.put_complete:
   >>>     pend_event()
   >>>     print 'still moving'
   
   This approach can be a bit more convenient for interactive codes.
   
== User Callbacks (monitors):
 
  Under normal operation of a program communicating with Epics, pend_event(), poll(), or
  pend_io() should be called periodically.
  
  When a PVs value on the host machine has changed, a pend_event() or poll() is the only way
  for the local application to know that the change has occurred.  When a variable changes
  and one of the polling routines is called, the internal value and attributes are
  automatically updated to the latest values.
 
  In addition, you can define one or more 'callback' routines to be run every time a PVs
  state is seen to change.  The callback routine(s) can be used to update GUI widgets,
  for example. 
   
  A callback can be specified at PV creation:
  >>>def my_callback(PV=None, **kws):
         print 'my callback ', PV.pvname, PV.value
 
  >>>p = EpicsCA.PV('XXX', callback=my_callback)
  
  See the closure class (in this module) for a convenient way to set a callback with
  arguments and keywords.
 
  **********  Important Note: **********
     callback functions will be called with the first argument 'PV' holding the
     PV object.
 
     You *must* have a 'PV' argument in your callback routine!!
  **********  Important Note: **********
  
  Additional callbacks can be added and removed at any time.  To do this, a dictionary of
  callbacks is maintained, each having an 'index' as a key.  If not specified, an index key
  will be created.  
 
  add_callback(self,callback=None,index=None,*args,**kws):
     set a user defined callback, returns  the index key for this callback.
 
  remove_callback(index=None):
      remove a callback given its index name
 
  clear_callbacks():
      clear all user-defined callbacks
 
  list_callbacks():
      returns a list of existing callbacks and their indices
      
  set_callback(callback=None,*args,**kws):
      set a callback, erasing all current callbacks.  This is included for backward
      compatibility -- normally, add_callback() should be used.
 
  **********  Recommendataion: **********
 
  Because the user-defined callbacks are really run from within a "pend_event()",
  it is not very useful to set other PVs and rely on them being changed (as the
  action  may not be noticable until later), or to run very extensive calculations.
 
  My recommendation is to use callbacks for doing little more than noting that
  a PV have changed, and then acting on that change after pend_event().  This can
  be especially true for GUI code, and explains much of the code in lib/wx.  
  
  A useful approach is to create a store of "changes", have pend_event()
  simply put information about the changes in that store, then have another
  routine which acts on the changes:
 
  changes = []
  def onEvent(pv=None, **kw):
      if pv is not None:
          changes.append((pv.pvname, pv.char_value, time.ctime())
 
  for pv in PVlist:
      pv.set_callback(callback=onEvent)
 
  def showChanges():
      while changes:
          name,cvalue,ctime = changes.pop()
          print 'PV  %s = %s at %s' % (name,cvalue,ctime)
 
  # main loop
  while True:
      pend_event()    # note PV changes
      showChanges()   # act on PV changes
 
  Methods defined here:
__copy__(self)
__deepcopy__(self, visit)
__eq__(self, other)
__ge__(self, other)
__getattr__(self, attr)
internal getting of attributes.
For many 'shadowed' values (those that should not be set),
this just retrieves the shadowed value.
 
When getting 'value' or 'char_value' here, a real get() is done.
__gt__(self, other)
__init__(self, pvname=None, callback=None, connect=False, connect_time=1.0, use_numpy=True, use_control=False, use_char_changes=True)
__le__(self, other)
__lt__(self, other)
__ne__(self, other)
__nonzero__(self)
__repr__(self)
__setattr__(self, attr, val)
internal setting of attributes.
Note that many attributes should not be set, and trying to set them will
raise an exception.
 
Important exceptions:
    setting a pvs 'value' will do a 'put()' for that value, really
    setting the Epics Value.
 
    setting a pvs 'pvname' will reconnect to the (possibly new) pv.
__str__(self)
add_callback(self, callback=None, index=None, *args, **kws)
set a user defined callback
clear_callbacks(self)
clear all user-defined callbacks
connect(self, force=False, connect_time=1.0)
connect a pv to the epics layer, or reconnect:
disconnect(self)
get(self, use_char=False, max_time=0.10000000000000001)
get(): returns a pvs value.
equivalent to accessing the 'value' attribute.
See also get_string() to  get the string representation.
 
Note that this relies on the 'get callback [see _get_callback() below]
to get the latest value.
 
max_time option sets max time to wait for complete connection if
the PV value is still None (uninitialized).
get_enum_strings(self)
return list of enumeration strings (can also access .enum_strings attribute)
get_info(self)
return list of strings containing an information paragraph about pv
list_callbacks(self)
return list of existing callbacks
poll(self)
check for connection, then pend_event: this is where the real action happens!
put(self, value, user_wait=False, wait=False, timeout=3600.0)
put a value, optionally waiting until the put is complete.
 
There are 2 options for how to wait for a 'put' to complete:
   -- blocking wait:
         pv.put(value, wait=True, timeout=3600.0)
      this approach will block until the put has completed    
      or until the supplied timeout (in seconds, default= 3600)
      has elapsed. Note that like all CA times, the timeout is
      approximate, and should be used as a clock.
 
      It is *intended* that the put can be interrupted with a
      Control-C interrupt.  This is not extensively tested on
      all platforms
 
   -- user wait:
         pv.put(value, user_wait=True)
         while not pv.put_complete:
             pv.poll()
             # any other code  
      in this approach, the put() call will return immediately,
      and the caller can then wait (or timeout, or fail) until
      pv.put_complete becomes True
remove_callback(self, index=None)
remove a callback given its index name
set_callback(self, callback=None, *args, **kws)
set a callback (for backward compatibility -- use 'add_callback')

Data and other attributes defined here:
MAX_STRING_LEN = 40
callback_ErrorMsg = 'severe error with get callback for %s'
connect_ErrorMsg = 'cannot connect to %s -- may need a connection timeout longer than %f seconds'
enumrange_ErrorMsg = 'value %i out of range for enum PV %s'
repr_Normal = "<PV: '%s', count=%i, type=%s, access=%s>"
repr_unconnected = "<PV '%s': unconnectd>"
repr_unnamed = '<PV: unnamed>'
setattr_ErrorMsg = 'cannot set %s for %s'