#!/usr/bin/env python
#    "$Name:  $";
#    "$Header:  $";
# ============================================================================
#
# file :        TestServer
#
# description : Python source for the TestServer and its commands.
#                The class is derived from Device. It represents the
#                CORBA servant object which will be accessed from the
#                network. All commands which can be executed on the
#                TestServer are implemented in this file.
#
# project :     TANGO Device Server
#
# $Author:  $
#
# $Revision:  $
#
# $Log:  $
#
# copyleft :    European Synchrotron Radiation Facility
#               BP 220, Grenoble 38043
#               FRANCE
#
# ============================================================================
#          This file is generated by POGO
#    (Program Obviously used to Generate tango Object)
#
#         (c) - Software Engineering Group - ESRF
# ============================================================================
#

import PyTango
import sys
import numpy
import struct
import pickle


if sys.version_info > (3,):
    long = int
    # unicode = str
else:
    bytes = str


# =================================================================
#   TestServer Class Description:
#
#         My Simple Server
#
# =================================================================
#     Device States Description:
#
#   DevState.ON :  Server On
# =================================================================


class TestServer(PyTango.Device_4Impl):

    # -------- Add you global variables here --------------------------

    # -----------------------------------------------------------------
    #    Device constructor
    # -----------------------------------------------------------------

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

        self.defaults = {}
        self.defaults["ScalarBoolean"] = [
            True, PyTango.SCALAR, PyTango.DevBoolean]
        self.defaults["ScalarUChar"] = [
            12, PyTango.SCALAR, PyTango.DevUChar]
        self.defaults["ScalarShort"] = [
            12, PyTango.SCALAR, PyTango.DevShort]
        self.defaults["ScalarUShort"] = [
            12, PyTango.SCALAR, PyTango.DevUShort]
        self.defaults["ScalarLong"] = [
            123, PyTango.SCALAR, PyTango.DevLong]
        self.defaults["ScalarULong"] = [
            123, PyTango.SCALAR, PyTango.DevULong]
        self.defaults["ScalarLong64"] = [
            123, PyTango.SCALAR, PyTango.DevLong64]
        self.defaults["ScalarULong64"] = [
            123, PyTango.SCALAR, PyTango.DevULong64]
        self.defaults["ScalarFloat"] = [
            -1.23, PyTango.SCALAR, PyTango.DevFloat]
        self.defaults["ScalarDouble"] = [
            123.45, PyTango.SCALAR, PyTango.DevDouble]
        self.defaults["ScalarString"] = [
            "Hello!", PyTango.SCALAR, PyTango.DevString]
        self.defaults["ScalarEncoded"] = [
            ("UTF8", b"Hello UTF8! Pr\xc3\xb3ba \xe6\xb5\x8b"),
            PyTango.SCALAR, PyTango.DevEncoded]

        self.dtype = None

        self.attr_ScalarBoolean = True
        self.attr_ScalarUChar = 12
        self.attr_ScalarShort = 12
        self.attr_ScalarUShort = 12
        self.attr_ScalarLong = 123
        self.attr_ScalarULong = 123
        self.attr_ScalarLong64 = 123
        self.attr_ScalarULong64 = 123
        self.attr_ScalarFloat = -1.23
        self.attr_ScalarDouble = 1.233
        self.attr_ScalarString = "Hello!"
        self.attr_FilenamePattern = "testscan"
        self.attr_ScalarEncoded = \
            "UTF8", b"Hello UTF8! Pr\xc3\xb3ba \xe6\xb5\x8b"
        self.attr_Crystal = 1
        self.attr_ImagesPerFile = 14
        self.attr_UnitCalibration = 2187.3755

        self.attr_SpectrumBoolean = [True, False]
        self.attr_SpectrumUChar = [1, 2]
        self.attr_SpectrumShort = [1, -3, 4]
        self.attr_SpectrumUShort = [1, 4, 5, 6]
        self.attr_SpectrumULong = numpy.array(
            [1234, 5678, 45, 345], dtype='uint32')
        self.attr_SpectrumLong = [1123, -435, 35, -6345]
        self.attr_SpectrumLong64 = [1123, -435, 35, -6345]
        self.attr_SpectrumULong64 = [1123, 23435, 35, 3345]
        self.attr_SpectrumFloat = [11.23, -4.35, 3.5, -634.5]
        self.attr_SpectrumDouble = [1.123, 23.435, 3.5, 3.345]
        self.attr_SpectrumString = ["Hello", "Word", "!", "!!"]
        self.attr_SpectrumEncoded = [
            "INT32", b"\x00\x01\x03\x04\x20\x31\x43\x54\x10\x11\x13\x14"]
        self.attr_SpectrumEncoded = self.encodeSpectrum()

        self.attr_ImageBoolean = numpy.array([[True]], dtype='int16')
        self.attr_ImageUChar = numpy.array([[2, 5], [3, 4]], dtype='uint8')
        self.attr_ImageShort = numpy.array([[2, 5], [3, 4]], dtype='int16')
        self.attr_ImageUShort = numpy.array([[2, 5], [3, 4]], dtype='uint16')
        self.attr_ImageLong = numpy.array([[2, 5], [3, 4]], dtype='int32')
        self.attr_ImageULong = numpy.array([[2, 5], [3, 4]], dtype='uint32')
        self.attr_ImageLong64 = numpy.array([[2, 5], [3, 4]], dtype='int64')
        self.attr_ImageULong64 = numpy.array([[2, 5], [3, 4]], dtype='uint64')
        self.attr_ImageFloat = numpy.array([[2., 5.], [3., 4.]],
                                           dtype='float32')
        self.attr_ImageDouble = numpy.array([[2.4, 5.45], [3.4, 4.45]],
                                            dtype='double')
        self.attr_ImageString = [['True']]
        self.attr_ImageEncoded = self.encodeImage()

        self.attr_value = ""
        TestServer.init_device(self)

    def encodeSpectrum(self):
        format = 'INT32'
        # uint8 B
        #        mode = 0
        # uint16 H
        #        mode = 1
        # uint32 I
        #        mode = 2
        fspectrum = numpy.array(self.attr_SpectrumULong, dtype='int32')
        ibuffer = bytes(struct.pack('i' * fspectrum.size, *fspectrum))
        return [format, ibuffer]

    def encodeImage(self):
        format = 'VIDEO_IMAGE'
        # uint8 B
        mode = 0
        # uint16 H
        #  mode = 1
        width, height = self.attr_ImageUChar.shape
        version = 1
        endian = sys.byteorder == u'big'
        # endian = ord(str(struct.pack('=H', 1)[-1]))
        hsize = struct.calcsize('!IHHqiiHHHH')
        header = struct.pack(
            '!IHHqiiHHHH', 0x5644454f, version, mode, -1,
            width, height, endian, hsize, 0, 0)
        fimage = self.attr_ImageUChar.flatten()
        ibuffer = struct.pack('B' * fimage.size, *fimage)
        return [format, bytes(header + ibuffer)]

    # -----------------------------------------------------------------
    #    Device destructor
    # -----------------------------------------------------------------
    def delete_device(self):
        """ """

    # -----------------------------------------------------------------
    #    Device initialization
    # -----------------------------------------------------------------

    def init_device(self):
        self.set_state(PyTango.DevState.ON)
        self.get_device_properties(self.get_device_class())
        env = {'new': {'ActiveMntGrp': 'nxsmntgrp',
                       'DataCompressionRank': 0,
                       'NeXusSelectorDevice': u'p09/nxsrecselector/1',
                       'ScanDir': u'/tmp/',
                       'ScanFile': [u'sar4r.nxs'],
                       'ScanID': 192,
                       '_ViewOptions': {'ShowDial': True}}}

        self.attr_Environment = ("pickle", pickle.dumps(env, protocol=2))
        self.ChangeValueType("ScalarDouble")
        self.attr_DoorList = ['test/door/1', 'test/door/2']
        self.attr_MotorList = []
        self.attr_ExpChannelList = []

    # -----------------------------------------------------------------
    #    Always excuted hook method
    # -----------------------------------------------------------------
    def always_executed_hook(self):
        pass
    #        print "In ", self.get_name(), "::always_excuted_hook()"

    #
    # =================================================================
    #
    #    TestServer read/write attribute methods
    #
    # =================================================================
    #
    # -----------------------------------------------------------------
    #    Read DoorList attribute
    # -----------------------------------------------------------------
    def read_DoorList(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_DoorList)

    # -----------------------------------------------------------------
    #    Write DoorList attribute
    # -----------------------------------------------------------------
    def write_DoorList(self, attr):
        #    Add your own code here

        self.attr_DoorList = attr.get_write_value()

    #
    # =================================================================
    #
    #    TestServer read/write attribute methods
    #
    # =================================================================
    #
    # -----------------------------------------------------------------
    #    Read MotorList attribute
    # -----------------------------------------------------------------
    def read_MotorList(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_MotorList)

    # -----------------------------------------------------------------
    #    Write MotorList attribute
    # -----------------------------------------------------------------
    def write_MotorList(self, attr):
        #    Add your own code here

        self.attr_MotorList = attr.get_write_value()

    #
    # =================================================================
    #
    #    TestServer read/write attribute methods
    #
    # =================================================================
    #
    # -----------------------------------------------------------------
    #    Read ExpChannelList attribute
    # -----------------------------------------------------------------
    def read_ExpChannelList(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ExpChannelList)

    # -----------------------------------------------------------------
    #    Write ExpChannelList attribute
    # -----------------------------------------------------------------
    def write_ExpChannelList(self, attr):
        #    Add your own code here

        self.attr_ExpChannelList = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read Environment attribute
    # -----------------------------------------------------------------
    def read_Environment(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_Environment[0], self.attr_Environment[1])

    # -----------------------------------------------------------------
    #    Write Environment attribute
    # -----------------------------------------------------------------
    def write_Environment(self, attr):
        #    Add your own code here

        self.attr_Environment = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read Value attribute
    # -----------------------------------------------------------------
    def read_Value(self, attr):
        #    Add your own code here

        attr.set_value(self.defaults[self.dtype][0])

    # -----------------------------------------------------------------
    #    Write Value attribute
    # -----------------------------------------------------------------
    def write_Value(self, attr):
        #    Add your own code here

        self.defaults[self.dtype][0] = attr.get_write_value()

    # =================================================================
    #
    #    TestServer command methods
    #
    # =================================================================
    #
    # -----------------------------------------------------------------
    #    SetState command:
    #
    #    Description: Set state of tango device
    #
    #    argin: DevString     tango state
    # -----------------------------------------------------------------
    def SetState(self, state):
        if state == "RUNNING":
            self.set_state(PyTango.DevState.RUNNING)
        elif state == "FAULT":
            self.set_state(PyTango.DevState.FAULT)
        elif state == "ALARM":
            self.set_state(PyTango.DevState.ALARM)
        else:
            self.set_state(PyTango.DevState.ON)

    # -----------------------------------------------------------------
    #    ChangeValueType command:
    #
    #    Description: Set state of tango device
    #
    #    argin: DevString     tango state
    # -----------------------------------------------------------------
    def ChangeValueType(self, dtype):
        if dtype in self.defaults.keys():
            if self.dtype is not None:
                self.remove_attribute("Value")
            self.dtype = dtype
            dev_class = self.get_device_class()
            attr_data = PyTango.AttrData(
                "Value", dev_class.get_name(),
                [
                    [
                        self.defaults[self.dtype][2],
                        self.defaults[self.dtype][1],
                        PyTango.READ_WRITE
                    ],
                    {
                        'description': "dynamic attribute",
                    }
                ]
            )

            self.add_attribute(attr_data,
                               r_meth=self.read_Value,
                               w_meth=self.write_Value)

    # -----------------------------------------------------------------
    #    Read ScalarLong attribute
    # -----------------------------------------------------------------
    def read_ScalarLong(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ScalarLong)

    # -----------------------------------------------------------------
    #    Write ScalarLong attribute
    # -----------------------------------------------------------------
    def write_ScalarLong(self, attr):
        #    Add your own code here
        self.attr_ScalarLong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read Crystal attribute
    # -----------------------------------------------------------------
    def read_Crystal(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_Crystal)

    # -----------------------------------------------------------------
    #    Write Crystal attribute
    # -----------------------------------------------------------------
    def write_Crystal(self, attr):
        #    Add your own code here
        self.attr_Crystal = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read Crystal attribute
    # -----------------------------------------------------------------
    def read_ImagesPerFile(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImagesPerFile)

    # -----------------------------------------------------------------
    #    Write Crystal attribute
    # -----------------------------------------------------------------
    def write_ImagesPerFile(self, attr):
        #    Add your own code here
        self.attr_ImagesPerFile = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read UnitCalibration attribute
    # -----------------------------------------------------------------
    def read_UnitCalibration(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_UnitCalibration)

    # -----------------------------------------------------------------
    #    Write UnitCalibration attribute
    # -----------------------------------------------------------------
    def write_UnitCalibration(self, attr):
        #    Add your own code here
        self.attr_UnitCalibration = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarBoolean attribute
    # -----------------------------------------------------------------
    def read_ScalarBoolean(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarBoolean)

    # -----------------------------------------------------------------
    #    Write ScalarBoolean attribute
    # -----------------------------------------------------------------
    def write_ScalarBoolean(self, attr):
        #    Add your own code here
        self.attr_ScalarBoolean = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarShort attribute
    # -----------------------------------------------------------------
    def read_ScalarShort(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ScalarShort)

    # -----------------------------------------------------------------
    #    Write ScalarShort attribute
    # -----------------------------------------------------------------
    def write_ScalarShort(self, attr):
        #    Add your own code here
        self.attr_ScalarShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarUShort attribute
    # -----------------------------------------------------------------
    def read_ScalarUShort(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ScalarUShort)

    # -----------------------------------------------------------------
    #    Write ScalarUShort attribute
    # -----------------------------------------------------------------
    def write_ScalarUShort(self, attr):
        #    Add your own code here
        self.attr_ScalarUShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarULong attribute
    # -----------------------------------------------------------------
    def read_ScalarULong(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarULong)

    # -----------------------------------------------------------------
    #    Write ScalarULong attribute
    # -----------------------------------------------------------------
    def write_ScalarULong(self, attr):
        #    Add your own code here
        self.attr_ScalarULong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarLong64 attribute
    # -----------------------------------------------------------------
    def read_ScalarLong64(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ScalarLong64)

    # -----------------------------------------------------------------
    #    Write ScalarLong64 attribute
    # -----------------------------------------------------------------
    def write_ScalarLong64(self, attr):
        #    Add your own code here
        self.attr_ScalarLong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarULong64 attribute
    # -----------------------------------------------------------------
    def read_ScalarULong64(self, attr):
        #    Add your own code here
        attr.set_value(long(self.attr_ScalarULong64))
        # Do not work as well

    # -----------------------------------------------------------------
    #    Write ScalarULong64 attribute
    # -----------------------------------------------------------------
    def write_ScalarULong64(self, attr):
        #    Add your own code here
        self.attr_ScalarULong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarFloat attribute
    # -----------------------------------------------------------------
    def read_ScalarFloat(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarFloat)

    # -----------------------------------------------------------------
    #    Write ScalarFloat attribute
    # -----------------------------------------------------------------
    def write_ScalarFloat(self, attr):
        #    Add your own code here
        self.attr_ScalarFloat = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarDouble attribute
    # -----------------------------------------------------------------
    def read_ScalarDouble(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarDouble)

    # -----------------------------------------------------------------
    #    Write ScalarDouble attribute
    # -----------------------------------------------------------------
    def write_ScalarDouble(self, attr):
        #    Add your own code here
        self.attr_ScalarDouble = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarString attribute
    # -----------------------------------------------------------------
    def read_ScalarString(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ScalarString)

    # -----------------------------------------------------------------
    #    Write ScalarString attribute
    # -----------------------------------------------------------------
    def write_ScalarString(self, attr):
        #    Add your own code here
        self.attr_ScalarString = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read FilenamePattern attribute
    # -----------------------------------------------------------------
    def read_FilenamePattern(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_FilenamePattern)

    # -----------------------------------------------------------------
    #    Write FilenamePattern attribute
    # -----------------------------------------------------------------
    def write_FilenamePattern(self, attr):
        #    Add your own code here
        self.attr_FilenamePattern = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarEncoded attribute
    # -----------------------------------------------------------------
    def read_ScalarEncoded(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarEncoded[0], self.attr_ScalarEncoded[1])

    # -----------------------------------------------------------------
    #    Write ScalarEncoded attribute
    # -----------------------------------------------------------------
    def write_ScalarEncoded(self, attr):
        #    Add your own code here

        self.attr_ScalarEncoded = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ScalarUChar attribute
    # -----------------------------------------------------------------
    def read_ScalarUChar(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ScalarUChar)

    # -----------------------------------------------------------------
    #    Write ScalarUChar attribute
    # -----------------------------------------------------------------
    def write_ScalarUChar(self, attr):
        #    Add your own code here
        self.attr_ScalarUChar = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumEncoded attribute
    # -----------------------------------------------------------------
    def read_SpectrumEncoded(self, attr):
        #    Add your own code here
        self.attr_SpectrumEncoded = self.encodeSpectrum()
        attr.set_value(self.attr_SpectrumEncoded[0],
                       self.attr_SpectrumEncoded[1])

    # -----------------------------------------------------------------
    #    Write SpectrumEncoded attribute
    # -----------------------------------------------------------------
    def write_SpectrumEncoded(self, attr):
        #    Add your own code here
        self.attr_SpectrumEncoded = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageEncoded attribute
    # -----------------------------------------------------------------
    def read_ImageEncoded(self, attr):
        #    Add your own code here
        self.attr_ImageEncoded = self.encodeImage()
        attr.set_value(self.attr_ImageEncoded[0], self.attr_ImageEncoded[1])

    # -----------------------------------------------------------------
    #    Write ImageEncoded attribute
    # -----------------------------------------------------------------
    def write_ImageEncoded(self, attr):
        #    Add your own code here
        self.attr_ImageEncoded = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumBoolean attribute
    # -----------------------------------------------------------------
    def read_SpectrumBoolean(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumBoolean)

    # -----------------------------------------------------------------
    #    Write SpectrumBoolean attribute
    # -----------------------------------------------------------------
    def write_SpectrumBoolean(self, attr):
        #    Add your own code here
        self.attr_SpectrumBoolean = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumUChar attribute
    # -----------------------------------------------------------------
    def read_SpectrumUChar(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumUChar)

    # -----------------------------------------------------------------
    #    Write SpectrumUChar attribute
    # -----------------------------------------------------------------
    def write_SpectrumUChar(self, attr):
        #    Add your own code here
        self.attr_SpectrumUChar = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumShort attribute
    # -----------------------------------------------------------------
    def read_SpectrumShort(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumShort)

    # -----------------------------------------------------------------
    #    Write SpectrumShort attribute
    # -----------------------------------------------------------------
    def write_SpectrumShort(self, attr):
        #    Add your own code here
        self.attr_SpectrumShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumUShort attribute
    # -----------------------------------------------------------------
    def read_SpectrumUShort(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumUShort)

    # -----------------------------------------------------------------
    #    Write SpectrumUShort attribute
    # -----------------------------------------------------------------
    def write_SpectrumUShort(self, attr):
        #    Add your own code here
        self.attr_SpectrumUShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumLong attribute
    # -----------------------------------------------------------------
    def read_SpectrumLong(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumLong)

    # -----------------------------------------------------------------
    #    Write SpectrumLong attribute
    # -----------------------------------------------------------------
    def write_SpectrumLong(self, attr):
        #    Add your own code here
        self.attr_SpectrumLong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumULong attribute
    # -----------------------------------------------------------------
    def read_SpectrumULong(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumULong)

    # -----------------------------------------------------------------
    #    Write SpectrumULong attribute
    # -----------------------------------------------------------------
    def write_SpectrumULong(self, attr):
        #    Add your own code here
        self.attr_SpectrumULong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumLong64 attribute
    # -----------------------------------------------------------------
    def read_SpectrumLong64(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumLong64)

    # -----------------------------------------------------------------
    #    Write SpectrumLong64 attribute
    # -----------------------------------------------------------------
    def write_SpectrumLong64(self, attr):
        #    Add your own code here
        self.attr_SpectrumLong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumULong64 attribute
    # -----------------------------------------------------------------
    def read_SpectrumULong64(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumULong64)

    # -----------------------------------------------------------------
    #    Write SpectrumULong64 attribute
    # -----------------------------------------------------------------
    def write_SpectrumULong64(self, attr):
        #    Add your own code here
        self.attr_SpectrumULong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumFloat attribute
    # -----------------------------------------------------------------
    def read_SpectrumFloat(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumFloat)

    # -----------------------------------------------------------------
    #    Write SpectrumFloat attribute
    # -----------------------------------------------------------------
    def write_SpectrumFloat(self, attr):
        #    Add your own code here
        self.attr_SpectrumFloat = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumDouble attribute
    # -----------------------------------------------------------------
    def read_SpectrumDouble(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumDouble)

    # -----------------------------------------------------------------
    #    Write SpectrumDouble attribute
    # -----------------------------------------------------------------
    def write_SpectrumDouble(self, attr):
        #    Add your own code here
        self.attr_SpectrumDouble = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read SpectrumString attribute
    # -----------------------------------------------------------------
    def read_SpectrumString(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_SpectrumString)

    # -----------------------------------------------------------------
    #    Write SpectrumString attribute
    # -----------------------------------------------------------------
    def write_SpectrumString(self, attr):
        #    Add your own code here
        self.attr_SpectrumString = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageBoolean attribute
    # -----------------------------------------------------------------
    def read_ImageBoolean(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ImageBoolean)

    # -----------------------------------------------------------------
    #    Write ImageBoolean attribute
    # -----------------------------------------------------------------
    def write_ImageBoolean(self, attr):
        #    Add your own code here
        self.attr_ImageBoolean = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageUChar attribute
    # -----------------------------------------------------------------
    def read_ImageUChar(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ImageUChar)

    # -----------------------------------------------------------------
    #    Write ImageUChar attribute
    # -----------------------------------------------------------------
    def write_ImageUChar(self, attr):
        self.attr_ImageUChar = attr.get_write_value()
        #    Add your own code here

    # -----------------------------------------------------------------
    #    Read ImageShort attribute
    # -----------------------------------------------------------------
    def read_ImageShort(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageShort)

    # -----------------------------------------------------------------
    #    Write ImageShort attribute
    # -----------------------------------------------------------------
    def write_ImageShort(self, attr):
        #    Add your own code here
        self.attr_ImageShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageUShort attribute
    # -----------------------------------------------------------------
    def read_ImageUShort(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ImageUShort)

    # -----------------------------------------------------------------
    #    Write ImageUShort attribute
    # -----------------------------------------------------------------
    def write_ImageUShort(self, attr):
        #    Add your own code here
        self.attr_ImageUShort = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageLong attribute
    # -----------------------------------------------------------------
    def read_ImageLong(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ImageLong)

    # -----------------------------------------------------------------
    #    Write ImageLong attribute
    # -----------------------------------------------------------------
    def write_ImageLong(self, attr):
        #    Add your own code here
        self.attr_ImageLong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageULong attribute
    # -----------------------------------------------------------------
    def read_ImageULong(self, attr):
        #    Add your own code here

        attr.set_value(self.attr_ImageULong)

    # -----------------------------------------------------------------
    #    Write ImageULong attribute
    # -----------------------------------------------------------------
    def write_ImageULong(self, attr):
        #    Add your own code here
        self.attr_ImageULong = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageLong64 attribute
    # -----------------------------------------------------------------
    def read_ImageLong64(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageLong64)

    # -----------------------------------------------------------------
    #    Write ImageLong64 attribute
    # -----------------------------------------------------------------
    def write_ImageLong64(self, attr):
        #    Add your own code here
        self.attr_ImageLong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageULong64 attribute
    # -----------------------------------------------------------------
    def read_ImageULong64(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageULong64)

    # -----------------------------------------------------------------
    #    Write ImageULong64 attribute
    # -----------------------------------------------------------------
    def write_ImageULong64(self, attr):
        #    Add your own code here
        self.attr_ImageULong64 = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageFloat attribute
    # -----------------------------------------------------------------
    def read_ImageFloat(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageFloat)

    # -----------------------------------------------------------------
    #    Write ImageFloat attribute
    # -----------------------------------------------------------------
    def write_ImageFloat(self, attr):
        #    Add your own code here
        self.attr_ImageFloat = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageDouble attribute
    # -----------------------------------------------------------------
    def read_ImageDouble(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageDouble)

    # -----------------------------------------------------------------
    #    Write ImageDouble attribute
    # -----------------------------------------------------------------
    def write_ImageDouble(self, attr):
        #    Add your own code here
        self.attr_ImageDouble = attr.get_write_value()

    # -----------------------------------------------------------------
    #    Read ImageString attribute
    # -----------------------------------------------------------------
    def read_ImageString(self, attr):
        #    Add your own code here
        attr.set_value(self.attr_ImageString)

    # -----------------------------------------------------------------
    #    Write ImageString attribute
    # -----------------------------------------------------------------
    def write_ImageString(self, attr):
        #    Add your own code here
        self.attr_ImageString = attr.get_write_value()

    # =================================================================
    #
    #    SimpleServer command methods
    #
    # =================================================================
    #
    # -----------------------------------------------------------------
    #    GetBoolean command:
    #
    #    Description: Returns ScalarBoolean
    #
    #    argout: DevBoolean    ScalarBoolean
    # -----------------------------------------------------------------
    def GetBoolean(self):
        #    Add your own code here

        return self.attr_ScalarBoolean

    # -----------------------------------------------------------------
    #    GetShort command:
    #
    #    Description: Returns ScalarShort
    #
    #    argout: DevShort    ScalarShort
    # -----------------------------------------------------------------
    def GetShort(self):
        #    Add your own code here

        return self.attr_ScalarShort

    # -----------------------------------------------------------------
    #    GetLong command:
    #
    #    Description: Returns ScalarLong
    #
    #    argout: DevLong    ScalarLong
    # -----------------------------------------------------------------
    def GetLong(self):
        #    Add your own code here

        return self.attr_ScalarLong

    # -----------------------------------------------------------------
    #    GetLong64 command:
    #
    #    Description: Returns ScalarLong64
    #
    #    argout: DevLong64    ScalarLong64
    # -----------------------------------------------------------------
    def GetLong64(self):
        #    Add your own code here

        return self.attr_ScalarLong64

    # -----------------------------------------------------------------
    #    GetFloat command:
    #
    #    Description: Returns ScalarFloat
    #
    #    argout: DevFloat    ScalarFloat
    # -----------------------------------------------------------------
    def GetFloat(self):
        #    Add your own code here

        return self.attr_ScalarFloat

    # -----------------------------------------------------------------
    #    GetDouble command:
    #
    #    Description: Returns ScalarDouble
    #
    #    argout: DevDouble    ScalarDouble
    # -----------------------------------------------------------------
    def GetDouble(self):
        #    Add your own code here

        return self.attr_ScalarDouble

    # -----------------------------------------------------------------
    #    GetUShort command:
    #
    #    Description: Returns ScalarUShort
    #
    #    argout: DevUShort    ScalarUShort
    # -----------------------------------------------------------------
    def GetUShort(self):
        #    Add your own code here

        return self.attr_ScalarUShort

    # -----------------------------------------------------------------
    #    GetULong command:
    #
    #    Description: Returns ScalarULong
    #
    #    argout: DevULong    ScalarULong
    # -----------------------------------------------------------------
    def GetULong(self):
        #    Add your own code here

        return self.attr_ScalarULong

    # -----------------------------------------------------------------
    #    GetULong64 command:
    #
    #    Description: Returns ScalarULong64
    #
    #    argout: DevULong64    ScalarULong64
    # -----------------------------------------------------------------
    def GetULong64(self):
        #    Add your own code here

        return self.attr_ScalarULong64

    # -----------------------------------------------------------------
    #    GetString command:
    #
    #    Description: Returns ScalarString
    #
    #    argout: DevString    ScalarString
    # -----------------------------------------------------------------
    def GetString(self):
        #    Add your own code here

        return self.attr_ScalarString

    # -----------------------------------------------------------------
    #    CreateDataSource command:
    #
    # -----------------------------------------------------------------
    def CreateAttribute(self, name):
        #    Add your own code here
        attr = PyTango.Attr(name, PyTango.DevString, PyTango.READ_WRITE)
        self.add_attribute(attr, self.read_General, self.write_General)

    def read_General(self, attr):
        attr.set_value(self.attr_value)

    def write_General(self, attr):
        self.attr_value = attr.get_write_value()


