Skip to content

Commit dc0b462

Browse files
committed
'readback_value' in scan settings
1 parent eab7795 commit dc0b462

2 files changed

Lines changed: 37 additions & 9 deletions

File tree

Test/test_scan_settings.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@ def __init__(self):
1818
# Define special settings for some devices
1919
# Temperature controller uses completion, but no readback
2020
self.defineDeviceClass("My:Lakeshore.*", completion=True, readback=False, timeout=300, tolerance=10)
21+
2122
# Motor uses completion and readback (with special readback name, see below)
2223
self.defineDeviceClass("My:Motor.*", completion=True, readback=True, timeout=100)
23-
# Counter comared by increment, not absolute value
24+
25+
# Counter compared by increment, not absolute value
2426
self.defineDeviceClass("PerpetualCounter", comparison='increase by')
27+
28+
# Device where you may write '5', but then check for Status=="OK"
29+
self.defineDeviceClass("DeviceWithStatus", completion=True, readback="Status", readback_value="OK", tolerance=0)
30+
2531

2632
def getReadbackName(self, device_name):
2733
# Motors use their *.RBV field for readback
@@ -153,6 +159,9 @@ def testSettingsBasedSet(self):
153159
cmd = SettingsBasedSet('Unknown:Motor1', 42, readback=False)
154160
self.assertEquals(str(cmd), "Set('Unknown:Motor1', 42)")
155161

162+
cmd = SettingsBasedSet('DeviceWithStatus', 5)
163+
self.assertEquals(str(cmd), "Set('DeviceWithStatus', 5, completion=True, readback='Status', readback_value='OK')")
164+
156165

157166
def testSettingsBasedLoop(self):
158167
setScanSettings(MyScanSettings())

