From afde2f85e26fc9294e2f88ae1f9ee455f70323f8 Mon Sep 17 00:00:00 2001 From: CPD Date: Tue, 29 Apr 2025 12:25:57 +0200 Subject: [PATCH] Init --- prsctl/measurement_device/__init__.py | 34 +++ prsctl/measurement_device/base.py | 63 ++++++ prsctl/measurement_device/impl/sr830.py | 86 ++++++++ prsctl/measurement_device/impl/test.py | 60 +++++ prsctl/utility/__init__.py | 0 prsctl/utility/config_file.py | 50 +++++ prsctl/utility/data.py | 280 ++++++++++++++++++++++++ prsctl/utility/data_collector.py | 141 ++++++++++++ prsctl/utility/device_select.py | 26 +++ prsctl/utility/file_io.py | 37 ++++ prsctl/utility/visa.py | 34 +++ 11 files changed, 811 insertions(+) create mode 100644 prsctl/measurement_device/__init__.py create mode 100644 prsctl/measurement_device/base.py create mode 100644 prsctl/measurement_device/impl/sr830.py create mode 100644 prsctl/measurement_device/impl/test.py create mode 100644 prsctl/utility/__init__.py create mode 100644 prsctl/utility/config_file.py create mode 100644 prsctl/utility/data.py create mode 100644 prsctl/utility/data_collector.py create mode 100644 prsctl/utility/device_select.py create mode 100644 prsctl/utility/file_io.py create mode 100644 prsctl/utility/visa.py diff --git a/prsctl/measurement_device/__init__.py b/prsctl/measurement_device/__init__.py new file mode 100644 index 0000000..2530581 --- /dev/null +++ b/prsctl/measurement_device/__init__.py @@ -0,0 +1,34 @@ + +from .base import MeasurementDevice + +TYPENAME_TEST = "Test" +TYPENAME_KEITHLEY2700 = "Keithley 2700" + +try: + from .impl.sr830 import SR830 +except ImportError: + pass + +from .impl.test import TestVoltageMeasurementDevice + +def list_devices() -> dict[str,list[str]]: + devices = { + TYPENAME_TEST: ["Voltage Measurement Dummy Device"], + } + try: + from .impl.sr830 import SR830 + devices[TYPENAME_KEITHLEY2700] = SR830.enumerate_devices() + except ImportError: + pass + return devices + +def connect_device(type_name: str, device_name: str) -> MeasurementDevice: + if type_name == TYPENAME_TEST: + return TestVoltageMeasurementDevice() + elif type_name == TYPENAME_KEITHLEY2700: + try: + from .impl.sr830 import SR830 + return SR830.connect_device(device_name) + except ImportError as e: + raise ValueError(f"Keithley 2700 devices not available: {e}") + raise ValueError(f"Unknown device type {type_name}") \ No newline at end of file diff --git a/prsctl/measurement_device/base.py b/prsctl/measurement_device/base.py new file mode 100644 index 0000000..45901cb --- /dev/null +++ b/prsctl/measurement_device/base.py @@ -0,0 +1,63 @@ +from abc import ABC, abstractmethod +from typing import Callable + +""" +Created on Tue Jan 21 16:19:01 2025 + +@author: Matthias Quintern +""" + +class MeasurementDevice(ABC): + @abstractmethod + def test_connection(self) -> None: + """ + Verify that the device is still properly connected. + If not, raises ConnectionError + """ + pass + # RUN COMMANDS ON THE DEVICE + @abstractmethod + def run(self, code, verbose=False): + pass + @abstractmethod + def run_script(self, script_path, verbose=False): + pass + + @abstractmethod + def reset(self, verbose=False): + pass + + @abstractmethod + def read_value(self) -> tuple[float, float]: + """ + Read a single value + + Returns + ------- + [timestamp, voltage] + """ + pass + + @abstractmethod + def measure(self, interval: int, update_func: Callable[None, [int, float, float]]|None=None, max_measurements:int|None=None): + """ + Take voltage readings after milliseconds. + + Parameters + ---------- + interval : int + Number of milliseconds to wait between readings. + update_func : Callable[None, [int, float, float]] or None, optional + A function that is called after each reading with parameters ,