commit afde2f85e26fc9294e2f88ae1f9ee455f70323f8 Author: CPD Date: Tue Apr 29 12:25:57 2025 +0200 Init 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 ,