scan/util/scan_settings.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,20 @@ class DeviceSettings(object):
5353
:param readback: False to not use a readback,
5454
True to use the primary name,
5555
Actual read back name if different from the promary device name.
56+
:param readback_value: None to check against written value, otherwise custom readback number or string value.
5657
:param timeout: Time out for callback and readback in seconds. 0 to wait forever.
5758
:param tolerance: Tolerance for numeric readback comparison.
5859
:param comparison: Comparison to use in Wait commands
5960
:param parallel: Perform in parallel?
6061
"""
61-
def __init__(self, name, completion=False, readback=False, timeout=0.0, tolerance=None, comparison='>=', parallel=False):
62+
def __init__(self, name, completion=False, readback=False, readback_value=None, timeout=0.0, tolerance=None, comparison='>=', parallel=False):
6263
self._name = name
6364
self._completion = completion
6465
self._readback = readback
66+
if isinstance(readback_value, str) and len(readback_value) <= 0:
67+
self._readback_value = None
68+
else:
69+
self._readback_value = readback_value
6570
self._timeout = timeout
6671
self._tolerance = tolerance
6772
self._comparison = comparison
@@ -81,6 +86,10 @@ def getReadback(self):
8186
return None
8287
return self._name if self._readback == True else self._readback
8388

89+
def getReadbackValue(self):
90+
""":returns: None to check against written value, otherwise custom readback number or string value."""
91+
return self._readback_value
92+
8493
def getTimeout(self):
8594
""":returns: Timeout in seconds for both completion and readback."""
8695
return self._timeout
@@ -101,8 +110,13 @@ def __repr__(self):
101110
rb = self.getReadback()
102111
if rb:
103112
rb = "'" + rb + "'"
104-
return "DeviceSettings('%s', completion=%s, readback=%s, timeout=%g, tolerance=%s, comparison='%s', parallel=%s)" % (
105-
self._name, str(self._completion), rb, self._timeout, str(self._tolerance), self._comparison, str(self._parallel))
113+
114+
rbv = self._readback_value
115+
if isinstance(rbv, str):
116+
rbv = "'" + rbv + "'"
117+
118+
return "DeviceSettings('%s', completion=%s, readback=%s, readback_value=%s, timeout=%g, tolerance=%s, comparison='%s', parallel=%s)" % (
119+
self._name, str(self._completion), rb, rbv, self._timeout, str(self._tolerance), self._comparison, str(self._parallel))
106120

107121

108122

@@ -145,6 +159,7 @@ def loadDeviceClasses(self, json_filename):
145159
self.defineDeviceClass(dev.encode('ascii'),
146160
completion=attr.get('completion', False),
147161
readback=f(attr.get('readback', False)),
162+
readback_value=f(attr.get('readback_value', "")),
148163
timeout=attr.get('timeout', 0.0),
149164
tolerance=attr.get('tolerance', 0.0),
150165
comparison=attr.get('comparison', ">=")
@@ -167,7 +182,7 @@ def getReadbackName(self, device_name):
167182

168183
return device_name
169184

170-
def defineDeviceClass(self, name_pattern, completion=False, readback=False, timeout=0.0, tolerance=None, comparison='>='):
185+
def defineDeviceClass(self, name_pattern, completion=False, readback=False, readback_value=None, timeout=0.0, tolerance=None, comparison='>='):
171186
"""Define a class of devices based on name
172187
173188
Call this in the constructor of your derived class.
@@ -182,11 +197,12 @@ def defineDeviceClass(self, name_pattern, completion=False, readback=False, time
182197
:param readback: False to not use a readback,
183198
True to use the primary name,
184199
Actual read back name if different from the promary device name.
200+
:param readback_value: None to check against written value, otherwise custom readback number or string value.
185201
:param timeout: Time out for callback and readback in seconds. 0 to wait forever.
186202
:param tolerance: Tolerance for numeric readback comparison.
187203
:param comparison: Comparison to use in Wait commands.
188204
"""
189-
self.device_settings.insert(0, DeviceSettings(name_pattern, completion, readback, timeout, tolerance, comparison))
205+
self.device_settings.insert(0, DeviceSettings(name_pattern, completion=completion, readback=readback, readback_value=readback_value, timeout=timeout, tolerance=tolerance, comparison=comparison))
190206

191207
def getDefaultSettings(self, name):
192208
"""Get the default settings for a device
@@ -203,7 +219,7 @@ def getDefaultSettings(self, name):
203219
rb = setting._readback
204220
if rb == True:
205221
rb = self.getReadbackName(name)
206-
return DeviceSettings(name, setting.getCompletion(), rb, setting.getTimeout(), setting.getTolerance(), setting.getComparison())
222+
return DeviceSettings(name, completion=setting.getCompletion(), readback=rb, readback_value=setting.getReadbackValue(), timeout=setting.getTimeout(), tolerance=setting.getTolerance(), comparison=setting.getComparison())
207223
return DeviceSettings(name)
208224

209225
def parseDeviceSettings(self, prefixed_device):
@@ -265,7 +281,8 @@ def parseDeviceSettings(self, prefixed_device):
265281
if readback == True:
266282
readback = device
267283

268-
return DeviceSettings(default.getName(), completion=completion, readback=readback, timeout=default.getTimeout(), tolerance=default.getTolerance(),
284+
return DeviceSettings(default.getName(), completion=completion, readback=readback, readback_value=default.getReadbackValue(),
285+
timeout=default.getTimeout(), tolerance=default.getTolerance(),
269286
comparison=default.getComparison(), parallel=parallel)
270287

271288
def __str__(self):
@@ -298,13 +315,15 @@ def SettingsBasedSet(prefixed_device, value, **kwargs):
298315
:param readback: `False` to not check any readback,
299316
`True` to wait for readback from the `device`,
300317
or name of specific device to check for readback.
318+
:param readback_value: None to check against written value, otherwise custom readback number or string value.
301319
:param tolerance: Tolerance when checking numeric `readback`.
302320
:param timeout: Timeout in seconds, used for `completion` and `readback`.
303321
:param errhandler: Error handler
304322
"""
305323
settings = __scan_settings.parseDeviceSettings(prefixed_device)
306324
completion = kwargs['completion'] if 'completion' in kwargs else settings.getCompletion()
307325
readback = kwargs['readback'] if 'readback' in kwargs else settings.getReadback()
326+
readback_value = kwargs['readback_value'] if 'readback_value' in kwargs else settings.getReadbackValue()
308327
tolerance = kwargs['tolerance'] if 'tolerance' in kwargs else settings.getTolerance()
309328
timeout = kwargs['timeout'] if 'timeout' in kwargs else settings.getTimeout()
310329
errhandler = kwargs['errhandler'] if 'errhandler' in kwargs else None
@@ -313,7 +332,7 @@ def SettingsBasedSet(prefixed_device, value, **kwargs):
313332
tolerance = 0.1
314333

315334
return Set(settings.getName(), value,
316-
completion=completion, readback=readback, tolerance=tolerance, timeout=timeout, errhandler=errhandler)
335+
completion=completion, readback=readback, readback_value=readback_value, tolerance=tolerance, timeout=timeout, errhandler=errhandler)
317336

318337
def SettingsBasedLoop(prefixed_device, start, end, step, body=None, *args, **kwargs):
319338
"""Set a device to various values in a loop.

0 commit comments

Comments
 (0)