Beispiel #1
0
class PowerSupply(Device):

    host = device_property(str, default_value='localhost')
    port = device_property(int, default_value=45000)

    def init_device(self):
        super().init_device()
        self.calibration_task = None
        self.conn = connect(self.host, self.port)

    @attribute(dtype=float)
    def voltage(self):
        return float(write_readline(self.conn, b'VOL?\n'))

    @command
    def calibrate(self):
        if self.calibration_task is not None:
            raise Exception('Calibration already in place')
        self.calibration_task = spawn(self.do_calibration)

    def do_calibration(self):
        self.set_state(DevState.RUNNING)
        try:        
            write_readline(self.conn, b'CALIB 1\n')
            while int(write_readline(self.conn, b'stat?\n')):
                sleep(0.1)
        finally:
            self.set_state(DevState.ON)
            self.calibration_task = None
Beispiel #2
0
class Merlin(Device):
    host = device_property(dtype=str, mandatory=False)
    port = device_property(dtype=int, mandatory=False)

    def init_device(self):
        super().init_device()
        self._control = MerlinControl(host=self.host, port=self.port)

    @command
    def connect(self):
        self._control.connect()

    @command
    def close(self):
        self._control.close()

    @command(dtype_in=str, dtype_out=str)
    def get(self, param):
        with self._control:
            return self._control.get(param)

    @command(dtype_in=(str, ))
    def set(self, param_value):
        param, value = param_value
        with self._control:
            return self._control.set(param, value)

    @command(dtype_in=str)
    def cmd(self, cmd):
        with self._control:
            return self._control.cmd(cmd)

    @command(dtype_out=str)
    def hello(self):
        return "world"
Beispiel #3
0
class MythenSLS(Device):

    host = device_property(dtype=str)
    ctrl_port = device_property(dtype=int, default_value=DEFAULT_CTRL_PORT)
    stop_port = device_property(dtype=int, default_value=DEFAULT_STOP_PORT)

    def init_device(self):
        super().init_device()
        self.ctrl = get_control()

    @property
    def mythen(self):
        return self.ctrl.hwInterface().detector

    def dev_state(self):
        status = self.mythen.run_status
        if status in (RunStatus.WAITING, RunStatus.TRANSMITTING,
                      RunStatus.RUNNING):
            return DevState.RUNNING
        elif status == RunStatus.ERROR:
            return DevState.FAULT
        return DevState.ON

    def dev_status(self):
        return repr(self.mythen)

    @attribute
    def exposure_time_left(self):
        return self.mythen.exposure_time_left

    @attribute
    def nb_cycles_left(self):
        return self.mythen.nb_cycles_left

    @attribute
    def nb_frames_left(self):
        return self.mythen.nb_frames_left

    @attribute
    def progress(self):
        return self.mythen.progress

    @attribute
    def measurement_time(self):
        return self.mythen.measurement_time

    @attribute(dtype=int)
    def energy_threshold(self):
        return self.mythen.energy_threshold

    @energy_threshold.setter
    def energy_threshold(self, energy_threshold):
        self.mythen.energy_threshold = energy_threshold
Beispiel #4
0
class FuelCell(Device):

    url = device_property(dtype=str, doc='fuell cell hostname')
    name = device_property(dtype=str, default_value=None)

    def init_device(self):
        Device.init_device(self)
        try:
            if self.name:
                config = get_config()
                self.fuelcell = config.get(self.name)
            else:
                self.fuelcell = _FuelCell('Fuel Cell',
                                          dict(tcp=dict(url=self.url)))
            self.set_state(DevState.ON)
            self.set_status('Ready!')
        except Exception as e:
            self.set_state(DevState.FAULT)
            self.set_status('Error:\n' + str(e))

    # ----------
    # Commands
    # ----------

    @command(dtype_in=[int], doc_in=Ptc.timescan.__doc__)
    def timescan(self, par_list):
        self.fuelcell.ptc.timescan(*par_list)

    @command(dtype_in=[str], doc_in=Ptc.cv.__doc__)
    def cv(self, par_list):
        if len(par_list) < 7:
            raise RuntimeError('not enough parameters')
        channel = par_list[0]
        start = float(par_list[1])
        stop = float(par_list[2])
        margin1 = float(par_list[3])
        margin2 = float(par_list[4])
        speed = float(par_list[5])
        sweeps = int(par_list[6])

        self.fuelcell.ptc.cv(channel, start, stop, margin1, margin2, speed,
                             sweeps)

    @command(doc_in=Ptc.stop.__doc__)
    def stop(self):
        self.fuelcell.ptc.stop()

    def write_vsense(self, value):
        self.fuelcell.ptc.set_vsense_feedback(value)

    def write_current(self, value):
        self.fuelcell.ptc.set_current_feedback(value)
Beispiel #5
0
class BaseJulabo(Device):

    url = device_property(dtype=str)
    baudrate = device_property(dtype=int, default_value=9600)
    bytesize = device_property(dtype=int, default_value=8)
    parity = device_property(dtype=str, default_value='N')

    Julabo = None

    async def init_device(self):
        await super().init_device()
        kwargs = dict(concurrency="asyncio")
        if self.url.startswith("serial") or self.url.startswith("rfc2217"):
            kwargs = dict(baudrate=self.baudrate,
                          bytesize=self.bytesize,
                          parity=self.parity)

        connection = connection_for_url(self.url, **kwargs)
        self.julabo = self.Julabo(connection)

    async def dev_state(self):
        status_code = int((await self.julabo.status())[:2])
        if status_code in {0, 2}:
            return DevState.STANDBY
        elif status_code in {1, 3}:
            return DevState.RUNNING
        elif status_code < 0:
            return DevState.ALARM
        return DevState.FAULT

    async def dev_status(self):
        return await self.julabo.status()

    @attribute(dtype=str, label="Identification")
    async def identification(self):
        """Device identification (model and version)"""
        return await self.julabo.identification()

    @attribute(dtype=bool, label="Is started?")
    async def is_started(self):
        """Is device started or not"""
        return await self.julabo.is_started()

    @command
    async def start(self):
        """Start the device"""
        await self.julabo.start()

    @command
    async def stop(self):
        """Stop the device"""
        await self.julabo.stop()
Beispiel #6
0
class MandatoryPropertyServer(Device):

    Hostname = device_property(
        dtype='str', mandatory=True,
        doc='The controller host address')

    Port = device_property(
        dtype='int', default_value=3456,
        doc='The controller port number')

    def init_device(self):
        Device.init_device(self)
        print('Port: ', self.Port)
        print('Host: ', self.Hostname)
        self.set_state(DevState.ON)
Beispiel #7
0
class TestDevice(Device):
    """."""

    _start_time = time.time()
    version = device_property(dtype=str, default_value=__version__)

    def init_device(self):
        """."""
        Device.init_device(self)
        self.set_state(DevState.STANDBY)

    def always_executed_hook(self):
        """."""

    def delete_device(self):
        """."""

    @attribute(dtype=str)
    def identifier(self):
        """Return the device name."""
        return type(self).__name__

    @attribute(dtype=float)
    def up_time(self):
        """."""
        return time.time() - self._start_time

    # pylint: disable=no-self-use
    @command(dtype_in=str, dtype_out=str)
    def cmd_str_arg(self, value: str) -> str:
        """."""
        time.sleep(0.01)
        return value
class Omicron_laser(Device):

    url = device_property(dtype=str)

    def init_device(self):
        super().init_device()
        self.connection = serial.serial_for_url(self.url)
        self.omicron_laser = omicron_laser.core.Omicron_laser(self.connection)


################################################################################

    @attribute(dtype=float, unit="bar", label="Pressure set point")
    def pressure_setpoint(self):
        # example processing the result
        setpoint = self.omicron_laser.get_pressure_setpoint()
        return setpoint / 1000

    @pressure_setpoint.setter
    def pressure_setpoint(self, value):
        # example returning the coroutine back to tango
        return self.omicron_laser.get_pressure_setpoint(value * 1000)

    @command
    def turn_on(self):
        # example returning the coroutine back to who calling function
        return self.omicron_laser.turn_on()
