import PyTango
import sys
import math


class TaurusTest(PyTango.Device_4Impl):

    def __init__(self, cl, name):
        PyTango.Device_4Impl.__init__(self, cl, name)
        TaurusTest.init_device(self)

    def delete_device(self):
        print "[Device delete_device method] for device", self.get_name()

    def init_device(self):
        print "In ", self.get_name(), "::init_device()"
        self.set_state(PyTango.DevState.ON)
        self.get_device_properties(self.get_device_class())
        self._position = 50.0
        self._velocity = 20.0
        self._acceleration = 4.0
        self._simulation_mode = False
        self._abscissas = [x / 50.0 for x in xrange(1024)]
        self._curve = [math.sin(x) for x in self._abscissas]

    def always_executed_hook(self):
        print "In ", self.get_name(), "::always_excuted_hook()"

    def read_attr_hardware(self, data):
        print "In ", self.get_name(), "::read_attr_hardware()"

    def read_Position(self, attr):
        attr.set_value(self._position)

    def write_Position(self, attr):
        self._position = attr.get_write_value()

    def read_Velocity(self, attr):
        attr.set_value(self._velocity)

    def is_Velocity_allowed(self, req_type):
        if req_type == PyTango.AttReqType.WRITE_REQ:
            return True
        return self._velocity < 5

    def write_Velocity(self, attr):
        self._velocity = attr.get_write_value()

    def read_Acceleration(self, attr):
        attr.set_value(self._acceleration)

    def write_Acceleration(self, attr):
        self._acceleration = attr.get_write_value()

    def read_SimulationMode(self, attr):
        attr.set_value(self._simulation_mode)

    def write_SimulationMode(self, attr):
        self._simulation_mode = attr.get_write_value()

    def read_Abscissas(self, attr):
        attr.set_value(self._abscissas)

    def read_Curve(self, attr):
        attr.set_value(self._curve)

    def write_Curve(self, attr):
        self._curve = attr.get_write_value()

    def create_device_cb(self, device_name):
        print "About to create device", device_name

    def CreateTaurusTestDevice(self, device_name):
        klass = self.get_device_class()
        klass.create_device(device_name, cb=self.create_device_cb)

    def DeleteTaurusTestDevice(self, device_name):
        klass = self.get_device_class()
        klass.delete_device(device_name)


class TaurusTestClass(PyTango.DeviceClass):

    #    Class Properties
    class_property_list = {
    }

    #    Device Properties
    device_property_list = {
    }

    #    Command definitions
    cmd_list = {
        'CreateTaurusTestDevice':
            [[PyTango.DevString, 'device name'],
             [PyTango.DevVoid, ""]],
        'DeleteTaurusTestDevice':
            [[PyTango.DevString, 'device name'],
             [PyTango.DevVoid, ""]],
    }

    #    Attribute definitions
    attr_list = {
        'Position':
            [[PyTango.DevDouble,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                'label': "Gap",
                'unit': "mm",
                'format': "%8.3f",
                'max value': 1000,
                'min value': -1000,
                'max alarm': 900,
                'min alarm': -900,
                'max warning': 800,
                'min warning': -800,
            }],
        'Velocity':
            [[PyTango.DevDouble,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                'label': "Speed",
                'unit': "nm/s",
                'format': "%6.2f",
                'max value': 100,
                'min value': 0,
                'max alarm': 95,
                'min alarm': 5,
                'max warning': 90,
                'min warning': 10,
            }],
        'Acceleration':
            [[PyTango.DevDouble,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                'label': "Acceleration",
                'unit': "nm/s/s",
                'format': "%6.2f",
                'max value': 100,
                'min value': 0,
                'max alarm': 95,
                'min alarm': 2,
                'max warning': 90,
                'min warning': 1,
            }],
        'SimulationMode':
            [[PyTango.DevBoolean,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                'label': "Simulation mode",
            }],
        'Abscissas':
            [[PyTango.DevDouble,
              PyTango.SPECTRUM,
              PyTango.READ, 1024],
             {
                'label': "X values for Curve 1",
            }],
        'Curve':
            [[PyTango.DevDouble,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 1024],
             {
                'label': "Curve 1",
            }],

    }

    def __init__(self, name):
        PyTango.DeviceClass.__init__(self, name)
        self.set_type(name)
        print "In TaurusTestClass  constructor"


if __name__ == '__main__':
    try:
        py = PyTango.Util(sys.argv)
        py.add_TgClass(TaurusTestClass, TaurusTest, 'TaurusTest')

        U = PyTango.Util.instance()
        U.server_init()
        U.server_run()

    except PyTango.DevFailed, e:
        print '-------> Received a DevFailed exception:', e
    except Exception, e:
        print '-------> An unforeseen exception occured....', e
