Example #1
0
class Resolution(Readable):

    valuetype = (float, float)

    attached_devices = {
        'detector': Attach('Detector device with size information',
                           Detector),
        'beamstop': Attach('Beam stop device with size information',
                           BeamStop),
        'detpos': Attach('Detector position device', Readable),
        'wavelength': Attach('Wavelength device', Readable),
    }

    parameter_overrides = {
        'unit': Override(mandatory=False, volatile=True),
        'fmtstr': Override(default='%3.f - %3.f'),
    }

    def doRead(self, maxage=0):
        bs = self._attached_beamstop
        return qrange(self._attached_wavelength.read(maxage),
                      self._attached_detpos.read(0),
                      bs.slots[bs.shape][1][0] / 2.,
                      self._attached_detector.size[0] / 2.)

    def doReadUnit(self):
        unit = self._attached_wavelength.unit
        return '%s-1' % unit
Example #2
0
class MasterSlaveMotor(Moveable):
    """Combined master slave motor with possibility to apply a scale to the
    slave motor."""

    attached_devices = {
        "master": Attach("Master motor controlling the movement", Moveable),
        "slave": Attach("Slave motor following master motor movement",
                        Moveable),
    }

    parameters = {
        "scale":
        Param("Factor applied to master target position as slave "
              "position",
              type=float,
              default=1),
    }

    parameter_overrides = {
        "unit": Override(mandatory=False),
        "fmtstr": Override(default="%.3f %.3f"),
    }

    def _slavePos(self, pos):
        return self.scale * pos

    def doRead(self, maxage=0):
        return [
            self._attached_master.read(maxage),
            self._attached_slave.read(maxage)
        ]

    def doStart(self, pos):
        self._attached_master.move(pos)
        self._attached_slave.move(self._slavePos(pos))

    def doIsAllowed(self, pos):
        faultmsgs = []
        messages = []
        for dev in [self._attached_master, self._attached_slave]:
            allowed, msg = dev.isAllowed(pos)
            msg = dev.name + ': ' + msg
            messages += [msg]
            if not allowed:
                faultmsgs += [msg]
        if faultmsgs:
            return False, ', '.join(faultmsgs)
        return True, ', '.join(messages)

    def doReadUnit(self):
        return self._attached_master.unit

    def valueInfo(self):
        return Value(self._attached_master.name, unit=self.unit,
                     fmtstr=self._attached_master.fmtstr), \
               Value(self._attached_slave.name, unit=self.unit,
                     fmtstr=self._attached_slave.fmtstr)
Example #3
0
class FocusPoint(HasLimits, Moveable):
    attached_devices = {
        'table': Attach('table', Moveable),
        'pivot': Attach('pivot', Readable),
    }

    parameters = {
        'gisansdistance':
        Param('GISANS distance', type=floatrange(0, None), default=10700),
    }

    parameter_overrides = {
        'abslimits': Override(mandatory=True, volatile=False),
    }

    def moveToFocus(self):
        self._attached_table.move(self._calculation())

    def doRead(self, maxage=0):
        return self._attached_table.read(maxage)

    def doStart(self, pos):
        # self.moveToFocus() or move table
        self._attached_table.move(pos)

    def _calculation(self, pivot=None):
        if pivot is None:
            pivot = self._attached_pivot.read(0)
        focus = self.gisansdistance - pivot * self._attached_pivot.grid
        self.log.debug('FocusPoint _calculation focus %f pivot %d', focus,
                       pivot)
        return focus

    def doStatus(self, maxage=0):
        state = self._attached_table.status(maxage)
        if state[0] != status.OK:
            return state
        table = self._attached_table.read()
        focus = self._calculation()
        precision = 0
        if hasattr(self._attached_table, '_attached_device'):
            precision = self._attached_table._attached_device.precision
        elif hasattr(self._attached_table, 'precision'):
            precision = self._attached_table.precision
        else:
            precision = 0
        text = 'focus' if abs(table - focus) <= precision else state[1]
        return status.OK, text
Example #4
0
class SkewRead(Readable):
    """Device having two axes and an inclination.

    The position is the mid between the one and two device.
    """

    attached_devices = {
        'one': Attach('readable device 1', Readable),
        'two': Attach('readable device 2', Readable),
    }

    def _read_devices(self, maxage=0):
        return [d.read(maxage) for d in self._adevs.values()]

    def doRead(self, maxage=0):
        return sum(self._read_devices(maxage)) / 2.