class SKATelState(SKABaseDevice):
    """
    A generic base device for Telescope State for SKA.
    """
    # PROTECTED REGION ID(SKATelState.class_variable) ENABLED START #
    # PROTECTED REGION END #    //  SKATelState.class_variable

    # -----------------
    # Device Properties
    # -----------------

    TelStateConfigFile = device_property(
        dtype='str',
    )

    # ----------
    # Attributes
    # ----------

    # ---------------
    # General methods
    # ---------------
    def always_executed_hook(self):
        # PROTECTED REGION ID(SKATelState.always_executed_hook) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKATelState.always_executed_hook

    def delete_device(self):
        # PROTECTED REGION ID(SKATelState.delete_device) ENABLED START #
        pass
Beispiel #10
0
    class TestDevice1(Device):
        green_mode = server_green_mode

        prop1 = device_property(dtype=str)

        @command(dtype_out=str)
        def get_prop1(self):
            return self.prop1
Beispiel #11
0
    class TestDevice(Device):
        green_mode = server_green_mode

        prop = device_property(dtype=dtype)

        @command(dtype_out=patched_dtype)
        def get_prop(self):
            return default if self.prop is None else self.prop
Beispiel #12
0
    class TestDevice(Device):
        green_mode = server_green_mode

        prop = device_property(dtype=dtype, mandatory=True)

        @command(dtype_out=patched_dtype)
        def get_prop(self):
            return self.prop
Beispiel #13
0
    class TestDevice2(Device):
        green_mode = server_green_mode

        prop2 = device_property(dtype=int)

        @command(dtype_out=int)
        def get_prop2(self):
            return self.prop2
Beispiel #14
0
    class TestDevice(Device):
        green_mode = server_green_mode

        prop = device_property(dtype=dtype, default_value=default)

        @command(dtype_out=dtype)
        def get_prop(self):
            return self.prop
Beispiel #15
0
class PowerSupply(Device):

    host = device_property(str, default_value='localhost')
    port = device_property(int, default_value=45000)

    def init_device(self):
        super().init_device()
        self.conn = connect(self.host, self.port)

    @attribute(dtype=float)
    def voltage(self):
        return float(write_readline(self.conn, b'VOL?\n'))

    @command
    def calibrate(self):
        write_readline(self.conn, b'CALIB 1\n')
        while int(write_readline(self.conn, b'stat?\n')):
            sleep(0.1)
Beispiel #16
0
class OneAxis(Device):

    axis = device_property(dtype=str, default_value='1')

    def init_device(self):
        self.axis = self.get_name().split('/')[2]

        self.pi_device = PiDevice

        try:
            self.pi_device.FRF(self.axis)
        except:
            print(self.pi_device.qERR())
        print("done")
        #TODO query axises and reference every

    @attribute(dtype=float)
    def position(self):
        return self.pi_device.qPOS().get(self.axis)

    @attribute(dtype=bool)
    def servo(self):
        return self.pi_device.qSVO().get(self.axis)

    @attribute(dtype=bool)
    def referenced(self):
        return self.pi_device.qFRF().get(self.axis)

    def state(self):
        return self.pi_device.qSVO(self.axis)

    def status(self):
        return "IsConnected: " + self.pi_device.IsConnected()

    @command(dtype_in=None)
    def enable_servo(self):
        self.pi_device.SVO(self.axis, 1)

    @command(dtype_in=None)
    def disable_servo(self):
        self.pi_device.SVO(self.axis, 0)

    @command(dtype_in=float, dtype_out=None)
    def move(self, pos):
        if not self.pi_device.qSVO(self.axis):
            raise Exception("not in servo mode, enable first")

        self.pi_device.MOV(self.axis, pos)  # Command axis "A" to position pos

    @command(dtype_in=None)
    def stop(self):
        self.pi_device.HLT(self.axis)

    @command(dtype_in=None)
    def stop_all(self):
        self.pi_device.STP()
Beispiel #17
0
class Master(Device):
    WorkerFQDNs = device_property(dtype="DevVarStringArray")

    @command(dtype_in="DevLong")
    def Turn_Worker_On(self, worker_id):
        worker_fqdn = self.WorkerFQDNs[worker_id - 1]
        worker_device = tango.DeviceProxy(worker_fqdn)
        worker_device.is_on = True

    @command(dtype_in="DevLong")
    def Turn_Worker_Off(self, worker_id):
        worker_fqdn = self.WorkerFQDNs[worker_id - 1]
        worker_device = tango.DeviceProxy(worker_fqdn)
        worker_device.is_on = False
Beispiel #18
0
    class A(Device):
        green_mode = server_green_mode

        prop1 = device_property(dtype=str, default_value="hello1")
        prop2 = device_property(dtype=str, default_value="hello2")

        @command(dtype_out=str)
        def get_prop1(self):
            return self.prop1

        @command(dtype_out=str)
        def get_prop2(self):
            return self.prop2

        @attribute(access=AttrWriteType.READ_WRITE)
        def attr(self):
            return self.attr_value

        @attr.write
        def attr(self, value):
            self.attr_value = value

        def dev_status(self):
            return ")`'-.,_"
Beispiel #19
0
class Hamamatsu(Device):

    camera_id = device_property(dtype=int, default_value=0)

    def init_device(self):
        super().init_device()
        self.ctrl = get_control()

    @property
    def mythen(self):
        return self.ctrl.hwInterface().detector

    def dev_state(self):
        status = self.mythen.status
        return DevState.RUNNING if status == "RUNNING" else DevState.ON
class SKATelState(with_metaclass(DeviceMeta, SKABaseDevice)):
    """
    A generic base device for Telescope State for SKA.
    """
    # PROTECTED REGION ID(SKATelState.class_variable) ENABLED START #
    # PROTECTED REGION END #    //  SKATelState.class_variable

    # -----------------
    # Device Properties
    # -----------------

    TelStateConfigFile = device_property(
        dtype='str',
    )


    # ----------
    # Attributes
    # ----------

    # ---------------
    # General methods
    # ---------------

    def init_device(self):
        """init_device
        Init device method of SKATelStateDevice
        """
        SKABaseDevice.init_device(self)
        self._build_state = '{}, {}, {}'.format(release.name, release.version,
                                                release.description)
        self._version_id = release.version
        # PROTECTED REGION ID(SKATelState.init_device) ENABLED START #
        # PROTECTED REGION END #    //  SKATelState.init_device

    def always_executed_hook(self):
        # PROTECTED REGION ID(SKATelState.always_executed_hook) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKATelState.always_executed_hook

    def delete_device(self):
        # PROTECTED REGION ID(SKATelState.delete_device) ENABLED START #
        pass
Beispiel #21
0
class Multimeter(Device):

    name = device_property(dtype=str, doc='keithley bliss object name')

    def init_device(self):
        Device.init_device(self)

        try:
            config = get_config()
            self.device = config.get(self.name)
            switch_state(self, DevState.ON, "Ready!")
        except Exception as e:
            msg = "Exception initializing device: {0}".format(e)
            self.error_stream(msg)
            switch_state(self, DevState.FAULT, msg)

    def delete_device(self):
        if self.device:
            self.device.abort()

    @attribute(dtype=bool)
    def auto_range(self):
        return self.device.get_auto_range()

    @auto_range.setter
    def auto_range(self, auto_range):
        self.device.set_auto_range(auto_range)

    @attribute(dtype=float)
    def range(self):
        return self.get_range()

    @range.setter
    def range(self, range):
        self.set_range(range)

    @attribute(dtype=float)
    def nplc(self):
        return self.device.get_nplc()

    @nplc.setter
    def nplc(self, nplc):
        self.device.set_nplc(nplc)
