From 7653fafcd2b4e802bcb04e0b5d9f9f3d86fd969c Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Wed, 1 Feb 2023 18:50:22 +0100 Subject: [PATCH 01/11] Rename file. --- pymeasure/instruments/oxfordinstruments/__init__.py | 1 - pymeasure/instruments/oxfordinstruments/{adapters.py => base.py} | 0 2 files changed, 1 deletion(-) rename pymeasure/instruments/oxfordinstruments/{adapters.py => base.py} (100%) diff --git a/pymeasure/instruments/oxfordinstruments/__init__.py b/pymeasure/instruments/oxfordinstruments/__init__.py index db4d8e9c18..7a9fc988c1 100644 --- a/pymeasure/instruments/oxfordinstruments/__init__.py +++ b/pymeasure/instruments/oxfordinstruments/__init__.py @@ -23,7 +23,6 @@ # -from .adapters import OxfordInstrumentsAdapter from .itc503 import ITC503 from .ips120_10 import IPS120_10 from .ps120_10 import PS120_10 diff --git a/pymeasure/instruments/oxfordinstruments/adapters.py b/pymeasure/instruments/oxfordinstruments/base.py similarity index 100% rename from pymeasure/instruments/oxfordinstruments/adapters.py rename to pymeasure/instruments/oxfordinstruments/base.py From 6c456daccd3c3e0a8962d7dfb28354aeb1785218 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Wed, 1 Feb 2023 19:20:55 +0100 Subject: [PATCH 02/11] Oxford adapter removed. --- .../instruments/oxfordinstruments/base.py | 47 ++++++++++++++----- .../oxfordinstruments/ips120_10.py | 21 ++------- .../instruments/oxfordinstruments/itc503.py | 21 ++------- 3 files changed, 42 insertions(+), 47 deletions(-) diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index bbfe94314e..b9a5cd01b8 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -23,7 +23,7 @@ # -from pymeasure.adapters import VISAAdapter +from pymeasure.instruments import Instrument from pyvisa.errors import VisaIOError import re @@ -38,25 +38,47 @@ class OxfordVISAError(Exception): pass -class OxfordInstrumentsAdapter(VISAAdapter): - """Adapter class for the VISA library using PyVISA to communicate - with instruments. +class OxfordInstrumentsBase(Instrument): + """Base instrument for devices from Oxford Instruments. + Checks the replies from instruments for validity. - :param resource_name: VISA resource name that identifies the address + :param adapter: A string, integer, or :py:class:`~pymeasure.adapters.Adapter` subclass object + :param string name: The name of the instrument. Often the model designation by default. :param max_attempts: Integer that sets how many attempts at getting a valid response to a query can be made - :param kwargs: key-word arguments for constructing a PyVISA Adapter + :param \\**kwargs: In case ``adapter`` is a string or integer, additional arguments passed on + to :py:class:`~pymeasure.adapters.VISAAdapter` (check there for details). + Discarded otherwise. """ timeoutError = VisaIOError(-1073807339) regex_pattern = r"^([a-zA-Z])[\d.+-]*$" - def __init__(self, resource_name, max_attempts=5, **kwargs): - super().__init__(resource_name, **kwargs) + def __init__(self, adapter, name="OxfordInstruments Base", max_attempts=5, **kwargs): + kwargs.setdefault('read_termination', '\r') + + super().__init__(adapter, + name=name, + includeSCPI=False, + asrl={ + 'baud_rate': 9600, + 'data_bits': 8, + 'parity': 0, + 'stop_bits': 20, + }, + **kwargs) self.max_attempts = max_attempts + def values(self, command, separator=',', cast=float, preprocess_reply=lambda v: v[1:], maxsplit=-1, + **kwargs): + """Write a command and get values.""" + return super().values(command, separator=separator, cast=cast, + preprocess_reply=preprocess_reply, + maxsplit=maxsplit, + **kwargs) + def ask(self, command): """Write the command to the instrument and return the resulting ASCII response. Also check the validity of the response before returning it; if the response is not valid, another @@ -72,7 +94,10 @@ def ask(self, command): """ for attempt in range(self.max_attempts): - response = super().ask(command) + # Skip the checks in "write" + super().write(command) + self.wait_for() + response = self.read() if self.is_valid_response(response, command): return response @@ -92,7 +117,7 @@ def ask(self, command): raise OxfordVISAError(f"Retried {self.max_attempts} times without getting a valid " "response, maybe there is something worse at hand.") - def _write(self, command): + def write(self, command): """Write command to instrument and check whether the reply indicates that the given command was not understood. The devices from Oxford Instruments reply with '?xxx' to a command 'xxx' if this command is @@ -103,7 +128,7 @@ def _write(self, command): :raises: :class:`~.OxfordVISAError` if the instrument does not recognise the supplied command or if the response of the instrument is not understood """ - super()._write(command) + super().write(command) if not command[0] == "$": response = self.read() diff --git a/pymeasure/instruments/oxfordinstruments/ips120_10.py b/pymeasure/instruments/oxfordinstruments/ips120_10.py index 8914800da3..83957f40a8 100644 --- a/pymeasure/instruments/oxfordinstruments/ips120_10.py +++ b/pymeasure/instruments/oxfordinstruments/ips120_10.py @@ -30,7 +30,7 @@ from pymeasure.instruments.validators import strict_discrete_set from pymeasure.instruments.validators import truncated_range -from .adapters import OxfordInstrumentsAdapter +from .base import OxfordInstrumentsBase # Setup logging log = logging.getLogger(__name__) @@ -47,7 +47,7 @@ class SwitchHeaterError(ValueError): pass -class IPS120_10(Instrument): +class IPS120_10(OxfordInstrumentsBase): """Represents the Oxford Superconducting Magnet Power Supply IPS 120-10. .. code-block:: python @@ -116,25 +116,10 @@ def __init__(self, field_range=None, **kwargs): - if isinstance(adapter, (int, str)): - kwargs.setdefault('read_termination', '\r') - kwargs.setdefault('send_end', True) - adapter = OxfordInstrumentsAdapter( - adapter, - asrl={ - 'baud_rate': 9600, - 'data_bits': 8, - 'parity': 0, - 'stop_bits': 20, - }, - preprocess_reply=lambda v: v[1:], - **kwargs, - ) - super().__init__( adapter=adapter, name=name, - includeSCPI=False, + **kwargs ) if switch_heater_heating_delay is not None: diff --git a/pymeasure/instruments/oxfordinstruments/itc503.py b/pymeasure/instruments/oxfordinstruments/itc503.py index beaab0c26f..495dc10fd6 100644 --- a/pymeasure/instruments/oxfordinstruments/itc503.py +++ b/pymeasure/instruments/oxfordinstruments/itc503.py @@ -32,7 +32,7 @@ from pymeasure.instruments.validators import strict_discrete_set, \ truncated_range, strict_range -from .adapters import OxfordInstrumentsAdapter +from .base import OxfordInstrumentsBase # Setup logging @@ -58,7 +58,7 @@ def pointer_validator(value, values): return tuple(strict_range(v, values) for v in value) -class ITC503(Instrument): +class ITC503(OxfordInstrumentsBase): """Represents the Oxford Intelligent Temperature Controller 503. .. code-block:: python @@ -84,25 +84,10 @@ def __init__(self, max_temperature=1677.7, **kwargs): - if isinstance(adapter, (int, str)): - kwargs.setdefault('read_termination', '\r') - kwargs.setdefault('send_end', True) - adapter = OxfordInstrumentsAdapter( - adapter, - asrl={ - 'baud_rate': 9600, - 'data_bits': 8, - 'parity': 0, - 'stop_bits': 20, - }, - preprocess_reply=lambda v: v[1:], - **kwargs, - ) - super().__init__( adapter=adapter, name=name, - includeSCPI=False, + **kwargs, ) # Clear the buffer in order to prevent communication problems From 46238d85d49312e4d497ffd7ecaa3882cb5a843d Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Wed, 1 Feb 2023 19:30:17 +0100 Subject: [PATCH 03/11] Documentation adjusted. Closes #842 --- docs/api/instruments/oxfordinstruments/adapters.rst | 11 ----------- docs/api/instruments/oxfordinstruments/base.rst | 11 +++++++++++ docs/api/instruments/oxfordinstruments/index.rst | 2 +- pymeasure/instruments/oxfordinstruments/base.py | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 docs/api/instruments/oxfordinstruments/adapters.rst create mode 100644 docs/api/instruments/oxfordinstruments/base.rst diff --git a/docs/api/instruments/oxfordinstruments/adapters.rst b/docs/api/instruments/oxfordinstruments/adapters.rst deleted file mode 100644 index 1ad8031e29..0000000000 --- a/docs/api/instruments/oxfordinstruments/adapters.rst +++ /dev/null @@ -1,11 +0,0 @@ -############################### -Oxford Instruments VISA Adapter -############################### - -.. autoclass:: pymeasure.instruments.oxfordinstruments.OxfordInstrumentsAdapter - :members: - :show-inheritance: - -.. autoclass:: pymeasure.instruments.oxfordinstruments.adapters.OxfordVISAError - :members: - :show-inheritance: diff --git a/docs/api/instruments/oxfordinstruments/base.rst b/docs/api/instruments/oxfordinstruments/base.rst new file mode 100644 index 0000000000..59da2dcc51 --- /dev/null +++ b/docs/api/instruments/oxfordinstruments/base.rst @@ -0,0 +1,11 @@ +################################## +Oxford Instruments Base Instrument +################################## + +.. autoclass:: pymeasure.instruments.oxfordinstruments.base.OxfordInstrumentsBase + :members: + :show-inheritance: + +.. autoclass:: pymeasure.instruments.oxfordinstruments.base.OxfordVISAError + :members: + :show-inheritance: diff --git a/docs/api/instruments/oxfordinstruments/index.rst b/docs/api/instruments/oxfordinstruments/index.rst index 6f86e1be88..a215bb4b62 100644 --- a/docs/api/instruments/oxfordinstruments/index.rst +++ b/docs/api/instruments/oxfordinstruments/index.rst @@ -9,7 +9,7 @@ This section contains specific documentation on the Oxford Instruments instrumen .. toctree:: :maxdepth: 2 - adapters + base ITC503 IPS120_10 PS120_10 diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index b9a5cd01b8..07d089e45f 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -71,8 +71,8 @@ def __init__(self, adapter, name="OxfordInstruments Base", max_attempts=5, **kwa **kwargs) self.max_attempts = max_attempts - def values(self, command, separator=',', cast=float, preprocess_reply=lambda v: v[1:], maxsplit=-1, - **kwargs): + def values(self, command, separator=',', cast=float, preprocess_reply=lambda v: v[1:], + maxsplit=-1, **kwargs): """Write a command and get values.""" return super().values(command, separator=separator, cast=cast, preprocess_reply=preprocess_reply, From 51a5e603e957ee21e989724c66f8b4d2bb8b3bc8 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Wed, 8 Feb 2023 09:24:16 +0100 Subject: [PATCH 04/11] Using visa constants Co-authored-by: Benjamin Klebel-Knobloch <32774645+bklebel@users.noreply.github.com> --- pymeasure/instruments/oxfordinstruments/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index 07d089e45f..3932e01489 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -25,7 +25,7 @@ from pymeasure.instruments import Instrument from pyvisa.errors import VisaIOError - +from pyvisa import constants as vconst import re import logging @@ -65,8 +65,8 @@ def __init__(self, adapter, name="OxfordInstruments Base", max_attempts=5, **kwa asrl={ 'baud_rate': 9600, 'data_bits': 8, - 'parity': 0, - 'stop_bits': 20, + 'parity': vconst.Parity.none, + 'stop_bits': vconst.StopBits.two, }, **kwargs) self.max_attempts = max_attempts From 2ed86287cf819f236680340d399f463a5724827c Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Wed, 8 Feb 2023 09:29:40 +0100 Subject: [PATCH 05/11] Fix PS120_10 get process. --- pymeasure/instruments/oxfordinstruments/ps120_10.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymeasure/instruments/oxfordinstruments/ps120_10.py b/pymeasure/instruments/oxfordinstruments/ps120_10.py index d11d4c65a0..206fcb348f 100644 --- a/pymeasure/instruments/oxfordinstruments/ps120_10.py +++ b/pymeasure/instruments/oxfordinstruments/ps120_10.py @@ -27,12 +27,12 @@ def PS_custom_get_process(v): - """convert string to proper float value, for working with the PS 120-10 """ - return float(v[1:]) * 1e-2 + """Adjust the received value, for working with the PS 120-10 """ + return v * 1e-2 def PS_custom_set_process(v): - """convert float to proper int value, for working with the PS 120-10 """ + """Convert float to proper int value, for working with the PS 120-10 """ return int(v * 1e2) From a296d8baa1e58fd83ff94d0a6da0fb2aa5ae0d07 Mon Sep 17 00:00:00 2001 From: Benjamin Klebel <32774645+bklebel@users.noreply.github.com> Date: Fri, 24 Feb 2023 11:41:10 +0100 Subject: [PATCH 06/11] debugging --- pymeasure/instruments/oxfordinstruments/ps120_10.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymeasure/instruments/oxfordinstruments/ps120_10.py b/pymeasure/instruments/oxfordinstruments/ps120_10.py index d11d4c65a0..90a783baeb 100644 --- a/pymeasure/instruments/oxfordinstruments/ps120_10.py +++ b/pymeasure/instruments/oxfordinstruments/ps120_10.py @@ -100,12 +100,12 @@ def __init__(self, current_setpoint_get_process = PS_custom_get_process current_setpoint_set_process = PS_custom_set_process - current_setpoint_set_command = "J%d" + current_setpoint_set_command = "I%d" field_setpoint_get_process = PS_custom_get_process field_setpoint_set_process = PS_custom_set_process - field_setpoint_set_command = "T%d" + field_setpoint_set_command = "J%d" sweep_rate_get_process = PS_custom_get_process sweep_rate_set_process = PS_custom_set_process - sweep_rate_set_command = "A%d" + sweep_rate_set_command = "T%d" From 99aff19c5a7e85871a0af84cf74dee7591cf1234 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:17:14 +0100 Subject: [PATCH 07/11] Tests added. --- .../instruments/oxfordinstruments/base.py | 2 +- .../oxfordinstruments/test_base_instrument.py | 39 +++++++++ .../oxfordinstruments/test_ips120_10.py | 80 +++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 tests/instruments/oxfordinstruments/test_base_instrument.py create mode 100644 tests/instruments/oxfordinstruments/test_ips120_10.py diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index 3932e01489..c7bd96d019 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -183,4 +183,4 @@ def is_valid_response(self, response, command): return bool(match) def __repr__(self): - return "" % self.connection.resource_name + return "" % self.adapter.connection.resource_name diff --git a/tests/instruments/oxfordinstruments/test_base_instrument.py b/tests/instruments/oxfordinstruments/test_base_instrument.py new file mode 100644 index 0000000000..0aa9497c3c --- /dev/null +++ b/tests/instruments/oxfordinstruments/test_base_instrument.py @@ -0,0 +1,39 @@ +# +# This file is part of the PyMeasure package. +# +# Copyright (c) 2013-2023 PyMeasure Developers +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +import pytest + +from pymeasure.test import expected_protocol + + +from pymeasure.instruments.oxfordinstruments.base import OxfordInstrumentsBase, OxfordVISAError + + +def test_wrong_response(): + with expected_protocol(OxfordInstrumentsBase, + [("A", "B"), (None, "")], + max_attempts=1, + ) as inst: + with pytest.raises(OxfordVISAError): + inst.ask("A") diff --git a/tests/instruments/oxfordinstruments/test_ips120_10.py b/tests/instruments/oxfordinstruments/test_ips120_10.py new file mode 100644 index 0000000000..06fe6bb1c0 --- /dev/null +++ b/tests/instruments/oxfordinstruments/test_ips120_10.py @@ -0,0 +1,80 @@ +# +# This file is part of the PyMeasure package. +# +# Copyright (c) 2013-2023 PyMeasure Developers +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +import pytest + +from pymeasure.test import expected_protocol + + +from pymeasure.instruments.oxfordinstruments.ips120_10 import IPS120_10 + + +def test_version(): + with expected_protocol(IPS120_10, + [("V", "IPS120-10 Version 3.04 @ Oxford Instruments 1996")] + ) as inst: + assert inst.version == "IPS120-10 Version 3.04 @ Oxford Instruments 1996" + + +def test_activity_getter(): + with expected_protocol(IPS120_10, + [("X", "X00A0C0M00P00")] + ) as inst: + assert inst.activity == "hold" + + +def test_activity_setter(): + with expected_protocol(IPS120_10, + [("A0", "A")] + ) as inst: + inst.activity = "hold" + + +@pytest.mark.xfail() # TODO this test fails, the correct response has to be added. +def test_current_setpoint_getter(): + with expected_protocol(IPS120_10, + [("R0", "R1.3")] + ) as inst: + assert inst.current_setpoint == 1.3 + + +def test_current_setpoint_setter(): + with expected_protocol(IPS120_10, + [("I1.300000", "I")] + ) as inst: + inst.current_setpoint = 1.3 + + +def test_control_mode_getter(): + with expected_protocol(IPS120_10, + [("X", "X00A0C1M00P00")] + ) as inst: + assert inst.control_mode == "RL" + + +def test_control_mode_setter(): + with expected_protocol(IPS120_10, + [("C1", "C")] + ) as inst: + inst.control_mode = "RL" From 819a790f21b691f715289fcd345269cc7f15bcad Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:22:07 +0100 Subject: [PATCH 08/11] Tests for PS120 added. --- .../oxfordinstruments/test_ips120_10.py | 2 +- .../oxfordinstruments/test_ps120_10.py | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/instruments/oxfordinstruments/test_ps120_10.py diff --git a/tests/instruments/oxfordinstruments/test_ips120_10.py b/tests/instruments/oxfordinstruments/test_ips120_10.py index 06fe6bb1c0..d7f8b30dbf 100644 --- a/tests/instruments/oxfordinstruments/test_ips120_10.py +++ b/tests/instruments/oxfordinstruments/test_ips120_10.py @@ -54,7 +54,7 @@ def test_activity_setter(): @pytest.mark.xfail() # TODO this test fails, the correct response has to be added. def test_current_setpoint_getter(): with expected_protocol(IPS120_10, - [("R0", "R1.3")] + [("R0", "R+1.3")] ) as inst: assert inst.current_setpoint == 1.3 diff --git a/tests/instruments/oxfordinstruments/test_ps120_10.py b/tests/instruments/oxfordinstruments/test_ps120_10.py new file mode 100644 index 0000000000..f0d3139c5b --- /dev/null +++ b/tests/instruments/oxfordinstruments/test_ps120_10.py @@ -0,0 +1,80 @@ +# +# This file is part of the PyMeasure package. +# +# Copyright (c) 2013-2023 PyMeasure Developers +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +import pytest + +from pymeasure.test import expected_protocol + + +from pymeasure.instruments.oxfordinstruments.ps120_10 import PS120_10 + + +def test_version(): + with expected_protocol(PS120_10, + [("V", "IPS120-10 Version 3.04 @ Oxford Instruments 1996")] + ) as inst: + assert inst.version == "IPS120-10 Version 3.04 @ Oxford Instruments 1996" + + +def test_activity_getter(): + with expected_protocol(PS120_10, + [("X", "X00A0C0M00P00")] + ) as inst: + assert inst.activity == "hold" + + +def test_activity_setter(): + with expected_protocol(PS120_10, + [("A0", "A")] + ) as inst: + inst.activity = "hold" + + +@pytest.mark.xfail() # TODO this test fails, the correct response has to be added. +def test_current_setpoint_getter(): + with expected_protocol(PS120_10, + [("R0", "R+130")] + ) as inst: + assert inst.current_setpoint == 1.3 + + +def test_current_setpoint_setter(): + with expected_protocol(PS120_10, + [("I130", "I")] + ) as inst: + inst.current_setpoint = 1.3 + + +def test_control_mode_getter(): + with expected_protocol(PS120_10, + [("X", "X00A0C1M00P00")] + ) as inst: + assert inst.control_mode == "RL" + + +def test_control_mode_setter(): + with expected_protocol(PS120_10, + [("C1", "C")] + ) as inst: + inst.control_mode = "RL" From 96d0cfeaf517fa6cf977c89d0ffdb23eb647c6d3 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Tue, 28 Feb 2023 17:00:17 +0100 Subject: [PATCH 09/11] Return message handling improved and tests expanded. --- pymeasure/instruments/oxfordinstruments/base.py | 11 +++-------- pymeasure/instruments/oxfordinstruments/ips120_10.py | 1 - .../oxfordinstruments/test_base_instrument.py | 8 ++++++++ tests/instruments/oxfordinstruments/test_ips120_10.py | 1 - tests/instruments/oxfordinstruments/test_ps120_10.py | 8 +++++++- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index c7bd96d019..e58e6aeda8 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -71,14 +71,6 @@ def __init__(self, adapter, name="OxfordInstruments Base", max_attempts=5, **kwa **kwargs) self.max_attempts = max_attempts - def values(self, command, separator=',', cast=float, preprocess_reply=lambda v: v[1:], - maxsplit=-1, **kwargs): - """Write a command and get values.""" - return super().values(command, separator=separator, cast=cast, - preprocess_reply=preprocess_reply, - maxsplit=maxsplit, - **kwargs) - def ask(self, command): """Write the command to the instrument and return the resulting ASCII response. Also check the validity of the response before returning it; if the response is not valid, another @@ -100,6 +92,9 @@ def ask(self, command): response = self.read() if self.is_valid_response(response, command): + if command.startswith("R"): + # Remove the leading R of the response + return response.strip("R") return response log.debug("Received invalid response to '%s': %s", command, response) diff --git a/pymeasure/instruments/oxfordinstruments/ips120_10.py b/pymeasure/instruments/oxfordinstruments/ips120_10.py index 83957f40a8..a123ce5218 100644 --- a/pymeasure/instruments/oxfordinstruments/ips120_10.py +++ b/pymeasure/instruments/oxfordinstruments/ips120_10.py @@ -140,7 +140,6 @@ def __init__(self, version = Instrument.measurement( "V", """ A string property that returns the version of the IPS. """, - preprocess_reply=lambda v: v, ) control_mode = Instrument.control( diff --git a/tests/instruments/oxfordinstruments/test_base_instrument.py b/tests/instruments/oxfordinstruments/test_base_instrument.py index 0aa9497c3c..2fb8438a73 100644 --- a/tests/instruments/oxfordinstruments/test_base_instrument.py +++ b/tests/instruments/oxfordinstruments/test_base_instrument.py @@ -37,3 +37,11 @@ def test_wrong_response(): ) as inst: with pytest.raises(OxfordVISAError): inst.ask("A") + + +def test_write_not_understood_command(): + with expected_protocol(OxfordInstrumentsBase, + [("A", "?B")], + ) as inst: + with pytest.raises(OxfordVISAError): + inst.write("A") diff --git a/tests/instruments/oxfordinstruments/test_ips120_10.py b/tests/instruments/oxfordinstruments/test_ips120_10.py index d7f8b30dbf..68bef607d8 100644 --- a/tests/instruments/oxfordinstruments/test_ips120_10.py +++ b/tests/instruments/oxfordinstruments/test_ips120_10.py @@ -51,7 +51,6 @@ def test_activity_setter(): inst.activity = "hold" -@pytest.mark.xfail() # TODO this test fails, the correct response has to be added. def test_current_setpoint_getter(): with expected_protocol(IPS120_10, [("R0", "R+1.3")] diff --git a/tests/instruments/oxfordinstruments/test_ps120_10.py b/tests/instruments/oxfordinstruments/test_ps120_10.py index f0d3139c5b..e95c0995c3 100644 --- a/tests/instruments/oxfordinstruments/test_ps120_10.py +++ b/tests/instruments/oxfordinstruments/test_ps120_10.py @@ -51,7 +51,6 @@ def test_activity_setter(): inst.activity = "hold" -@pytest.mark.xfail() # TODO this test fails, the correct response has to be added. def test_current_setpoint_getter(): with expected_protocol(PS120_10, [("R0", "R+130")] @@ -78,3 +77,10 @@ def test_control_mode_setter(): [("C1", "C")] ) as inst: inst.control_mode = "RL" + + +def test_field_setpoint(): + with expected_protocol(PS120_10, + [("R8", "R+00100")], + ) as inst: + assert inst.field_setpoint == 1.0 From 5d5a3beeb735ea63816d1156ddcffbccbfdfce98 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Tue, 28 Feb 2023 17:51:58 +0100 Subject: [PATCH 10/11] Update pymeasure/instruments/oxfordinstruments/base.py Co-authored-by: Benjamin Klebel-Knobloch <32774645+bklebel@users.noreply.github.com> --- pymeasure/instruments/oxfordinstruments/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymeasure/instruments/oxfordinstruments/base.py b/pymeasure/instruments/oxfordinstruments/base.py index e58e6aeda8..15946225c5 100644 --- a/pymeasure/instruments/oxfordinstruments/base.py +++ b/pymeasure/instruments/oxfordinstruments/base.py @@ -86,7 +86,7 @@ def ask(self, command): """ for attempt in range(self.max_attempts): - # Skip the checks in "write" + # Skip the checks in "write", because we explicitly want to get an answer here super().write(command) self.wait_for() response = self.read() From 9bc45214ee1f0585e09f1a4b91aa7acecc07dbc5 Mon Sep 17 00:00:00 2001 From: Benedikt Moneke <67148916+bmoneke@users.noreply.github.com> Date: Tue, 28 Feb 2023 17:52:35 +0100 Subject: [PATCH 11/11] pytest import removed. --- tests/instruments/oxfordinstruments/test_ips120_10.py | 2 -- tests/instruments/oxfordinstruments/test_ps120_10.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/instruments/oxfordinstruments/test_ips120_10.py b/tests/instruments/oxfordinstruments/test_ips120_10.py index 68bef607d8..985e032eb0 100644 --- a/tests/instruments/oxfordinstruments/test_ips120_10.py +++ b/tests/instruments/oxfordinstruments/test_ips120_10.py @@ -22,8 +22,6 @@ # THE SOFTWARE. # -import pytest - from pymeasure.test import expected_protocol diff --git a/tests/instruments/oxfordinstruments/test_ps120_10.py b/tests/instruments/oxfordinstruments/test_ps120_10.py index e95c0995c3..64d4bf024f 100644 --- a/tests/instruments/oxfordinstruments/test_ps120_10.py +++ b/tests/instruments/oxfordinstruments/test_ps120_10.py @@ -22,8 +22,6 @@ # THE SOFTWARE. # -import pytest - from pymeasure.test import expected_protocol