Subject: |
Re: EPICS Python client application survey |
From: |
Michael Abbott <[email protected]> |
To: |
EPICS Tech Talk <[email protected]> |
Date: |
Thu, 1 Oct 2009 15:01:02 +0100 (BST) |
On Thu, 1 Oct 2009, Michael Abbott wrote:
> On Wed, 30 Sep 2009, Andrew Johnson wrote:
> > I would encourage those working on this to read the release notes for
> > R3.14.11 as there are a couple of things we added which you guys are
> > going to want to provide support for:
>
> > * Long strings. Important for accessing DBF_xxLINK fields since record
> > names can be up to 60 characters long, so you can't always read or
> > change the value of a link field using a 40 character DBF_STRING.
So implementing this for caget/camonitor seems to be easy, the following
patch against cothread 1-14 seems to do the trick. If anyone with a .11
server to hand fancies giving a go I'd be grateful; it seems to work ok
for me.
--- cothread/dbr.py (revision 36209)
+++ cothread/dbr.py (working copy)
@@ -595,7 +595,10 @@
dbr_type = DbrCodeToType[datatype]
raw_dbr = ctypes.cast(raw_dbr, ctypes.POINTER(dbr_type))[0]
- if count == 1:
+ if name[-1] =='$' and raw_dbr.dtype is numpy.uint8:
+ # Special case hack for long strings returned as DBR_CHAR arrays.
+ result = ca_str(ctypes.string_at(raw_dbr.raw_value))
+ elif count == 1:
# Single scalar values can be created directly from the raw value
result = raw_dbr.raw_value[0]
if dbr_type.dtype is str_dtype:
> 6. Does this also work in the same way for caput? I'm guessing so.
This one is a bit nastier because in cothread.catools the DBR_ coding for
caput is entirely determined by the Python data type, so I normally never
look at the field type ... and it looks like converting a string into a
numpy array is a lot clunkier than I'd like. But this patch should apply
against 1-14; I'll clean it up and restructure a little for 1-15.
--- cothread/catools.py (revision 36223)
+++ cothread/catools.py (working copy)
@@ -49,6 +49,7 @@
import sys
import atexit
import traceback
+import numpy
import cothread
from cadef import *
@@ -686,7 +687,13 @@
channel.Wait(timeout)
# Assemble the data in the appropriate format.
+ if pv[-1] == '$' and isinstance(value, str) and \
+ ca_field_type(channel) == DBR_CHAR:
+ # Tricky hack for long strings on 3.14.11 and above servers: send
+ # strings to PVs ending in $ as char arrays.
+ value = numpy.array(map(ord, value + '\0'), dtype = numpy.uint8)
datatype, count, dbr_array = value_to_dbr(value)
+
if wait:
# Assemble the callback context and give it an extra reference count
# to keep it alive until the callback handler sees it.
As a first stab, it seems to work just fine against a .11-pre server.
Disappointed to answer one of my earlier questions: have to request
PV_NAME.VAL$, as PV_NAME$ doesn't work, however I'm sure that's not very
important.
Regarding my null termination question, the answer seems to be that
strings *are* null terminated; this probably needs to be explicitly stated
somewhere!
- References:
- Re: EPICS Python client application survey Matt Newville
- Re: EPICS Python client application survey Benjamin Franksen
- Re: EPICS Python client application survey Andrew Johnson
- Re: EPICS Python client application survey Michael Abbott
- Navigate by Date:
- Prev:
Re: EPICS Python client application survey Benjamin Franksen
- Next:
Re: EPICS Python client application survey Andrew Johnson
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: EPICS Python client application survey Benjamin Franksen
- Next:
Re: EPICS Python client application survey Andrew Johnson
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|