Beispiel #22
0
    class B(A):

        prop2 = device_property(dtype=str, default_value="goodbye2")

        @attribute
        def attr2(self):
            return 3.14

        def dev_status(self):
            return 3 * A.dev_status(self)

        if server_green_mode == GreenMode.Asyncio:
            code = textwrap.dedent("""\
                @asyncio.coroutine
                def dev_status(self):
                    coro = super(type(self), self).dev_status()
                    result = {YIELD_FROM}(coro)
                    {RETURN}(3*result)
            """).format(**globals())
            exec(code)
Beispiel #23
0
class P04_beamline(Device):

    DYN_ATTRS = [
        dict(name='photonenergy',
             label='photon energy',
             dtype=tango.DevFloat,
             access=READ_WRITE,
             unit='eV',
             format='%6.2f',
             min_value=240,
             max_value=2000),
        dict(name='exitslit',
             label="exit slit",
             dtype=tango.DevFloat,
             access=READ_WRITE,
             unit="um",
             format="%4.0f"),
        dict(name='helicity',
             label='helicity',
             dtype=tango.DevLong,
             access=READ_WRITE,
             min_value=-1,
             max_value=1),
        dict(name='mono',
             label="monochromator",
             dtype=tango.DevFloat,
             access=READ,
             unit="eV",
             format="%6.2f"),
        dict(name='undugap',
             label='undulator gap',
             dtype=tango.DevFloat,
             access=READ,
             unit='mm'),
        # dict(name='undufactor', label='undulator scale factor',
        #      access=READ, format='%3.2f', dtype=tango.DevFloat),
        dict(name='undushift',
             label='undulator shift',
             dtype=tango.DevFloat,
             access=READ,
             unit='mm'),
        dict(name='ringcurrent',
             label='ring current',
             dtype=tango.DevFloat,
             access=READ,
             unit='mA'),
        # dict(name='keithley1', label='beamline keithley', dtype=tango.DevFloat,
        #      access=READ),
        # dict(name='keithley2', label='user keithley', dtype=tango.DevFloat,
        #      access=READ),
        dict(name='slt2hleft',
             label='slit hor left',
             dtype=tango.DevFloat,
             access=READ),
        dict(name='slt2hright',
             label='slit hor right',
             dtype=tango.DevFloat,
             access=READ),
        dict(name='slt2vgap',
             label='slit ver gap',
             dtype=tango.DevFloat,
             access=READ),
        dict(name='slt2voffset',
             label='slit ver offset',
             dtype=tango.DevFloat,
             access=READ),
        # dict(name='exsu2bpm', label='exsu2bpm', dtype=tango.DevFloat,
        # access=READ),
        # dict(name='exsu2baffle', label='exsu2baffle', dtype=tango.DevFloat,
        #       access=READ),
        # dict(name='pressure', label='experiment pressure', access=READ,
        #       dtype=tango.DevFloat, unit='mbar', format='%.2E'),
        dict(name='screen',
             label='beamline screen',
             dtype=tango.DevLong,
             access=READ_WRITE,
             min_value=0,
             max_value=2,
             enum_labels=['closed', 'mesh', 'open'])
    ]

    ready_to_move = attribute(name='ready_to_move',
                              label='in position',
                              access=READ,
                              dtype=tango.DevBoolean,
                              polling_period=1000,
                              fread="is_movable")

    host = device_property(dtype=str, mandatory=True, update_db=True)
    port = device_property(dtype=int, default_value=3002)

    def init_device(self):
        Device.init_device(self)
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((self.host, self.port))
        self.s.setblocking(True)
        self.lock = Lock()
        self.set_state(DevState.ON)
        energy = self.read_attr('photonenergy')[0]
        self._setpoint_E = [energy, energy]
        self._setpoint_helicity = self.read_attr('helicity')[0]

    def initialize_dynamic_attributes(self):
        # TODO: setup polling and event filter
        for d in self.DYN_ATTRS:
            new_attr = attribute(fget=self.read_general,
                                 fset=self.write_general,
                                 **d)
            self.add_attribute(new_attr)

    @command(dtype_in=str)
    def query(self, msg):
        '''Send a query and wait for its reply.'''
        if self.lock.acquire(timeout=0.5):
            if not msg.endswith(' eoc'):
                msg += ' eoc'
            # print('sent:', msg, file=self.log_debug)
            self.s.sendall(msg.encode())
            ans = self.s.recv(1024).decode()
            # print('received:', ans, file=self.log_debug)
            assert ans.endswith('eoa')
            self.lock.release()
            return ans[:-4]
        else:
            print(f"can't send '{msg}': socket is locked", file=self.log_error)
            return 'busy'

    def read_general(self, attr):
        key = attr.get_name()
        # print('reading', key, file=self.log_debug)
        val, time, quality = self.read_attr(key)
        attr.set_value(val)

    # def write_general(self, attr):
    #     key = attr.get_name()
    #     val = attr.get_write_value()
    #     send_attrs = ['photonenergy', 'exitslit', 'helicity', 'screen']
    #     cmd = 'send' if key in send_attrs else 'set'
    #     ntries = 0
    #     while ntries < 10:
    #         ntries += 1
    #         if self.is_movable():
    #             ans = self.query(f'{cmd} {key} {val}')
    #             print(f'setting {key}: {val} ({ntries}/10)', file=self.log_debug)
    #             if ans == 'started':
    #                 self.set_state(DevState.MOVING)
    #                 print(f'[key] moving to {val}', file=self.log_debug)
    #                 return
    #             time.sleep(1)

    #     print(f'could not send {key} to {val}', file=self.log_error)

    def write_general(self, attr):
        key = attr.get_name()
        val = attr.get_write_value()
        send_attrs = ['photonenergy', 'exitslit', 'helicity', 'screen']
        cmd = 'send' if key in send_attrs else 'set'
        if key == 'photonenergy':
            self._setpoint_E[0] = val
        if key == 'helicity':
            self._setpoint_helicity = val
        ans = self.query(f'{cmd} {key} {val}')
        print(f'setting {key}: {val}', file=self.log_debug)
        if ans == 'started':
            self._setpoint_E[1] = val
            self.set_state(DevState.MOVING)
            print(f'[key] moving to {val}', file=self.log_debug)
            return

        print(f'could not send {key} to {val}', file=self.log_error)

    def is_movable(self):
        '''Check whether undulator and monochromator are in position.'''
        in_pos = self.query('check photonenergy')
        in_pos = True if in_pos == '1' else False
        if (self._setpoint_E[0] != self._setpoint_E[1]) and in_pos:
            ans_set = self.query(f'send photonenergy {self._setpoint_E[0]}')
            if ans_set == 'started':
                self._setpoint_E[1] = self._setpoint_E[0]
        helicity = self.read_attr('helicity')[0]
        state = (helicity == self._setpoint_helicity) and in_pos
        self.set_state(DevState.ON if state else DevState.MOVING)
        return in_pos

    @command(dtype_in=str, dtype_out=str)
    def cmd_async(self, msg, test):
        '''Send a command without waiting for it to finish.

        The socket will still be blocked!
        '''
        t = Thread(target=self.query, args=(msg, ))
        t.daemon = True
        t.start()

    @command
    def closeconnection(self):
        ans = self.query('closeconnection')
        if 'bye!' in ans:
            self.s.close()
            self.set_state(DevState.OFF)

    def read_attr(self, attr):
        '''Queries the position of given attribute name.

        Returns
        -------
        val : float
        tstamp : time stamp
        quality : AttrQuality instance (ATTR_VALID, ATTR_CHANGING, ...)
        '''
        ans = self.query(f'read {attr}')
        if 'Current value' in ans:
            val = float(ans.split(':')[1])
            return val, time(), AttrQuality.ATTR_VALID
        else:
            self.error_stream('Socket busy or unexpected/incomplete answer')
            return None, time(), AttrQuality.ATTR_INVALID