# =================================================================
#
#    TestServerClass class definition
#
# =================================================================
class TestServerClass(PyTango.DeviceClass):

    #    Class Properties
    class_property_list = {
    }

    #    Device Properties
    device_property_list = {
        'StringList':
            [PyTango.DevVarStringArray,
             "element names",
             []],
        'BraggDevice':
            [PyTango.DevVarStringArray,
             "brag device name",
             []],
        'Version':
            [PyTango.DevVarStringArray,
             "version",
             []],
    }

    #    Command definitions
    cmd_list = {
        'SetState':
            [[PyTango.DevString, "ScalarString"],
             [PyTango.DevVoid, ""]],
        'CreateAttribute':
            [[PyTango.DevString, "ScalarString"],
             [PyTango.DevVoid, ""]],
        'ChangeValueType':
            [[PyTango.DevString, "ScalarString"],
             [PyTango.DevVoid, ""]],
        'GetBoolean':
            [[PyTango.DevVoid, ""],
             [PyTango.DevBoolean, "ScalarBoolean"]],
        'GetShort':
            [[PyTango.DevVoid, ""],
             [PyTango.DevShort, "ScalarShort"]],
        'GetLong':
            [[PyTango.DevVoid, ""],
             [PyTango.DevLong, "ScalarLong"]],
        'GetLong64':
            [[PyTango.DevVoid, ""],
             [PyTango.DevLong64, "ScalarLong64"]],
        'GetFloat':
            [[PyTango.DevVoid, ""],
             [PyTango.DevFloat, "ScalarFloat"]],
        'GetDouble':
            [[PyTango.DevVoid, ""],
             [PyTango.DevDouble, "ScalarDouble"]],
        'GetUShort':
            [[PyTango.DevVoid, ""],
             [PyTango.DevUShort, "ScalarUShort"]],
        'GetULong':
            [[PyTango.DevVoid, ""],
             [PyTango.DevULong, "ScalarULong"]],
        'GetULong64':
            [[PyTango.DevVoid, ""],
             [PyTango.DevULong64, "ScalarULong64"]],
        'GetString':
            [[PyTango.DevVoid, ""],
             [PyTango.DevString, "ScalarString"]],
    }

    #    Attribute definitions
    attr_list = {
        'Crystal':
            [[PyTango.DevLong,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "dcm crystal",
            }],
        'ImagesPerFile':
            [[PyTango.DevLong,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "image per file",
            }],
        'ScalarLong':
            [[PyTango.DevLong,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "test long scalar attribute",
            }],
        'ScalarBoolean':
            [[PyTango.DevBoolean,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "test scalar bool attribute",
            }],
        'ScalarShort':
            [[PyTango.DevShort,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "Scalar Short attribute",
            }],
        'ScalarUShort':
            [[PyTango.DevUShort,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarUShort attribute",
            }],
        'ScalarULong':
            [[PyTango.DevULong,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarULong attribute",
            }],
        'ScalarLong64':
            [[PyTango.DevLong64,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarLong64 attribute",
            }],
        'ScalarULong64':
            [[PyTango.DevULong64,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarULong64 attribute",
            }],
        'ScalarFloat':
            [[PyTango.DevFloat,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarFloat attribute",
            }],
        'UnitCalibration':
            [[PyTango.DevDouble,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "UnitCalibration dcm attribute",
            }],
        'ScalarDouble':
            [[PyTango.DevDouble,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarDouble attribute",
            }],
        'ScalarString':
            [[PyTango.DevString,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarString attribute",
            }],
        'FilenamePattern':
            [[PyTango.DevString,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "FilenamePattern attribute",
            }],
        'ScalarEncoded':
            [[PyTango.DevEncoded,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarEncoded attribute",
            }],
        'ScalarUChar':
            [[PyTango.DevUChar,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ScalarUChar attribute",
            }],
        'SpectrumEncoded':
            [[PyTango.DevEncoded,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "SpectrumEncoded attribute",
            }],
        'ImageEncoded':
            [[PyTango.DevEncoded,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "ImageEncoded attribute",
            }],
        'SpectrumBoolean':
            [[PyTango.DevBoolean,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumBoolean attribute",
            }],
        'SpectrumUChar':
            [[PyTango.DevUChar,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumUChar attribute",
            }],
        'SpectrumShort':
            [[PyTango.DevShort,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumShort attribute",
            }],
        'SpectrumUShort':
            [[PyTango.DevUShort,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumUShort",
            }],
        'SpectrumLong':
            [[PyTango.DevLong,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumLong attribute",
            }],
        'SpectrumULong':
            [[PyTango.DevULong,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumULong attribute",
            }],
        'SpectrumLong64':
            [[PyTango.DevLong64,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumLong64 attribute",
            }],
        'SpectrumULong64':
            [[PyTango.DevULong64,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumULong64 attribute",
            }],
        'SpectrumFloat':
            [[PyTango.DevFloat,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumFloat attribute",
            }],
        'SpectrumDouble':
            [[PyTango.DevDouble,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumDouble attribute",
            }],
        'SpectrumString':
            [[PyTango.DevString,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE, 4096],
             {
                 'description': "SpectrumString attribute",
            }],
        'ImageBoolean':
            [[PyTango.DevBoolean,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageBoolean attribute",
            }],
        'ImageUChar':
            [[PyTango.DevUChar,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageUChar attribute",
            }],
        'ImageShort':
            [[PyTango.DevShort,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageShort attribute",
            }],
        'ImageUShort':
            [[PyTango.DevUShort,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageUShort attribute",
            }],
        'ImageLong':
            [[PyTango.DevLong,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageLong attribute",
            }],
        'ImageULong':
            [[PyTango.DevULong,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageULong attribute",
            }],
        'ImageLong64':
            [[PyTango.DevLong64,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageLong64 attribute",
            }],
        'ImageULong64':
            [[PyTango.DevULong64,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageULong64 attribute",
            }],
        'ImageFloat':
            [[PyTango.DevFloat,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageFloat attribute",
            }],
        'ImageDouble':
            [[PyTango.DevDouble,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageDouble attribute",
            }],
        'ImageString':
            [[PyTango.DevString,
              PyTango.IMAGE,
              PyTango.READ_WRITE, 4096, 4096],
             {
                 'description': "ImageString attribute",
            }],
        'Environment':
            [[PyTango.DevEncoded,
              PyTango.SCALAR,
              PyTango.READ_WRITE],
             {
                 'description': "Environment attribute",
            }],
        'DoorList':
            [[PyTango.DevString,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE,
              256],
             {
                 'description': "door list attribute",
            }],
        'MotorList':
            [[PyTango.DevString,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE,
              256],
             {
                 'description': "motor list attribute",
            }],
        'ExpChannelList':
            [[PyTango.DevString,
              PyTango.SPECTRUM,
              PyTango.READ_WRITE,
              256],
             {
                 'description': "experimental channel list attribute",
            }],
    }

# -----------------------------------------------------------------
#    TestServerClass Constructor
# -----------------------------------------------------------------
    def __init__(self, name):
        PyTango.DeviceClass.__init__(self, name)
        self.set_type(name)


# =================================================================
#
#    TestServer class main method
#
# =================================================================
if __name__ == '__main__':
    try:
        py = PyTango.Util(sys.argv)
        py.add_class(TestServerClass, TestServer, 'TestServer')

        U = PyTango.Util.instance()

        U.server_init()
        U.server_run()

    except PyTango.DevFailed as e:
        print('-------> Received a DevFailed exception: %s' % e)
    except Exception as e:
        print('-------> An unforeseen exception occured.... %s' % e)