Example #5
0
class DetectorDistance(Readable):
    """Calculate detector distance based on the detector tubes position"""

    attached_devices = {
        'detectubes': Attach('Pilatus detector tubes', Readable, multiple=4)
    }

    parameters = {
        'offset':
        Param('Minimum distance between Pilatus and sample',
              type=int,
              settable=True),
        'tubelength':
        Param('List of tube length',
              type=listof(int),
              settable=False,
              default=[450, 450, 900, 900]),
    }

    hardware_access = False

    def doInit(self, mode):
        self.log.debug('Detector distance init')
        self.read()

    def doRead(self, maxage=0):
        distance = 0
        for tube, l in zip(self._attached_detectubes, self.tubelength):
            # tubes can only be set in correct sequence
            if tube.read(maxage) != 'up':
                break
            distance += l
        return self.offset + distance
Example #6
0
class ChopperBase(DeviceMixinBase):

    attached_devices = {
        'comm': Attach('Communication device', StringIO),
    }

    def _read_controller(self, mvalue):
        # TODO  this has to be fix somehow
        if hasattr(self, 'chopper'):
            what = mvalue % self.chopper
        else:
            what = mvalue
        # self.log.debug('_read_controller what: %s', what)
        res = self._attached_comm.communicate(what)
        res = res.replace('\x06', '')
        # self.log.debug('_read_controller res for %s: %s', what, res)
        return res

    def _read_base(self, what):
        res = self._attached_comm.communicate(what)
        res = res.replace('\x06', '')
        return res

    def _write_controller(self, mvalue, *values):
        # TODO: fix formatting for single values and lists
        # TODO: this has to be fix somehow
        if hasattr(self, 'chopper'):
            what = mvalue % ((self.chopper, ) + values)
        else:
            what = mvalue % (values)
        self.log.debug('_write_controller what: %s', what)
        self._attached_comm.writeLine(what)
Example #7
0
class RateImageChannel(BaseImageChannel):
    """Subclass of the Tango image channel that automatically returns the
    sum of all counts and the momentary count rate as scalar values.
    """

    attached_devices = {
        'timer': Attach('The timer channel', Measurable),
    }

    def doInit(self, mode):
        BaseImageChannel.doInit(self, mode)
        self._rate_data = [0, 0]

    def doReadArray(self, quality):
        narray = BaseImageChannel.doReadArray(self, quality)
        seconds = self._attached_timer.read(0)[0]
        cts = narray.sum()
        rate = calculateRate(self._rate_data, quality, cts, seconds)
        self.readresult = [cts, rate]
        return narray

    def valueInfo(self):
        return (Value(name=self.name + ' (total)', type='counter', fmtstr='%d',
                      errors='sqrt', unit='cts'),
                Value(name=self.name + ' (rate)', type='monitor',
                      fmtstr='%.1f', unit='cps'),)
Example #8
0
class HTFTemperatureController(TemperatureController):

    attached_devices = {
        'maxheater': Attach('Maximum heater output device', AnalogOutput),
    }

    parameters = {
        'maxheateroutput':
        Param('Maximum heater output',
              type=floatrange(0, 100),
              userparam=True,
              settable=True,
              volatile=True,
              unit='%'),
        'sensortype':
        Param('Currently used sensor type',
              type=str,
              userparam=True,
              settable=False,
              volatile=True,
              mandatory=False),
    }

    def doWriteMaxheateroutput(self, value):
        self._attached_maxheater.move(value)

    def doReadMaxheateroutput(self):
        return self._attached_maxheater.read(0)

    def doReadSensortype(self):
        return self._dev.sensortype
Example #9
0
class TubeAngle(HasLimits, Moveable):
    """Angle of the tube controlled by the yoke."""

    attached_devices = {
        'yoke': Attach('Yoke device', Moveable),
    }

    parameters = {
        'yokepos':
        Param('Position of yoke from pivot point',
              type=floatrange(0, 20000),
              unit='mm',
              default=11000),
    }

    parameter_overrides = {
        'abslimits': Override(mandatory=False, volatile=True),
        'unit': Override(mandatory=False, default='deg'),
    }

    def doRead(self, maxage=0):
        return degrees(atan2(self._attached_yoke.read(maxage), self.yokepos))

    def doStart(self, target):
        self._attached_yoke.move(tan(radians(target)) * self.yokepos)

    def doReadAbslimits(self):
        yokelimits = self._attached_yoke.userlimits
        return (degrees(atan2(yokelimits[0], self.yokepos)),
                degrees(atan2(yokelimits[1], self.yokepos)))
Example #10
0
class SkewMotor(Motor):
    """Device moving by using two axes and having a fixed inclination.

    Both axis have a fixed inclination given by the ``skew`` parameter.  The
    position of the devices is given for the middle between both axis.  The
    ``motor_1`` device has always the smaller position value than the
    ``motor_2`` device.

    pos(motor_1) + skew / 2 == pos == pos(motor_2) - skew / 2.
    """

    attached_devices = {
        'motor_1': Attach('moving motor, 1', Moveable),
        'motor_2': Attach('moving motor, 2', Moveable),
    }

    parameters = {
        'skew':
        Param('Skewness of hardware, difference between both motors',
              type=floatrange(0.),
              default=0.,
              settable=True,
              unit='main'),
    }

    def _read_motors(self, maxage=0):
        return self._attached_motor_1.read(maxage), \
            self._attached_motor_2.read(maxage)

    def doRead(self, maxage=0):
        return sum(self._read_motors(maxage)) / 2.

    def doIsAtTarget(self, pos):
        if self.target is None:
            return True
        if not self._attached_motor_1.isAtTarget(pos - self.skew / 2.) or \
           not self._attached_motor_2.isAtTarget(pos + self.skew / 2.):
            return False
        m1, m2 = self._read_motors()
        self.log.debug('%.3f, %.3f, %.3f, %.3f', m1, m2, (m1 + self.skew / 2.),
                       (m2 - self.skew / 2.))
        return abs(m1 - m2 + self.skew) <= self.precision

    def doStart(self, target):
        self._attached_motor_1.move(target - self.skew / 2.)
        self._attached_motor_2.move(target + self.skew / 2.)
Example #11
0
class NOKPosition(PolynomFit, Coder):
    """Device to read the current Position of a NOK.

    The Position is determined by a ratiometric measurement between two
    analogue voltages measured with i7000 modules via taco.

    As safety measure, the reference voltage obtained is checked to be in some
    configurable limits.
    """

    attached_devices = {
        'measure': Attach('Sensing Device (Poti)', Readable),
        'reference': Attach('Reference Device', Readable),
    }

    parameters = {
        'length': Param('Length... ????', type=float, mandatory=False),
        # fun stuff, not really needed....
        'serial': Param('Serial number', type=int, mandatory=False),
    }

    parameter_overrides = {
        'fmtstr': Override(default='%.3f'),
        'unit': Override(default='mm', mandatory=False),
    }

    def doReset(self):
        multiReset(self._adevs)

    def doRead(self, maxage=0):
        """Read basically two (scaled) voltages.

         - value from the poti (times a sign correction for top mounted potis)
         - ref from a reference voltage, scaled by 2 (Why???)

        Then it calculates the ratio poti / ref.
        Then this is put into a correcting polynom of at least first order
        Result is then offset + mul * <previously calculated value>
        """
        poti = self._attached_measure.read(maxage)
        ref = self._attached_reference.read(maxage)

        self.log.debug('Poti vs. Reference value: %f / %f', poti, ref)
        # apply simple scaling
        return self._fit(poti / ref)
Example #12
0
class DNSDetector(Detector):
    """Detector supporting different presets for spin flipper on or off."""

    attached_devices = {
        'flipper': Attach('Spin flipper device which will be read out '
                          'with respect to setting presets.', BaseFlipper),
    }

    def _getWaiters(self):
        waiters = self._adevs.copy()
        del waiters['flipper']
        return waiters

    def doTime(self, preset):
        if P_TIME in preset:
            return preset[P_TIME]
        elif P_TIME_SF in preset and self._attached_flipper.read() == ON:
            return preset[P_TIME_SF]
        elif P_TIME_NSF in preset and self._attached_flipper.read() == OFF:
            return preset[P_TIME_NSF]
        return 0  # no preset that we can estimate found

    def presetInfo(self):
        presets = Detector.presetInfo(self)
        presets.update((P_TIME_SF, P_TIME_NSF, P_MON_SF, P_MON_NSF))
        return presets

    def doSetPreset(self, **preset):
        new_preset = preset
        if P_MON_SF in preset and P_MON_NSF in preset:
            if self._attached_flipper.read() == ON:
                m = preset[P_MON_SF]
            else:
                m = preset[P_MON_NSF]
            new_preset = {P_MON: m}
        elif P_MON_SF in preset or P_MON_NSF in preset:
            self.log.warning('Incorrect preset setting. Specify either both '
                             '%s and %s or only %s.',
                             P_MON_SF, P_MON_NSF, P_MON)
            return
        elif P_TIME_SF in preset and P_TIME_NSF in preset:
            if self._attached_flipper.read() == ON:
                t = preset[P_TIME_SF]
            else:
                t = preset[P_TIME_NSF]
            new_preset = {P_TIME: t}
        elif P_TIME_SF in preset or P_TIME_NSF in preset:
            self.log.warning('Incorrect preset setting. Specify either both '
                             '%s and %s or only %s.',
                             P_TIME_SF, P_TIME_NSF, P_TIME)
            return
        elif P_MON in preset:
            new_preset = {P_MON: preset[P_MON]}
        elif P_TIME in preset:
            new_preset = {P_TIME: preset[P_TIME]}
        Detector.doSetPreset(self, **new_preset)
Example #13
0
class Timer(VirtualTimer):
    """Timer starts detector via digital IO."""

    attached_devices = {
        'digitalio': Attach('Timer channel', Moveable),
    }

    def _counting(self):
        self._attached_digitalio.move(1)
        VirtualTimer._counting(self)
        self._attached_digitalio.move(0)
Example #14
0
class ReadonlySwitcher(MappedReadable):
    """Same as the `Switcher`, but for read-only underlying devices."""

    attached_devices = {
        'readable': Attach('The continuous device which is read', Readable),
    }

    parameters = {
        'precision':
        Param('Precision for comparison', type=floatrange(0), default=0),
    }

    parameter_overrides = {
        'fallback': Override(userparam=False,
                             type=none_or(str),
                             mandatory=False),
    }

    hardware_access = False

    def _readRaw(self, maxage=0):
        return self._attached_readable.read(maxage)

    def _mapReadValue(self, pos):
        prec = self.precision
        for name, value in iteritems(self.mapping):
            if prec:
                if abs(pos - value) <= prec:
                    return name
            elif pos == value:
                return name
        if self.fallback is not None:
            return self.fallback
        raise PositionError(self,
                            'unknown position of %s' % self._attached_readable)

    def doStatus(self, maxage=0):
        # if the underlying device is moving or in error state,
        # reflect its status
        move_status = self._attached_readable.status(maxage)
        if move_status[0] not in (status.OK, status.WARN):
            return move_status
        # otherwise, we have to check if we are at a known position,
        # and otherwise return an error status
        try:
            if self.read(maxage) == self.fallback:
                return status.NOTREACHED, 'unconfigured position of %s or '\
                    'still moving' % self._attached_readable
        except PositionError as e:
            return status.NOTREACHED, str(e)
        return status.OK, ''

    def doReset(self):
        self._attached_readable.reset()
Example #15
0
class CollimatorLoverD(Readable):
    """Special device related to the L over d relation."""

    attached_devices = {
        'l': Attach('Distance device', Readable),
        'd': Attach('Pinhole', Readable),
    }

    def doInit(self, mode):
        if self._attached_l.unit != self._attached_d.unit:
            raise ConfigurationError(
                self, 'different units for L and d '
                '(%s vs %s)' % (self._attached_l.unit, self._attached_d.unit))

    def doRead(self, maxage=0):
        try:
            ret = float(self._attached_l.read(maxage)) / \
                float(self._attached_d.read(maxage))
        except ValueError:
            ret = 0
        return ret
Example #16
0
class BeamStopDevice(Readable):
    attached_devices = {
        'att': Attach('VSD device', Readable),
    }

    def doRead(self, maxage=0):
        return self._attached_att.read(maxage)

    def doStatus(self, maxage=0):
        if self._attached_att.read(maxage) < 0.01:
            return status.ERROR, 'VSD disconected'
        return status.OK, ''
Example #17
0
class RealFlightPath(Readable):
    attached_devices = {
        'table': Attach('port to read real table', Readable),
        'pivot': Attach('port to read real pivot', Readable),
    }

    parameter_overrides = {
        'unit': Override(volatile=True, mandatory=False),
    }

    def doRead(self, maxage=0):
        table = self._attached_table.read(maxage)
        pivot = self._attached_pivot.read(maxage)
        self.log.debug('table=%s, pivot=%s', table, pivot)
        # in meter
        D = (table + pivot * self._attached_pivot.grid + pre_sample_path) / 1e3
        self.log.debug('D=%.2f %s', D, self.unit)
        return D

    def doReadUnit(self):
        return 'm'