class SKACapability(with_metaclass(DeviceMeta, SKAObsDevice)):
    """
    A Subarray handling device. It exposes the instances of configured capabilities.
    """
    # PROTECTED REGION ID(SKACapability.class_variable) ENABLED START #
    # PROTECTED REGION END #    //  SKACapability.class_variable

    # -----------------
    # Device Properties
    # -----------------

    CapType = device_property(dtype='str', )

    CapID = device_property(dtype='str', )

    subID = device_property(dtype='str', )

    # ----------
    # Attributes
    # ----------

    activationTime = attribute(
        dtype='double',
        unit="s",
        standard_unit="s",
        display_unit="s",
        doc="Time of activation in seconds since Unix epoch.",
    )

    configuredInstances = attribute(
        dtype='uint16',
        doc=
        "Number of instances of this Capability Type currently in use on this subarray.",
    )

    usedComponents = attribute(
        dtype=('str', ),
        max_dim_x=100,
        doc=
        "A list of components with no. of instances in use on this Capability.",
    )

    # ---------------
    # General methods
    # ---------------

    def init_device(self):
        SKAObsDevice.init_device(self)
        self._build_state = '{}, {}, {}'.format(release.name, release.version,
                                                release.description)
        self._version_id = release.version
        # PROTECTED REGION ID(SKACapability.init_device) ENABLED START #
        self._activation_time = 0.0
        self._configured_instances = 0
        self._used_components = [""]
        # PROTECTED REGION END #    //  SKACapability.init_device

    def always_executed_hook(self):
        # PROTECTED REGION ID(SKACapability.always_executed_hook) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKACapability.always_executed_hook

    def delete_device(self):
        # PROTECTED REGION ID(SKACapability.delete_device) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKACapability.delete_device

    # ------------------
    # Attributes methods
    # ------------------

    def read_activationTime(self):
        # PROTECTED REGION ID(SKACapability.activationTime_read) ENABLED START #
        """
        Reads time of activation since Unix epoch.
        :return: Activation time in seconds
        """
        return self._activation_time
        # PROTECTED REGION END #    //  SKACapability.activationTime_read

    def read_configuredInstances(self):
        # PROTECTED REGION ID(SKACapability.configuredInstances_read) ENABLED START #
        """
        Reads the number of instances of a capability in the subarray
        :return: The number of configured instances of a capability in a subarray
        """
        return self._configured_instances
        # PROTECTED REGION END #    //  SKACapability.configuredInstances_read

    def read_usedComponents(self):
        # PROTECTED REGION ID(SKACapability.usedComponents_read) ENABLED START #
        """
        Reads the list of components with no. of instances in use on this Capability
        :return: The number of components currently in use.
        """
        return self._used_components
        # PROTECTED REGION END #    //  SKACapability.usedComponents_read

    # --------
    # Commands
    # --------

    @command(
        dtype_in='uint16',
        doc_in="The number of instances to configure for this Capability.",
    )
    @DebugIt()
    def ConfigureInstances(self, argin):
        # PROTECTED REGION ID(SKACapability.ConfigureInstances) ENABLED START #
        """
        This function indicates how many number of instances of the current capacity
        should to be configured.
        :param argin: Number of instances to configure
        :return: None.
        """
        self._configured_instances = argin
class SKAMaster(with_metaclass(DeviceMeta, SKABaseDevice)):
    """
    A master test
    """
    # PROTECTED REGION ID(SKAMaster.class_variable) ENABLED START #
    # PROTECTED REGION END #    //  SKAMaster.class_variable

    # -----------------
    # Device Properties
    # -----------------

    # List of maximum number of instances per capability type provided by this Element;
    # CORRELATOR=512, PSS-BEAMS=4, PST-BEAMS=6, VLBI-BEAMS=4  or for DSH it can be:
    # BAND-1=1, BAND-2=1, BAND3=0, BAND-4=0, BAND-5=0 (if only bands 1&amp;2 is installed)
    MaxCapabilities = device_property(dtype=('str', ), )

    # ----------
    # Attributes
    # ----------

    elementLoggerAddress = attribute(
        dtype='str',
        doc="FQDN of Element Logger",
    )

    elementAlarmAddress = attribute(
        dtype='str',
        doc="FQDN of Element Alarm Handlers",
    )

    elementTelStateAddress = attribute(
        dtype='str',
        doc="FQDN of Element TelState device",
    )

    elementDatabaseAddress = attribute(
        dtype='str',
        doc="FQDN of Element Database device",
    )

    maxCapabilities = attribute(
        dtype=('str', ),
        max_dim_x=20,
        doc=
        "Maximum number of instances of each capability type, e.g. 'CORRELATOR:512', 'PSS-BEAMS:4'.",
    )

    availableCapabilities = attribute(
        dtype=('str', ),
        max_dim_x=20,
        doc="A list of available number of instances of each capability type, "
        "e.g. 'CORRELATOR:512', 'PSS-BEAMS:4'.",
    )

    # ---------------
    # General methods
    # ---------------

    def init_device(self):
        SKABaseDevice.init_device(self)
        # PROTECTED REGION ID(SKAMaster.init_device) ENABLED START #
        self._build_state = '{}, {}, {}'.format(release.name, release.version,
                                                release.description)
        self._version_id = release.version
        # Initialize attribute values.
        self._element_logger_address = ""
        self._element_alarm_address = ""
        self._element_tel_state_address = ""
        self._element_database_address = ""
        self._element_alarm_device = ""
        self._element_tel_state_device = ""
        self._element_database_device = ""
        self._max_capabilities = {}
        if self.MaxCapabilities:
            for max_capability in self.MaxCapabilities:
                capability_type, max_capability_instances = max_capability.split(
                    ":")
                self._max_capabilities[capability_type] = int(
                    max_capability_instances)
        self._available_capabilities = self._max_capabilities.copy()
        # PROTECTED REGION END #    //  SKAMaster.init_device

    def always_executed_hook(self):
        # PROTECTED REGION ID(SKAMaster.always_executed_hook) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKAMaster.always_executed_hook

    def delete_device(self):
        # PROTECTED REGION ID(SKAMaster.delete_device) ENABLED START #
        pass
        # PROTECTED REGION END #    //  SKAMaster.delete_device

    # ------------------
    # Attributes methods
    # ------------------

    def read_elementLoggerAddress(self):
        # PROTECTED REGION ID(SKAMaster.elementLoggerAddress_read) ENABLED START #
        """Reads FQDN of Element Logger device"""
        return self._element_logger_address
        # PROTECTED REGION END #    //  SKAMaster.elementLoggerAddress_read

    def read_elementAlarmAddress(self):
        # PROTECTED REGION ID(SKAMaster.elementAlarmAddress_read) ENABLED START #
        """Reads FQDN of Element Alarm device"""
        return self._element_alarm_address
        # PROTECTED REGION END #    //  SKAMaster.elementAlarmAddress_read

    def read_elementTelStateAddress(self):
        # PROTECTED REGION ID(SKAMaster.elementTelStateAddress_read) ENABLED START #
        """Reads FQDN of Element TelState device"""
        return self._element_tel_state_address
        # PROTECTED REGION END #    //  SKAMaster.elementTelStateAddress_read

    def read_elementDatabaseAddress(self):
        # PROTECTED REGION ID(SKAMaster.elementDatabaseAddress_read) ENABLED START #
        """Reads FQDN of Element Database device"""
        return self._element_database_address
        # PROTECTED REGION END #    //  SKAMaster.elementDatabaseAddress_read

    def read_maxCapabilities(self):
        # PROTECTED REGION ID(SKAMaster.maxCapabilities_read) ENABLED START #
        """Reads maximum number of instances of each capability type"""
        return convert_dict_to_list(self._max_capabilities)
        # PROTECTED REGION END #    //  SKAMaster.maxCapabilities_read

    def read_availableCapabilities(self):
        # PROTECTED REGION ID(SKAMaster.availableCapabilities_read) ENABLED START #
        """Reads list of available number of instances of each capability type"""
        return convert_dict_to_list(self._available_capabilities)
        # PROTECTED REGION END #    //  SKAMaster.availableCapabilities_read

    # --------
    # Commands
    # --------

    @command(
        dtype_in='DevVarLongStringArray',
        doc_in="[nrInstances][Capability types]",
        dtype_out='bool',
    )
    @DebugIt()
    def isCapabilityAchievable(self, argin):
        # PROTECTED REGION ID(SKAMaster.isCapabilityAchievable) ENABLED START #
        """
        Checks of provided capabilities can be achieved by the resource(s).

        :param argin: DevVarLongStringArray.

            An array consisting pair of
                    [nrInstances]: DevLong. Number of instances of the capability.

                    [Capability types]: DevString. Type of capability.

        :return: DevBoolean

            True if capability can be achieved.

            False if cannot.
        """
        command_name = 'isCapabilityAchievable'
        capabilities_instances, capability_types = argin
        validate_input_sizes(command_name, argin)
        validate_capability_types(command_name, capability_types,
                                  list(self._max_capabilities.keys()))

        for capability_type, capability_instances in zip(
                capability_types, capabilities_instances):
            if not self._available_capabilities[
                    capability_type] >= capability_instances:
                return False

        return True
