Adaptor, with dynamic attribute

#!/usr/bin/env python
#
# Exports
#  Commands:
#    StopMove
#    Calibrate
#
#  Attributes:
#    Position
#    SlewRate
#    UnitLimitMax
#    UnitLimitMin
#    CwLimit
#    CcwLimit
#
# Property:
#   DynamicAttributes: SlewRate,int,rw
#
import PyTango, HasyUtils, inspect

class VM:
    #
    # init_device
    #
    def __init__( self):
        self.parent = inspect.currentframe().f_back.f_locals['self']
        self.parentProxy = PyTango.DeviceProxy( self.parent.get_name())
        AdaptedMotor = HasyUtils.getDeviceProperty( self.parent.get_name(), "AdaptedMotor")[0]
        if AdaptedMotor is None:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.parent.get_name(),
                "failed to find AdaptedMotor property", 
                "VmExecutor")
        try:
            self.adaptedMotorProxy = PyTango.DeviceProxy( AdaptedMotor)
        except:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.parent.get_name(),
                "failed to create proxy to %s" % AdaptedMotor, 
                "VmExecutor")
        #
        # translate position
        #
        if hasattr( self.adaptedMotorProxy, "Position"):
            self.position = "Position"
        else:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "failed to find Position", 
                "VmExecutor")
        #
        # translate slewrate
        #
        if hasattr( self.adaptedMotorProxy, "SlewRate"):
            self.slewRate = "SlewRate"
        elif hasattr( self.adaptedMotorProxy, "Velocity"):
            self.slewRate = "Velocity"
        else:
            self.slewRate = None
        #
        # translate UnitLimitMin, ~Max
        #
        if hasattr( self.adaptedMotorProxy, "UnitLimitMax"):
            self.unitLimitMax = "UnitLimitMax"
        elif hasattr( self.adaptedMotorProxy, "SoftCwLimit"):
            self.unitLimitMax = "SoftCwLimit"
        else:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "failed to find UnitLimitMax", 
                "VmExecutor")
        if hasattr( self.adaptedMotorProxy, "UnitLimitMin"):
            self.unitLimitMin = "UnitLimitMin"
        elif hasattr( self.adaptedMotorProxy, "SoftCcwLimit"):
            self.unitLimitMin = "SoftCcwLimit"
        else:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "failed to find UnitLimitMin", 
                "VmExecutor")
        #
        # translate CwLimit, CcwLimit
        # not condsidered to be critical
        #
        if hasattr( self.adaptedMotorProxy, "CwLimit"):
            self.cwLimit = "CwLimit"
        else:
            self.cwLimit = None

        if hasattr( self.adaptedMotorProxy, "CcwLimit"):
            self.ccwLimit = "CcwLimit"
        else:
            self.ccwLimit = None
        #
        # translate StopMove
        #
        if hasattr( self.adaptedMotorProxy, "StopMove"):
            self.stopMove = "StopMove"
        elif hasattr( self.adaptedMotorProxy, "Stop"):
            self.stopMove = "Stop"
        else:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "failed to find StopMove", 
                "VmExecutor")
        #
        # translate Calibrate
        #
        if hasattr( self.adaptedMotorProxy, "Calibrate"):
            self.calibrate = "Calibrate"
        else:
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "failed to find Calibrate", 
                "VmExecutor")
        return
    #
    # dev_state
    #
    def dev_state( self):
        argout = self.adaptedMotorProxy.state()
        return argout
    #
    # Position
    #
    def read_Position( self):
        return self.adaptedMotorProxy.read_attribute( self.position).value

    def write_Position( self, argin):
        if( argin < self.read_UnitLimitMin() or argin > self.read_UnitLimitMax()):
            PyTango.Except.throw_exception(
                "adaptor %s" % self.adaptedMotorProxy.name(),
                "requested position %g outside limits %g %g " % (self.read_UnitLimitMin(), 
                                                                 self.read_UnitLimitMax()), 
                "VmExecutor")
		
        return self.adaptedMotorProxy.write_attribute( "Position", argin)
    #
    # UnitLimitMax
    #
    def read_UnitLimitMax( self):
        return self.adaptedMotorProxy.read_attribute( self.unitLimitMax).value

    def write_UnitLimitMax( self, argin):
        return self.adaptedMotorProxy.write_attribute( self.unitLimitMax, argin)
    #
    # UnitLimitMin
    #
    def read_UnitLimitMin( self):
        return self.adaptedMotorProxy.read_attribute( self.unitLimitMin).value

    def write_UnitLimitMin( self, argin):
        return self.adaptedMotorProxy.write_attribute( self.unitLimitMin, argin)
    #
    # CwLimit, CcwLimit
    #
    def read_CwLimit( self):
        if self.cwLimit is None:
            return 0
        return self.adaptedMotorProxy.read_attribute( self.cwLimit).value
    def read_CcwLimit( self):
        if self.ccwLimit is None:
            return 0
        return self.adaptedMotorProxy.read_attribute( self.ccwLimit).value

    def read_DynamicAttr( self, name):
        if name.lower() == "slewrate":
            if self.slewRate == None:
                PyTango.Except.throw_exception(
                    "adaptor %s" % self.adaptedMotorProxy.name(),
                    "no interface to SlewRate ",
                    "VmExecutor")
            return self.adaptedMotorProxy.read_attribute( self.slewRate).value

    def write_DynamicAttr( self, name, value):
        if name.lower() == "slewrate":
            if self.slewRate == None:
                PyTango.Except.throw_exception(
                    "adaptor %s" % self.adaptedMotorProxy.name(),
                    "no interface to SlewRate ",
                    "VmExecutor")
            return self.adaptedMotorProxy.write_attribute( self.slewRate, value)
        

    def StopMove( self):
        return self.adaptedMotorProxy.command_inout( self.stopMove)

    def Calibrate(self, argin):
        return self.adaptedMotorProxy.command_inout( self.calibrate, argin)