Example #18
0
class GeometricBlur(Readable):
    """Special device to calculate geometric blur.

    Calculated from collimation and sample to detector distance."""

    attached_devices = {
        'l': Attach('Distance device', Readable),
        'd': Attach('Pinhole', Readable),
        'sdd': Attach('Sample Detector Distance', Readable),
    }

    parameter_overrides = {
        'unit': Override(volatile=True, mandatory=False),
    }

    def doInit(self, mode):
        units = set(d.unit for d in self._adevs.values())
        if len(units) != 1:
            raise ConfigurationError(
                self, 'different units for L, d and sdd '
                '(%s vs %s vs %s)' %
                (self._attached_l.unit, self._attached_d.unit,
                 self._attached_sdd.unit))
        if 'mm' not in units:
            raise ConfigurationError(
                self, "attached devices units have to be "
                "'mm'")

    def doRead(self, maxage=0):
        try:
            ret = float(self._attached_sdd.read(maxage)) * \
                float(self._attached_d.read(maxage)) / \
                float(self._attached_l.read(maxage))
            return 1000 * ret  # convert to um
        except ValueError:
            ret = 0
        return ret

    def doReadUnit(self):
        return 'um'
Example #19
0
class ArmController(IsController, Device):

    parameters = {
        'minangle':
        Param('Minimum angle between two arms',
              type=floatrange(0, None),
              settable=False,
              userparam=False,
              default=50.),
    }

    attached_devices = {
        'arm1': Attach('Arm 1 device', Moveable),
        'arm2': Attach('Arm 2 device', Moveable),
    }

    parameter_overrides = {
        'lowlevel': Override(default=True),
    }

    def isAdevTargetAllowed(self, adev, adevtarget):
        self.log.debug('%s: %s', adev, adevtarget)
        if adev == self._attached_arm1:
            target = self._attached_arm2.target
            if target is None:
                target = self._attached_arm2.read(0)
            absdiff = target - adevtarget
        else:
            target = self._attached_arm1.target
            if target is None:
                target = self._attached_arm1.read(0)
            absdiff = adevtarget - target
        if absdiff < 0:
            return False, 'Arms will cross.'
        dist = abs(absdiff)
        if dist >= self.minangle:
            return True, ''
        return False, 'Arms become too close to each other: %.3f deg, min. ' \
            'dist is %.3f' % (dist, self.minangle)
Example #20
0
class Resolution(Readable):
    """Calculate the wavelength resolution of the whole instrument.

    The chopper controller device is used to detect the real and virtual
    position of the second disc (chopper2).
    """
    attached_devices = {
        'chopper': Attach('chopper controller device', Readable),
        'flightpath': Attach('Read the real flightpath', Readable),
    }

    parameter_overrides = {
        'unit': Override(volatile=True, mandatory=False),
    }

    def doRead(self, maxage=0):
        return chopper_resolution(
            self._attached_chopper.target['chopper2_pos'],
            self._attached_flightpath.read(maxage))

    def doReadUnit(self):
        return '%'
Example #21
0
class Base(Readable):

    valuetype = str

    attached_devices = {
        'comm': Attach('Communication device', StringIO),
    }

    def doStatus(self, maxage=0):
        return status.OK, ''

    def doRead(self, maxage=0):
        return self._attached_comm.communicate('read')
Example #22
0
class ChopperDisc1(ChopperDisc):

    attached_devices = {
        'discs': Attach('slave choppers', ChopperDisc, multiple=5),
    }

    def doStart(self, target):
        for dev in self._attached_discs:
            dev.start(target)
        ChopperDisc.doStart(self, target)

    def _getWaiters(self):
        return []
Example #23
0
class NarzissSpin(BaseSequencer):

    attached_devices = {
        'pom': Attach('Polariser rotation', Moveable),
        'pmag': Attach('Polariser magnet', Moveable),
    }

    valuetype = oneof('+', '-', '0', 'undefined')

    def _generateSequence(self, target):
        seq = []

        if target == '+':
            seq.append((SeqDev(self._attached_pom,
                               0.8), SeqDev(self._attached_pmag, -2.5)))
            seq.append(SeqSleep(4.))
            seq.append(SeqDev(self._attached_pmag, .15))
        elif target == '-':
            seq.append((SeqDev(self._attached_pom,
                               0.8), SeqDev(self._attached_pmag, 2.5)))
            seq.append(SeqSleep(4.))
            seq.append(SeqDev(self._attached_pmag, 1.))
        elif target == '0':
            seq.append((SeqDev(self._attached_pom,
                               3), SeqDev(self._attached_pmag, 0)))
        else:
            raise ProgrammingError('Invalid value requested')

        return seq

    def doRead(self, maxage=0):
        val = self._attached_pmag.read(maxage)
        if abs(val - .15) < .02:
            return '+'
        if abs(val - 1.) < .05:
            return '-'
        if abs(val - 0) < .05:
            return '0'
        return 'undefined'
Example #24
0
class MotorEncoderDifference(Readable):

    attached_devices = {
        'motor': Attach('moving motor', Moveable),
        'analog': Attach('analog encoder maybe poti', Readable),
    }

    parameters = {
        'absolute':
        Param('Value is absolute or signed.',
              type=bool,
              settable=True,
              default=True),
    }

    def doRead(self, maxage=0):
        dif = self._attached_analog.read(maxage) - \
            self._attached_motor.read(maxage)
        return abs(dif) if self.absolute else dif

    def doStatus(self, maxage=0):
        return status.OK, ''
Example #25
0
class AnalogEncoder(PolynomFit, Readable):

    attached_devices = {
        'device': Attach('Sensing device (poti etc)', Readable),
    }

    def doRead(self, maxage=0):
        """Return a read analogue signal corrected by a polynom.

        A correcting polynom of at least first order is used.
        Result is then offset + mul * <previously calculated value>
        """
        return self._fit(self._attached_device.read(maxage))
Example #26
0
class ListmodeSink(FileSink):
    """Writer for the list mode files via QMesyDAQ itself."""

    attached_devices = {
        'image': Attach('Image device to set the file name', Image),
    }

    parameter_overrides = {
        'settypes': Override(default=[POINT]),
        'filenametemplate': Override(mandatory=False, userparam=False,
                                     default=['D%(pointcounter)07d.mdat']),
    }

    handlerclass = ListmodeSinkHandler
Example #27
0
class AnalogCalc(Coder):

    attached_devices = {
        'device1': Attach('first value for calculation', Readable),
        'device2': Attach('second value for calculation', Readable),
    }

    parameters = {
        'calc':
        Param('choose the calculation',
              type=oneof('mul', 'div', 'add', 'dif'),
              settable=False,
              mandatory=True,
              default='div'),
    }

    def doRead(self, maxage=0):
        """Return a read analogue signal corrected by a polynom.

        A correcting polynom of at least first order is used.
        Result is then offset + mul * <previously calculated value>
        """
        value1 = self._attached_device1.read(maxage)
        value2 = self._attached_device2.read(maxage)

        self.log.info('value 1: %f 2: %f', value1, value2)
        if self.calc == 'mul':
            result = value1 * value2
        elif self.calc == 'div':
            result = value1 / value2
        elif self.calc == 'add':
            result = value1 + value2
        elif self.calc == 'dif':
            result = value1 - value2
        self.log.debug('final result: %f', result)

        return result
Example #28
0
class TriState(CanDisable, Readable):
    attached_devices = {
        'port': Attach('port to read the real number', Readable),
    }

    _enabled = True

    def doRead(self, maxage=0):
        self.log.debug('mode=%s' % self._enabled)
        if self._enabled:
            return self._attached_port.read(maxage)
        return 0

    def doEnable(self, on):
        self._enabled = on
Example #29
0
class DOFlipper(NamedDigitalOutput, Waitable):
    """Flipper controlled via one digital output monitoring power supplies
    status."""

    attached_devices = {
        "powersupplies":
        Attach("Monitored power supplies", Readable, multiple=True),
    }

    def doStatus(self, maxage=0):
        tangoState, tangoStatus = NamedDigitalOutput.doStatus(self, maxage)
        state, status = Waitable.doStatus(self, maxage)
        if tangoState > state:
            state = tangoState
        status = tangoStatus + ', ' + status
        return state, status
Example #30
0
class PollMotor(Motor):

    attached_devices = {
        "polldevs":
        Attach("Devices polled during movement at same interval",
               Readable,
               multiple=True,
               optional=True),
    }

    def _getWaiters(self):
        return []

    def doRead(self, maxage=0):
        for d in self._attached_polldevs:
            d.read(maxage)
        return Motor.doRead(self, maxage)