class FspPssSubarray(CspSubElementObsDevice):
    """
    FspPssSubarray TANGO device class for the FspPssSubarray prototype
    """
    # PROTECTED REGION ID(FspPssSubarray.class_variable) ENABLED START #
    # PROTECTED REGION END #    //  FspPssSubarray.class_variable

    # -----------------
    # Device Properties
    # -----------------

    SubID = device_property(dtype='uint16')

    FspID = device_property(dtype='uint16')

    CbfControllerAddress = device_property(
        dtype='str',
        doc="FQDN of CBF Controller",
        default_value="mid_csp_cbf/controller/main")

    # TODO: CbfSubarrayAddress prop not being used
    CbfSubarrayAddress = device_property(dtype='str',
                                         doc="FQDN of CBF Subarray")

    VCC = device_property(dtype=('str', ))

    # ----------
    # Attributes
    # ----------

    receptors = attribute(
        dtype=('uint16', ),
        access=AttrWriteType.READ,
        max_dim_x=197,
        label="Receptors",
        doc="List of receptors assigned to subarray",
    )
    searchBeams = attribute(
        dtype=('str', ),
        access=AttrWriteType.READ,
        max_dim_x=192,
        label="SearchBeams",
        doc="List of searchBeams assigned to fspsubarray",
    )
    searchWindowID = attribute(
        dtype='uint16',
        access=AttrWriteType.READ,
        max_dim_x=2,
        label="ID for 300MHz Search Window",
        doc=
        "Identifier of the Search Window to be used as input for beamforming on this FSP.",
    )

    searchBeamID = attribute(
        dtype=('uint16', ),
        access=AttrWriteType.READ,
        max_dim_x=192,
        label="ID for 300MHz Search Window",
        doc=
        "Identifier of the Search Window to be used as input for beamforming on this FSP.",
    )

    outputEnable = attribute(
        dtype='bool',
        access=AttrWriteType.READ,
        label="Enable Output",
        doc="Enable/disable transmission of output products.",
    )

    # ---------------
    # General methods
    # ---------------

    def init_command_objects(self):
        """
        Sets up the command objects
        """
        super().init_command_objects()

        device_args = (self, self.state_model, self.logger)
        self.register_command_object("ConfigureScan",
                                     self.ConfigureScanCommand(*device_args))
        self.register_command_object("GoToIdle",
                                     self.GoToIdleCommand(*device_args))

    class InitCommand(CspSubElementObsDevice.InitCommand):
        """
        A class for the Vcc's init_device() "command".
        """
        def do(self):
            """
            Stateless hook for device initialisation.

            :return: A tuple containing a return code and a string
                message indicating status. The message is for
                information purpose only.
            :rtype: (ResultCode, str)
            """

            self.logger.debug("Entering InitCommand()")

            device = self.target

            # Make a private copy of the device properties:
            device._subarray_id = device.SubID
            device._fsp_id = device.FspID

            # initialize attribute values
            device._receptors = []
            device._search_beams = []
            device._search_window_id = 0
            device._search_beam_id = []
            device._output_enable = 0
            device._scan_id = 0
            device._config_id = ""

            # device proxy for easy reference to CBF Controller
            device._proxy_cbf_controller = tango.DeviceProxy(
                device.CbfControllerAddress)

            device._controller_max_capabilities = dict(
                pair.split(":")
                for pair in device._proxy_cbf_controller.get_property(
                    "MaxCapabilities")["MaxCapabilities"])
            device._count_vcc = int(device._controller_max_capabilities["VCC"])
            device._fqdn_vcc = list(device.VCC)[:device._count_vcc]
            device._proxies_vcc = [*map(tango.DeviceProxy, device._fqdn_vcc)]

            message = "FspPssSubarry Init command completed OK"
            self.logger.info(message)
            return (ResultCode.OK, message)

        # PROTECTED REGION END #    //  FspPssSubarray.init_device

    def always_executed_hook(self):
        # PROTECTED REGION ID(FspPssSubarray.always_executed_hook) ENABLED START #
        """hook before any commands"""
        pass
        # PROTECTED REGION END #    //  FspPssSubarray.always_executed_hook

    def delete_device(self):
        # PROTECTED REGION ID(FspPssSubarray.delete_device) ENABLED START #
        """Set Idle, remove all receptors, turn device OFF"""
        pass
        # PROTECTED REGION END #    //  FspPssSubarray.delete_device

    # ------------------
    # Attributes methods
    # ------------------

    def read_receptors(self):
        # PROTECTED REGION ID(FspPssSubarray.receptors_read) ENABLED START #
        """return receptros attribute.(array of int)"""
        return self._receptors
        # PROTECTED REGION END #    //  FspPssSubarray.receptors_read

    def read_searchBeams(self):
        # PROTECTED REGION ID(FspPssSubarray.searchBeams_read) ENABLED START #
        """Return searchBeams attribute (JSON)"""
        return self._search_beams
        # PROTECTED REGION END #    //  FspPssSubarray.searchBeams_read

    def read_searchBeamID(self):
        # PROTECTED REGION ID(FspPssSubarray.read_searchBeamID ENABLED START #
        """REturn list of SearchBeam IDs(array of int). (From searchBeams JSON)"""
        return self._search_beam_id
        # PROTECTED REGION END #    //  FspPssSubarray.read_searchBeamID

    def read_searchWindowID(self):
        # PROTECTED REGION ID(CbfSubarrayPssConfig.read_searchWindowID) ENABLED START #
        """Return searchWindowID attribtue(array of int)"""
        return self._search_window_id
        # PROTECTED REGION END #    //  CbfSubarrayPssConfig.read_searchWindowID

    def read_outputEnable(self):
        # PROTECTED REGION ID(CbfSubarrayPssConfig.read_outputEnable) ENABLED START #
        """Enable/Disable transmission of the output products"""
        return self._output_enable
        # PROTECTED REGION END #    //  CbfSubarrayPssConfig.read_outputEnable

    # --------
    # Commands
    # --------

    def _add_receptors(self, receptorIDs):
        """add specified receptors to the FSP subarray. Input is array of int."""
        self.logger.debug("_AddReceptors")
        errs = []  # list of error messages
        receptor_to_vcc = dict(
            [*map(int, pair.split(":"))]
            for pair in self._proxy_cbf_controller.receptorToVcc)
        for receptorID in receptorIDs:
            try:
                vccID = receptor_to_vcc[receptorID]
                subarrayID = self._proxies_vcc[vccID - 1].subarrayMembership

                # only add receptor if it belongs to the CBF subarray
                if subarrayID != self._subarray_id:
                    errs.append(
                        "Receptor {} does not belong to subarray {}.".format(
                            str(receptorID), str(self._subarray_id)))
                else:
                    if receptorID not in self._receptors:
                        self._receptors.append(receptorID)
                    else:
                        # TODO: this is not true if more receptors can be
                        #       specified for the same search beam
                        log_msg = "Receptor {} already assigned to current FSP subarray.".format(
                            str(receptorID))
                        self.logger.warn(log_msg)

            except KeyError:  # invalid receptor ID
                errs.append("Invalid receptor ID: {}".format(receptorID))

        if errs:
            msg = "\n".join(errs)
            self.logger.error(msg)
            tango.Except.throw_exception("Command failed", msg,
                                         "AddReceptors execution",
                                         tango.ErrSeverity.ERR)
        # PROTECTED REGION END #    //  FspPssSubarray.AddReceptors

    def _remove_receptors(self, argin):
        """Remove Receptors. Input is array of int"""
        self.logger.debug("_remove_receptors")
        for receptorID in argin:
            if receptorID in self._receptors:
                self._receptors.remove(receptorID)
            else:
                log_msg = "Receptor {} not assigned to FSP subarray. "\
                    "Skipping.".format(str(receptorID))
                self.logger.warn(log_msg)

    def _remove_all_receptors(self):
        self._remove_receptors(self._receptors[:])

    # --------
    # Commands
    # --------

    class ConfigureScanCommand(CspSubElementObsDevice.ConfigureScanCommand):
        """
        A class for the FspPssSubarray's ConfigureScan() command.
        """
        """Input a serilized JSON object. """
        def do(self, argin):
            """
            Stateless hook for ConfigureScan() command functionality.

            :param argin: The configuration as JSON formatted string
            :type argin: str

            :return: A tuple containing a return code and a string
                message indicating status. The message is for
                information purpose only.
            :rtype: (ResultCode, str)
            :raises: ``CommandError`` if the configuration data validation fails.
            """

            device = self.target

            argin = json.loads(argin)

            # Configure receptors.
            self.logger.debug("_receptors = {}".format(device._receptors))

            device._fsp_id = argin["fsp_id"]
            device._search_window_id = int(argin["search_window_id"])

            self.logger.debug("_search_window_id = {}".format(
                device._search_window_id))

            for searchBeam in argin["search_beam"]:

                if len(searchBeam["receptor_ids"]) != 1:
                    # TODO - to add support for multiple receptors
                    msg = "Currently only 1 receptor per searchBeam is supported"
                    self.logger.error(msg)
                    return (ResultCode.FAILED, msg)

                device._add_receptors(map(int, searchBeam["receptor_ids"]))
                self.logger.debug("device._receptors = {}".format(
                    device._receptors))
                device._search_beams.append(json.dumps(searchBeam))

                device._search_beam_id.append(int(
                    searchBeam["search_beam_id"]))

            # TODO: _output_enable is not currently set

            # TODO - possibly move validation of params to
            #        validate_input()
            # (result_code, msg) = self.validate_input(argin) # TODO

            result_code = ResultCode.OK  # TODO  - temp - remove
            msg = "Configure command completed OK"  # TODO temp, remove

            if result_code == ResultCode.OK:
                # store the configuration on command success
                device._last_scan_configuration = argin
                msg = "Configure command completed OK"

            return (result_code, msg)

        def validate_input(self, argin):
            """
            Validate the configuration parameters against allowed values, as needed.

            :param argin: The JSON formatted string with configuration for the device.
            :type argin: 'DevString'
            :return: A tuple containing a return code and a string message.
            :rtype: (ResultCode, str)
            """
            device = self.target
            return (ResultCode.OK,
                    "ConfigureScan arguments validation successfull")

    @command(
        dtype_in='DevString',
        doc_in="JSON formatted string with the scan configuration.",
        dtype_out='DevVarLongStringArray',
        doc_out=
        "A tuple containing a return code and a string message indicating status. "
        "The message is for information purpose only.",
    )
    @DebugIt()
    def ConfigureScan(self, argin):
        # PROTECTED REGION ID(Vcc.ConfigureScan) ENABLED START #
        """
        Configure the observing device parameters for the current scan.

        :param argin: JSON formatted string with the scan configuration.
        :type argin: 'DevString'

        :return: A tuple containing a return code and a string message indicating status.
            The message is for information purpose only.
        :rtype: (ResultCode, str)
        """
        command = self.get_command_object("ConfigureScan")
        (return_code, message) = command(argin)
        return [[return_code], [message]]

    class GoToIdleCommand(CspSubElementObsDevice.GoToIdleCommand):
        """
        A class for the FspPssSubarray's GoToIdle command.
        """
        def do(self):
            """
            Stateless hook for GoToIdle() command functionality.

            :return: A tuple containing a return code and a string
                message indicating status. The message is for
                information purpose only.
            :rtype: (ResultCode, str)
            """

            self.logger.debug("Entering GoToIdleCommand()")

            device = self.target

            # initialize attribute values
            device._search_beams = []
            device._search_window_id = 0
            device._search_beam_id = []
            device._output_enable = 0
            device._scan_id = 0
            device._config_id = ""

            device._remove_all_receptors()

            if device.state_model.obs_state == ObsState.IDLE:
                return (ResultCode.OK,
                        "GoToIdle command completed OK. Device already IDLE")

            return (ResultCode.OK, "GoToIdle command completed OK")
