106 feature add setpoint check before applying strengths#126
Conversation
…int-check-before-applying-strengths
…int-check-before-applying-strengths
…int-check-before-applying-strengths
Used in case of application of values on magnet arrays.
|
@JeanLucPons , it's ready for review. |
|
OK Thanks.
|
|
It behaves very strangely ? import time
from pyaml.accelerator import Accelerator
sr = Accelerator.load("tests/config/EBSTune.yaml")
mag = sr.live.get_magnet("QD2E-C04").strength
print( mag.get() )
print( mag._RWStrengthScalar__dev )
mag.set(100)
time.sleep(10)
print( mag.get() )[ubuntu20acu.pons] > python tests/jlp_test.py
21 Jan% 2026, 15:53:04 | WARNING | PyAML Tango control system binding (0.3.2) initialized with name 'live' and TANGO_HOST=ebs-simu-2:10000
-0.6178546595342231
Attribute(attribute='//ebs-simu-2:10000/srmag/vps-qd2/c04-e/current', unit='A', range=None)
0.0No excpetion and the beam is lost !? |
Ok, I will remove the availability check and add the range check to the aggregators. |
|
OK I will double check, i might be confused by the fact the the range is "lazily" initialized. |
|
OK it works (I definitely forgot something) but I still do not know why it claims that the range is None ? [ubuntu20acu.pons] > python tests/jlp_test.py
22 Jan% 2026, 11:12:09 | WARNING | PyAML Tango control system binding (0.3.2) initialized with name 'live' and TANGO_HOST=ebs-simu-2:10000
-0.6178546595342231
Attribute(attribute='//ebs-simu-2:10000/srmag/vps-qd2/c04-e/current', unit='A', range=None)
Traceback (most recent call last):
File "/home/esrf/pons/pyaml/tests/jlp_test.py", line 9, in <module>
mag.set(-100)
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/control/abstract_impl.py", line 299, in set
raise PyAMLException(f"The values are out of range: {current}, {dev_range} for device {self.__dev}")
pyaml.common.exception.PyAMLException: The values are out of range: 110.0, [0.0, 108.0] for device Attribute(attribute='//ebs-simu-2:10000/srmag/vps-qd2/c04-e/current', unit='A', range=None) |
|
That range is the one defined in the YAML file. If you want it to be automatically filled, it would require fetching it from the device. Due to lazy instantiation, I don't think this is a good idea... |
|
OK. I think, you can use the _cfg field of the attached device (if not already filled by the conf) instead of creating a new range attribute but we can discuss this later in tango-pyaml. |
|
It should be ok now @JeanLucPons |
|
You have to test it with the matching tango-pyaml branch. |
|
The developpement for pyaml-cs-oa must be done once we agree on the final implementation. |
…int-check-before-applying-strengths
|
I'm sorry but i still do not manage to make it work :( from pyaml.accelerator import Accelerator
sr = Accelerator.load("tests/config/EBSTune-range.yaml")
mag = sr.live.get_magnets("QForTune").strengths
mag.set( mag.get()*1000.0 )Failed with: [ubuntu20acu.pons] > python tests/jlp_test.py
22 Jan% 2026, 15:39:21 | WARNING | Tango control system binding for PyAML initialized with name 'live' and TANGO_HOST=ebs-simu-2:10000
Traceback (most recent call last):
File "/home/esrf/pons/pyaml/tests/jlp_test.py", line 5, in <module>
mag.set( mag.get()*1000.0 )
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/arrays/magnet_array.py", line 30, in set
self.__aggregator.set(nvalue)
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/control/abstract_impl.py", line 173, in set
self._devs.set(newHardwareValues)
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/tango/pyaml/multi_attribute.py", line 85, in set
self[index]._attribute_dev.write_attribute_reply(call_id, timeout)
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/tango/green.py", line 231, in greener
return executor.run(fn, args, kwargs, wait=wait, timeout=timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/tango/green.py", line 121, in run
return fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/tango/device_proxy.py", line 1042, in __DeviceProxy__write_attribute_reply
return __write_attributes_reply__(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/tango/device_proxy.py", line 953, in __write_attributes_reply__
return self.__write_attributes_reply(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tango._tango.DevFailed: DevFailed[
DevError[
desc = Failed to execute DeviceProxy::write_attributes_reply() on device srmag/vps-qd2/c04-e, object(s) Current
origin = DeviceProxy::write_attributes_reply()
reason = API_AttributeFailed
severity = ERR
]
]which is the buggy error we get when the Tango PS return an error, see here Here is my tune file: type: pyaml.accelerator
facility: ESRF
machine: sr
energy: 6e9
simulators:
- type: pyaml.lattice.simulator
lattice: sr/lattices/ebs.mat
name: design
controls:
- type: tango.pyaml.controlsystem
tango_host: ebs-simu-2:10000
name: live
data_folder: /data/store
arrays:
- type: pyaml.arrays.magnet
name: QForTune
elements:
- QD2E-C04
- QD2A-C05
- QD2E-C05
- QD2A-C06
- QD2E-C06
- ...
devices:
- type: pyaml.magnet.quadrupole
name: QF1E-C04
model:
type: pyaml.magnet.linear_model
calibration_factor: 1.00054
crosstalk: 1.0
curve:
type: pyaml.configuration.csvcurve
file: sr/magnet_models/QF1_strength.csv
unit: 1/m
powerconverter:
type: tango.pyaml.attribute
attribute: srmag/vps-qf1/c04-e/current
range: [10,109]
unit: A
- type: pyaml.magnet.quadrupole
name: QF1A-C05
model:
type: pyaml.magnet.linear_model
calibration_factor: 0.996841
crosstalk: 1.0
curve:
type: pyaml.configuration.csvcurve
file: sr/magnet_models/QF1_strength.csv
unit: 1/m
powerconverter:
type: tango.pyaml.attribute
attribute: srmag/vps-qf1/c05-a/current
range: [10,109]
unit: A
... |
|
In control/abstract_impl.py : dev_range = self._devs.get_range()
print(newHardwareValues)
print(dev_range)
if not check_range(newHardwareValues, dev_range):
raise PyAMLException(f"The values are out of range: {newHardwareValues}, {dev_range} for device {self._devs}")outputs [110. 110. 110. 110. 110. 110. 110. 110. 110. 110. 110. 110. 110. 110. hardware setpoints are the one expected. |
|
I've turn your case into a test. It works. I've done a minor change due to the improvement in the dummy CS but nothing critical. |
|
The exception (simplified), before I handle it as a valid result for the test: @pytest.mark.parametrize( tests/test_range_array.py:15 Traceback (most recent call last): newHardwareValues: dev_range (flat list of bounds, min/max pairs): device list (DeviceAccessList): |
|
Still failing. [ubuntu20acu.pons] > python tests/jlp_test.py
22 Jan% 2026, 16:51:51 | WARNING | Tango control system binding for PyAML initialized with name 'live' and TANGO_HOST=ebs-simu-3:10000
Traceback (most recent call last):
File "/home/esrf/pons/pyaml/tests/jlp_test.py", line 5, in <module>
mag.set( mag.get()*1000.0 )
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/arrays/magnet_array.py", line 30, in set
self.__aggregator.set(nvalue)
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/control/abstract_impl.py", line 168, in set
if not check_range(newHardwareValues, dev_range):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/operation/common/miniconda/envs/jlp-py312/lib/python3.12/site-packages/pyaml/control/abstract_impl.py", line 48, in check_range
raise ValueError(f"dev_range must have an even length, got {r.size}")
ValueError: dev_range must have an even length, got 1 |
|
Ok, it's strange. The error is in the implementation. get_range() returns None instead of an array. Even an array of None is ok but it must be an array with a correct number of elements. |
|
OK it is better i was in branch 25. Still this ? def set(self, value: float):
available = self.__dev.check_device_availability()
if not available: |
I missed this one. |
|
It should be ok now. |
|
For me it is fine for now on the pyaml side. tango-pyaml pyaml-cs-oa It would be good to list out of range values according to their respective range and device. i.e. |
|
I agree, it requires another function to build a beautiful error message. I will do it now; it won’t take long, and the required tests are already there. |
|
I let you do a last review and it should be ok for merge. |
|
OK it is fine. Thanks. |
|
May be you can update the version number as well. |
Ok, has there is no interface breaks, i'll update only the patch number. |



Description
DeviceAccess can provide a range of acceptable values.
Related Issue
Closes #106
Features/issues described there are: