Source code for fluidlab.instruments.drivers

"""Instrument drivers (:mod:`fluidlab.instruments.drivers`)

Abstract base class for instrument drivers.
Concrete classes must define features, and overload default_physical_interface,
and default_inter_params attributes.


.. autoclass:: Driver


from fluidlab.interfaces import interface_from_string, FalseInterface, Interface
from fluidlab.instruments.features import SuperValue

[docs]class Driver: """Instrument driver (base class). Parameters ---------- interface : :class:`fluidlab.interfaces.Interface` The interface used to communicate with the instrument. """ default_physical_interface = None default_inter_params = dict() @classmethod def _build_class_with_features(cls, features): for feature in features: feature._build_driver_class(cls) def __init__(self, interface=None): if isinstance(interface, str): interface = interface_from_string( interface, self.default_physical_interface, **self.default_inter_params ) elif not interface: interface = FalseInterface() elif not isinstance(interface, Interface): raise ValueError("interface should be an Interface.") self._interface = self.interface = interface self.values = {} for name in dir(self): v = getattr(self, name) if isinstance(v, SuperValue): self.values[name] = v v._interface = self._interface v._driver = self def __setattr__(self, k, v): if ( not isinstance(v, SuperValue) and k in dir(self) and isinstance(getattr(self, k), SuperValue) ): raise ValueError( k + " is associated with a quantity in the instrument. " "Do not set this value by assignment. Use a set function." ) super().__setattr__(k, v)
[docs] def set(self, name, *args, **kargs): """Set a value.""" value = self._get_value_from_name(name) value.set(*args, **kargs)
[docs] def get(self, name, *args, **kargs): """Get a value.""" value = self._get_value_from_name(name) return value.get(*args, **kargs)
def _get_value_from_name(self, name): try: value = getattr(self, name) error_class = None except AttributeError: error_class = AttributeError else: if not isinstance(value, SuperValue): error_class = ValueError if error_class: raise error_class(name + " is not a value of this instrument") return value def __enter__(self): self.interface.__enter__() return self def __exit__(self, type_, value, cb): self.interface.__exit__(type_, value, cb)
if __name__ == "__main__": driver = Driver("ASRL4::INSTR", backend="@sim")