Beispiel #27
0
class DCP3000(Device):

    green_mode = GreenMode.Asyncio

    url = device_property(dtype=str)
    baudrate = device_property(dtype=int, default_value=9600)
    bytesize = device_property(dtype=int, default_value=8)
    parity = device_property(dtype=str, default_value="N")

    dcp = None

    def url_to_connection_args(self):
        url = self.url
        res = urllib.parse.urlparse(url)
        kwargs = dict(concurrency="async")
        if res.scheme in {"serial", "rfc2217"}:
            kwargs.update(
                dict(baudrate=self.baudrate,
                     bytesize=self.bytesize,
                     parity=self.parity))
        return url, kwargs

    async def init_device(self):
        await super().init_device()
        url, kwargs = self.url_to_connection_args()
        conn = connection_for_url(url, **kwargs)
        self.dcp = dcp3000.DCP3000(conn)
        self.last_values = {}

    async def read_attr_hardware(self, indexes):
        multi_attr = self.get_device_attr()
        names = [
            multi_attr.get_attr_by_ind(index).get_name().lower()
            for index in indexes
        ]
        funcs = (ATTR_MAP[name] for name in names)
        values = [await func(self.dcp) for func in funcs]
        self.last_values = dict(zip(names, values))

    async def dev_state(self):
        state = DevState.ON
        try:
            errors = await self.dcp.errors()
            if errors:
                state = DevState.ALARM
        except:
            state = DevState.FAULT
        return state

    async def dev_status(self):
        self.__status = "Ready!"
        try:
            errors = await self.dcp.errors()
            if errors:
                self.__status = "Hardware error(s):\n" + "\n".join(errors)
        except Exception as error:
            self.__status = "Communication error:\n{!r}".format(error)
        return self.__status

    @attribute(unit="mbar")
    def pressure(self):
        return self.last_values["pressure"]

    @attribute(unit="mbar", dtype=[float], max_dim_x=8)
    def transducer_pressures(self):
        return self.last_values["transducer_pressures"]

    @attribute(unit="mbar")
    def transducer_pressure_1(self):
        return self.last_values["transducer_pressure_1"]

    @attribute(unit="mbar")
    def transducer_pressure_2(self):
        return self.last_values["transducer_pressure_2"]

    @attribute(unit="mbar")
    def transducer_pressure_3(self):
        return self.last_values["transducer_pressure_3"]

    @attribute(unit="mbar")
    def transducer_pressure_4(self):
        return self.last_values["transducer_pressure_4"]

    @attribute(dtype=[str])
    def errors(self):
        return self.last_values["errors"]

    @attribute(dtype=str)
    def version(self):
        return self.last_values["version"]

    @attribute()
    def on_setpoint_1(self):
        return self.last_values["on_setpoint_1"]

    @on_setpoint_1.setter
    def on_setpoint_1(self, value):
        return self.dcp.on_setpoint(1, value)

    @attribute()
    def on_setpoint_2(self):
        return self.last_values["on_setpoint_2"]

    @on_setpoint_2.setter
    def on_setpoint_2(self, value):
        return self.dcp.on_setpoint(2, value)

    @attribute()
    def on_setpoint_3(self):
        return self.last_values["on_setpoint_3"]

    @on_setpoint_3.setter
    def on_setpoint_3(self, value):
        return self.dcp.on_setpoint(3, value)

    @attribute()
    def on_setpoint_4(self):
        return self.last_values["on_setpoint_4"]

    @on_setpoint_4.setter
    def on_setpoint_4(self, value):
        return self.dcp.on_setpoint(4, value)

    @attribute()
    def off_setpoint_1(self):
        return self.last_values["off_setpoint_1"]

    @off_setpoint_1.setter
    def off_setpoint_1(self, value):
        return self.dcp.off_setpoint(1, value)

    @attribute()
    def off_setpoint_2(self):
        return self.last_values["off_setpoint_2"]

    @off_setpoint_2.setter
    def off_setpoint_2(self, value):
        return self.dcp.off_setpoint(2, value)

    @attribute()
    def off_setpoint_3(self):
        return self.last_values["off_setpoint_3"]

    @off_setpoint_3.setter
    def off_setpoint_3(self, value):
        return self.dcp.off_setpoint(3, value)

    @attribute()
    def off_setpoint_4(self):
        return self.last_values["off_setpoint_4"]

    @off_setpoint_4.setter
    def off_setpoint_4(self, value):
        return self.dcp.off_setpoint(4, value)

    @command
    def switch_on(self):
        return self.dcp.switch_on()

    @command
    def switch_off(self):
        return self.dcp.switch_off()

    @command
    def open_venting_valve(self):
        return self.dcp.open_venting_value()

    @command
    def close_venting_valve(self):
        return self.dcp.close_venting_valve()

    @command
    def vent(self):
        return self.dcp.vent()
class  AgilisAGAP(Device):

    Address = device_property(
        dtype='int16',
    )
    Port = device_property(
        dtype='str',
    )

# some Constants
    __AXIS_X = 'U'
    __AXIS_Y = 'V'

# Errors from page 64 of the manual
    __ERROR_NEG_END_OF_RUN = 1
    __ERROR_POS_END_OF_RUN = 2
    __ERROR_OUT_OF_RANGE   = ('G', 'C')

# States from page 65 of the manual
    __STATE_READY   = ('32', '33', '34', '35', '36')
    __STATE_MOVING  = ('28', '29')
    
    position_x = attribute(
        label='Position X',
        dtype='float',
        access=AttrWriteType.READ_WRITE,
        format="%4.3f",
        doc = 'absolute position X'
    )
    position_y = attribute(
        label='Position Y',
        dtype='float',
        access=AttrWriteType.READ_WRITE,
        format="%4.3f",
        doc = 'absolute position Y'
    )

    def init_device(self):
        Device.init_device(self)

        self.set_state(DevState.INIT)
        try:
            self.info_stream("Connecting to AgilisAGAP on port: {:s} ...".format(self.Port))
            self.serial = serial.Serial(
                port = self.Port,
                baudrate = 921600,
                bytesize = 8,
                stopbits = 1,
                parity = 'N',
                xonxoff = True,
                timeout = 0.05)
            if self.serial.isOpen():
                self.serial.close()
            self.serial.open()
            self.info_stream("Success!")
            self.info_stream('Connection established:\n{:s}\n{:s}'.format(self.query('ID?'), self.query('VE?')))
        except:
            self.error_stream("Cannot connect!")
            self.set_state(DevState.OFF)
       
        self.set_state(DevState.ON)        

    def delete_device(self):
        if self.serial.isOpen():
            self.serial.close()
            self.info_stream('Connection closed for port {:s}'.format(self.Port))

    def always_executed_hook(self):
        res = self.query('TS?')
        if (res != ''):
            err = int(res[:4],16)
            state = res[4:]
            if (state in self.__STATE_MOVING):
                self.set_status('Device is MOVING')
                self.set_state(DevState.MOVING)
            elif (state in self.__STATE_READY):
                self.set_status('Device is ON')
                self.set_state(DevState.ON)
            else:
                self.set_status('Device is UNKOWN')
                self.set_state(DevState.UNKNOWN)

    def read_position_x(self):
        return float(self.query('TP' + self.__AXIS_X + '?'))

    def write_position_x(self, value):
        self.query('PA' + self.__AXIS_X + str(value))
        err = self.get_cmd_error_string()
        if err in self.__ERROR_OUT_OF_RANGE:
            Except.throw_exception('x position out of range',
                'x position out of range',
                'write_position_x')
        else:
            self.set_state(DevState.MOVING)  

    def read_position_y(self):
        return float(self.query('TP' + self.__AXIS_Y + '?'))

    def write_position_y(self, value):
        self.query('PA' + self.__AXIS_Y + str(value))
        err = self.get_cmd_error_string()
        if err in self.__ERROR_OUT_OF_RANGE:
            Except.throw_exception('y position out of range',
                'y position out of range',
                'write_position_y')
        else:
            self.set_state(DevState.MOVING)
        
    @command
    def Stop(self):
        self.query('ST')
        
    @command()    
    def Reset(self):
        self.query('RS')

    def query(self, cmd):
        prefix = str(self.Address) + cmd[:-1]
        self.send_cmd(cmd)
        answer = self.serial.readline().decode('utf-8')
        if answer.startswith(prefix):
           answer = answer[len(prefix):].strip()
        else:
           answer = ''
        return answer
    
    def send_cmd(self, cmd):
        cmd = str(self.Address) + cmd + '\r\n'
        self.serial.flushInput()
        self.serial.flushOutput()
        self.serial.write(cmd.encode('utf-8'))
        self.serial.flush()                  

    def get_cmd_error_string(self):
        error = self.query('TE?')
        return error.strip()
class TemplateDeviceServer(Device):
    '''
    This docstring should describe your Tango Class and optionally
    what it depends on (drivers etc).
    '''

    # ------ Attributes ------ #

    humidity = attribute(label='Humidity',
                         dtype=float,
                         access=AttrWriteType.READ,
                         doc='Example for an attribute that can only be read.')

    # optionally use fget/fset to point to read and write functions.
    # Default is "read_temperature"/"write_temperature".
    # Added some optional attribute properties.
    temperature = attribute(label='Temperature',
                            fget='get_temperature',
                            dtype=float,
                            access=AttrWriteType.READ_WRITE,
                            display_level=DispLevel.EXPERT,
                            min_value=-273.15,
                            min_alarm=-100,
                            max_alarm=100,
                            min_warning=-50,
                            max_warning=50,
                            unit='C',
                            format="8.4f",
                            doc='Attribute that can be read/written.')

    # ------ Device Properties ------ #
    # device_properties will be set once per family-member and usually -
    # contain serial numbers or a certain port-ID that needs to be set once -
    # and will not change while the server is running.

    port = device_property(dtype=int, default_value=10000)

    # ------ default functions that are inherited from parent "Device" ------ #
    def init_device(self):
        Device.init_device(self)
        self.info_stream('Connection established')  # prints this line while -
        # in logging mode "info" or lower
        self.set_state(DevState.ON)

        # here you could initiate first contact to the hardware (driver)

        self.__temp = 0  # declaring values for the attributes if needed
        self.__humid = 0

    def delete_device(self):
        self.set_state(DevState.OFF)
        self.error_stream('A device was deleted!')  # prints this line while -
        # in logging mode "error" or lower.

    # define what is executed when Tango checks for the state.
    # Here you could inquire the state of the hardware and not just -
    # (as it is in default) of the TDS.
    # Default returns state but also sets state from ON to ALARM if -
    # some attribute alarm limits are surpassed.
    def dev_state(self):
        # possible pseudo code:
        # if hardware-state and TDS-state is ON:
        #   return DevState.ON
        # else:
        #   return DevState.FAULT
        return DevState

    def always_executed_hook(self):
        # a method that is executed continuously and by default does nothing.
        # if you want smth done polled/continuously, put it in this method.
        # check connection to hardware or whether status is acceptable etc.
        pass

# ------ Read/Write functions ------ #

    def read_humidity(self):  # this is default to read humidity
        return self.__humid  # returns the value of the "humidity" attr.

    def get_temperature(self):  # this was set by fget in attribute declaration
        return self.__temp

    def write_temperature(self, value):
        # possibly execute some function here to talk to the hardware -
        # (e.g. set temperature with a thermostat)
        self.__temp = value  # update the declared server value of the attr.

# ------ Internal Methods ------ #
# method that works with multiple input parameters only "inside" this code

    def internal_method(self, param1, param2):
        # do something with param1, param2
        pass

# ------ COMMANDS ------ #

    @DebugIt()  # let the execution of this command be logged in debugging mode
    @command()  # make method executable through the client -
    # (as opposed to just callable inside this code)
    def external_method(self, param):
        # this kind of method only allows one input parameter
        pass

    # more examples of externally executable methods
    @command()
    def turn_off(self):
        self.set_state(DevState.OFF)

    @command()
    def turn_on(self):
        self.set_state(DevState.ON)
Beispiel #30
0
class EC301DS(Device):
    """ An SRS EC301 device

       Device States Description:
    #
    #   DevState.ON :     The device is in operation
    #   DevState.INIT :   Initialisation of the communication with the device and initial configuration
    #   DevState.FAULT :  The Device has a problem and cannot handle further requests.
    #   DevState.MOVING : The Device is engaged in an acquisition.
    """

    ### Properties ###

    Host = device_property(dtype=str,
                           default_value="b-nanomax-ec301-0",
                           doc="hostname")
    Port = device_property(dtype=int, default_value=1680)

    ### Attributes ###

    @attribute(label='Voltage',
               dtype=float,
               doc='Single voltage measurement',
               unit='V',
               format='1.3f')
    def voltage(self):
        return self.ec301.voltage

    @attribute(label='Current',
               dtype=float,
               doc='Single current measurement',
               unit='A',
               format='.3e')
    def current(self):
        return self.ec301.current

    @attribute(label='ID', dtype=str, doc='Device ID string')
    def id(self):
        return self.ec301.id

    @attribute(label='Error', dtype=str, doc='Last error message')
    def error(self):
        return self.ec301.error

    @attribute(label='Running', dtype=bool, doc='acquiring/scanning')
    def running(self):
        return self.ec301.running

    @attribute(label='Mode', dtype=str, doc='Control mode')
    def mode(self):
        return self.ec301.mode

    @mode.write
    def mode(self, mod):
        self.ec301.mode = mod

    @attribute(
        label='Enabled',
        dtype=bool,
        doc=
        'Cell enabled? Querying gives false if the front panel switch is out.')
    def enabled(self):
        return self.ec301.enabled

    @enabled.write
    def enabled(self, stat):
        self.ec301.enabled = stat

    @attribute(label='I Range', dtype=int, doc='Current range as log(range/A)')
    def Irange(self):
        return self.ec301.Irange

    @Irange.write
    def Irange(self, rng):
        self.ec301.Irange = rng

    @attribute(label='E Range',
               dtype=int,
               doc='Potential range (2, 5, or 15)',
               unit='V')
    def Erange(self):
        return self.ec301.Erange

    @Erange.write
    def Erange(self, rng):
        self.ec301.Erange = rng

    @attribute(label='Autorange', dtype=bool, doc='Autorange on/off')
    def autorange(self):
        return self.ec301.autorange

    @autorange.write
    def autorange(self, val):
        self.ec301.autorange = val

    @attribute(label='Averaging', dtype=int, doc='Sample averaging')
    def averaging(self):
        return self.ec301.averaging

    # should perhaps be an enum
    @averaging.write
    def averaging(self, avg):
        self.ec301.averaging = avg

    @attribute(label='Bandwidth',
               dtype=int,
               doc='Control loop bandwidth as log(bw/Hz)')
    def bandwidth(self):
        return self.ec301.bandwidth

    @bandwidth.write
    def bandwidth(self, bw):
        self.ec301.bandwidth = bw

    @attribute(label='I lowpass 10kHz',
               dtype=bool,
               doc='Enables 10 kHz low-pass filter in front of I ADC')
    def Ilowpass(self):
        return self.ec301.Ilowpass

    @Ilowpass.write
    def Ilowpass(self, val):
        self.ec301.Ilowpass = val

    @attribute(label='E lowpass 10kHz',
               dtype=bool,
               doc='Enables 10 kHz low-pass filter in front of E ADC')
    def Elowpass(self):
        return self.ec301.Elowpass

    @Elowpass.write
    def Elowpass(self, val):
        self.ec301.Elowpass = val

    @attribute(label='Compliance limit',
               dtype=float,
               doc='Limit on the compliance voltage',
               unit='V')
    def compliance_limit(self):
        return self.ec301.compliance_limit

    @compliance_limit.write
    def compliance_limit(self, val):
        self.ec301.compliance_limit = val

    ### Commands ###

    @command(dtype_in=float)
    def setPotential(self, pot):
        self.ec301.setPotential(pot)

    @command(dtype_in=float)
    def setCurrent(self, cur):
        self.ec301.setCurrent(cur)

    @command(dtype_in=str)
    def acquire(self, arg_list):
        arg_list = arg_list.strip()
        time, trigger = [eval(s) for s in arg_list.split()]
        self.ec301.acquire(time, trigger)

    @command(dtype_in=str)
    def potentialStep(self, arg_list):
        arg_list = arg_list.strip()
        t0, t1, E0, E1, trigger, full_bandwidth, return_to_E0 = [
            eval(s) for s in arg_list.split()
        ]
        self.ec301.potentialStep(t0, t1, E0, E1, trigger, full_bandwidth,
                                 return_to_E0)

    @command(dtype_in=str)
    def potentialCycle(self, arg_list):
        arg_list = arg_list.strip()
        t0, E0, E1, E2, v, cycles, trigger = [
            eval(s) for s in arg_list.split()
        ]
        self.ec301.potentialCycle(t0, E0, E1, E2, v, cycles, trigger)

    @command()
    def stop(self):
        self.ec301.stop()

    @command(dtype_out=(float, ))
    def readout_t(self):
        t, E, I, aux, raw = self.ec301.readout()
        return t

    @command(dtype_out=(float, ))
    def readout_E(self):
        t, E, I, aux, raw = self.ec301.readout()
        return E

    @command(dtype_out=(float, ))
    def readout_I(self):
        t, E, I, aux, raw = self.ec301.readout()
        return I

    @command(dtype_out=(float, ))
    def readout_sync_adc(self):
        t, E, I, aux, raw = self.ec301.readout()
        return aux

    @command(dtype_out=(float, ))
    def readout_raw(self):
        t, E, I, aux, raw = self.ec301.readout()
        return raw

    ### Other stuff ###

    # Device methods
    def init_device(self):
        """Instantiate device object, do initial instrument configuration."""
        self.set_state(DevState.INIT)

        try:
            self.get_device_properties()
            self.ec301 = ec301lib.EC301(host=self.Host, port=self.Port)

        except Exception as e:
            self.set_state(DevState.FAULT)
            self.set_status('Device failed at init: %s' % e.message)

        self.set_state(DevState.ON)

    # This sets the state before every command
    def always_executed_hook(self):
        if self.ec301.running:
            self.set_state(DevState.MOVING)
        else:
            self.set_state(DevState.ON)