[pytango] 142/483: Implementation of MultiAttrProp

Sandor Bodo-Merle sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:14:34 UTC 2017


This is an automated email from the git hooks/post-receive script.

sbodomerle-guest pushed a commit to annotated tag bliss_8.10
in repository pytango.

commit 8aff6231db08ee8ad345d1a8098d98bac40157da
Author: trogucki <trogucki at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date:   Fri Sep 21 14:31:21 2012 +0000

    Implementation of MultiAttrProp
    
    git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@21158 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
 PyTango/__init__.py            |   4 +-
 PyTango/device_server.py       |  48 ++++-
 src/device_attribute.cpp       |  30 +--
 src/device_attribute_numpy.hpp |   4 +-
 src/device_data.cpp            |   4 +-
 src/from_py.h                  | 419 +++++++++++++++++++++++++++++++++++++++++
 src/server/attribute.cpp       | 185 +++++++++---------
 src/server/attribute.h         |   5 +
 src/server/command.cpp         |   8 +-
 src/server/wattribute.cpp      |  22 +--
 src/tgutils.h                  | 211 +++++++++++++++------
 src/to_py.h                    |  31 +++
 12 files changed, 777 insertions(+), 194 deletions(-)

diff --git a/PyTango/__init__.py b/PyTango/__init__.py
index 19acd31..4a0d750 100644
--- a/PyTango/__init__.py
+++ b/PyTango/__init__.py
@@ -64,7 +64,7 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
 'GroupReply', 'GroupReplyList', 'IMAGE', 'ImageAttr', 'InfoIt',
 'KeepAliveCmdCode', 'Level', 'LockCmdCode', 'LockerInfo', 'LockerLanguage',
 'LogIt', 'LogLevel', 'LogTarget', 'Logger', 'Logging', 'MessBoxType',
-'MultiAttribute', 'MultiClassAttribute', 'NamedDevFailed',
+'MultiAttribute', 'MultiAttrProp', 'MultiClassAttribute', 'NamedDevFailed',
 'NamedDevFailedList', 'NonDbDevice', 'NonSupportedFeature',
 'NotAllowed', 'NumpyType', 'PeriodicEventInfo', 'PeriodicEventProp',
 'PollCmdCode', 'PollDevice',
@@ -157,7 +157,7 @@ from .log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
     ErrorIt, FatalIt
 from .device_server import ChangeEventProp, PeriodicEventProp, \
     ArchiveEventProp, AttributeAlarm, EventProperties, AttributeConfig, \
-    AttributeConfig_2, AttributeConfig_3
+    AttributeConfig_2, AttributeConfig_3, MultiAttrProp
 from .attribute_proxy import AttributeProxy
 from .group import Group
 from .pyutil import Util
diff --git a/PyTango/device_server.py b/PyTango/device_server.py
index fbc3d67..0da51b3 100644
--- a/PyTango/device_server.py
+++ b/PyTango/device_server.py
@@ -30,6 +30,7 @@ from __future__ import print_function
 __all__ = [ "ChangeEventProp", "PeriodicEventProp", "ArchiveEventProp",
             "AttributeAlarm", "EventProperties",
             "AttributeConfig", "AttributeConfig_2", "AttributeConfig_3",
+            "MultiAttrProp",
             "device_server_init"]
 
 __docformat__ = "restructuredtext"
@@ -95,6 +96,32 @@ class EventProperties(object):
         self.per_event = PeriodicEventProp()
         self.arch_event = ArchiveEventProp()
 
+class MultiAttrProp(object):
+    """This class represents the python interface for the Tango IDL object
+    MultiAttrProp."""
+    
+    def __init__(self):
+        self.label = ''
+        self.description = ''
+        self.unit = ''
+        self.standard_unit = ''
+        self.display_unit = ''
+        self.format = ''
+        self.min_value = ''
+        self.max_value = ''
+        self.min_alarm = ''
+        self.max_alarm = ''
+        self.min_warning = ''
+        self.max_warning = ''
+        self.delta_t = ''
+        self.delta_val = ''
+        self.event_period = ''
+        self.archive_period = ''
+        self.rel_change = ''
+        self.abs_change = ''
+        self.archive_rel_change = ''
+        self.archive_abs_change = ''
+
 def _init_attr_config(attr_cfg):
     """Helper function to initialize attribute config objects"""
     attr_cfg.name = ''
@@ -161,9 +188,12 @@ def __Attribute__get_properties(self, attr_cfg = None):
             New in PyTango 7.1.4
     """
 
-    if attr_cfg is None:
-        attr_cfg = AttributeConfig()
-    return self._get_properties(attr_cfg)
+    if isinstance(attr_cfg,MultiAttrProp):
+        return self._get_properties_multi_attr_prop(attr_cfg)
+    else:
+        if attr_cfg is None:
+            attr_cfg = AttributeConfig()
+        return self._get_properties(attr_cfg)
 
 def __Attribute__get_properties_2(self, attr_cfg = None):
     """get_properties_2(self, attr_cfg = None) -> AttributeConfig_2
@@ -207,7 +237,7 @@ def __Attribute__get_properties_3(self, attr_cfg = None):
         attr_cfg = AttributeConfig_3()
     return self._get_properties_3(attr_cfg)
 
-def __Attribute__set_properties(self, attr_cfg, dev):
+def __Attribute__set_properties(self, attr_cfg, dev = None):
     """set_properties(self, attr_cfg, dev) -> None
 
                 Set attribute properties.
@@ -222,10 +252,14 @@ def __Attribute__set_properties(self, attr_cfg, dev):
 
             New in PyTango 7.1.4
     """
-    if isinstance(attr_cfg, AttributeConfig_3):
-        self._set_properties_3(attr_cfg, dev)
+    
+    if isinstance(attr_cfg,MultiAttrProp):
+        return self._set_properties_multi_attr_prop(attr_cfg)
     else:
-        self._set_properties(attr_cfg, dev)
+        if isinstance(attr_cfg, AttributeConfig_3):
+            self._set_properties_3(attr_cfg, dev)
+        else:
+            self._set_properties(attr_cfg, dev)
 
 
 def __DeviceImpl__get_device_class(self):
diff --git a/src/device_attribute.cpp b/src/device_attribute.cpp
index 306c3d6..2b7bb98 100644
--- a/src/device_attribute.cpp
+++ b/src/device_attribute.cpp
@@ -519,19 +519,19 @@ namespace PyDeviceAttribute
                         case PyTango::ExtractAsNumpy:
                         case PyTango::ExtractAsTuple:
                         case PyTango::ExtractAsList:
-                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, 
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                                 _update_scalar_values, self, py_value);
                             break;
                         case PyTango::ExtractAsBytes:
-                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                                 _update_value_as_bin, self, py_value, true);
                             break;
                         case PyTango::ExtractAsByteArray:
-                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                                 _update_value_as_bin, self, py_value, false);
                             break;
                         case PyTango::ExtractAsString:
-                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                                 _update_value_as_string, self, py_value);
                             break;
                         case PyTango::ExtractAsNothing:
@@ -542,7 +542,7 @@ namespace PyDeviceAttribute
                 {
                     if (extract_as != PyTango::ExtractAsNothing)
                     {
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, 
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_scalar_values, self, py_value);
                     }
                 }
@@ -555,28 +555,28 @@ namespace PyDeviceAttribute
                     default:
                     case PyTango::ExtractAsNumpy:
 #                   ifndef DISABLE_PYTANGO_NUMPY
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, 
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_array_values, self, is_image, py_value);
                         break;
 #                   endif
                     case PyTango::ExtractAsTuple:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_array_values_as_tuples, self, is_image, py_value);
                         break;
                     case PyTango::ExtractAsList:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_array_values_as_lists, self, is_image, py_value);
                         break;
                     case PyTango::ExtractAsBytes:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_value_as_bin, self, py_value, true);
                         break;
                     case PyTango::ExtractAsByteArray:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_value_as_bin, self, py_value, false);
                         break;
                     case PyTango::ExtractAsString:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type,
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
                             _update_value_as_string, self, py_value);
                         break;
                     case PyTango::ExtractAsNothing:
@@ -667,7 +667,7 @@ namespace PyDeviceAttribute
         switch(data_format)
         {
             case Tango::SCALAR:
-                TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_scalar_attribute, self, py_value );
+                TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_scalar_attribute, self, py_value );
                 break;
             case Tango::IMAGE:
                 isImage = true;
@@ -683,14 +683,14 @@ namespace PyDeviceAttribute
                 // standard types and C++ are.
 #               ifdef DISABLE_PYTANGO_NUMPY
                 {
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_list_attribute, self, isImage, py_value );
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_list_attribute, self, isImage, py_value );
                 }
 #               else
                 {
                     if (PyArray_Check(py_value.ptr()))
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_numpy_attribute, self, isImage, py_value );
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_numpy_attribute, self, isImage, py_value );
                     else
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_list_attribute, self, isImage, py_value );
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_list_attribute, self, isImage, py_value );
                     break;
                 }
 #               endif
diff --git a/src/device_attribute_numpy.hpp b/src/device_attribute_numpy.hpp
index 211b322..9dab76f 100644
--- a/src/device_attribute_numpy.hpp
+++ b/src/device_attribute_numpy.hpp
@@ -39,7 +39,7 @@ namespace PyDeviceAttribute {
     template<long type>
     static void _dev_var_x_array_deleter(void * ptr_)
     {
-        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
             delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
         );
     }
@@ -48,7 +48,7 @@ namespace PyDeviceAttribute {
     static void _dev_var_x_array_deleter(PyObject* obj)
     {
         void * ptr_ = PyCapsule_GetPointer(obj, NULL);
-        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
             delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
         );
     }
diff --git a/src/device_data.cpp b/src/device_data.cpp
index 9123f54..000be4f 100644
--- a/src/device_data.cpp
+++ b/src/device_data.cpp
@@ -162,7 +162,7 @@ namespace PyDeviceData {
     {
         Tango::DeviceData &self = boost::python::extract<Tango::DeviceData &>(py_self);
         
-        TANGO_DO_ON_DEVICE_DATA_TYPE(self.get_type(),
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(self.get_type(),
             return extract_scalar<tangoTypeConst>(self);
         ,
             return extract_array<tangoTypeConst>(self, py_self, extract_as);
@@ -172,7 +172,7 @@ namespace PyDeviceData {
 
     void insert(Tango::DeviceData &self, long data_type, object py_value)
     {
-        TANGO_DO_ON_DEVICE_DATA_TYPE(data_type,
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(data_type,
             insert_scalar<tangoTypeConst>(self, py_value);
         , 
             insert_array<tangoTypeConst>(self, py_value);
diff --git a/src/from_py.h b/src/from_py.h
index 0ab46cf..e0c0c21 100644
--- a/src/from_py.h
+++ b/src/from_py.h
@@ -289,6 +289,425 @@ void from_py_object(boost::python::object &, Tango::AttributeConfig &);
 void from_py_object(boost::python::object &, Tango::AttributeConfig_2 &);
 void from_py_object(boost::python::object &, Tango::AttributeConfig_3 &);
 
+template<typename T>
+void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<T> &multi_attr_prop)
+{
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = boost::python::extract<T>(py_obj.attr("min_value"));
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = boost::python::extract<T>(py_obj.attr("max_value"));
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = boost::python::extract<T>(py_obj.attr("min_alarm"));
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = boost::python::extract<T>(py_obj.attr("max_alarm"));
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = boost::python::extract<T>(py_obj.attr("min_warning"));
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = boost::python::extract<T>(py_obj.attr("max_warning"));
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = boost::python::extract<T>(py_obj.attr("delta_val"));
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
+template<>
+inline void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<Tango::DevEncoded> &multi_attr_prop)
+{
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_value"));
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_value"));
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_alarm"));
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_alarm"));
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_warning"));
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_warning"));
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = boost::python::extract<Tango::DevUChar>(py_obj.attr("delta_val"));
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
+template<>
+inline void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<Tango::DevString> &multi_attr_prop)
+{
+	string empty_str("");
+
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = empty_str;
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = empty_str;
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = empty_str;
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = empty_str;
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = empty_str;
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = empty_str;
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = empty_str;
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
 void from_py_object(boost::python::object &, Tango::AttributeConfigList &);
 void from_py_object(boost::python::object &, Tango::AttributeConfigList_2 &);
 void from_py_object(boost::python::object &, Tango::AttributeConfigList_3 &);
diff --git a/src/server/attribute.cpp b/src/server/attribute.cpp
index 3f7b676..ef3d383 100644
--- a/src/server/attribute.cpp
+++ b/src/server/attribute.cpp
@@ -43,9 +43,6 @@ using namespace boost::python;
             struct timeval tv; PYTG_TIME_FROM_DOUBLE(dbl, tv)
 #endif
 
-#ifndef TgLibVersNb
-#   define TgLibVersNb 80005
-#endif
 
 inline static void throw_wrong_python_data_type(const std::string &att_name,
                                          const char *method)
@@ -333,12 +330,12 @@ namespace PyAttribute
                         fname + "()");
             } else {
                 if (quality)
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_value_date_quality_scalar, att, value, t, *quality);
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_value_date_quality_scalar, att, value, t, *quality);
                 else
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_value_scalar, att, value);
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_value_scalar, att, value);
             }
         } else {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                 __set_value_date_quality_array,
                     att, value, t, quality, x, y, fname, isImage);
         }
@@ -414,7 +411,63 @@ namespace PyAttribute
         att.get_properties_3(tg_attr_cfg);
         return to_py(tg_attr_cfg, attr_cfg);
     }
+
+    template<typename TangoScalarType>
+    inline void _get_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	Tango::MultiAttrProp<TangoScalarType> tg_multi_attr_prop;
+    	att.get_properties(tg_multi_attr_prop);
+
+    	to_py(tg_multi_attr_prop,multi_attr_prop);
+    }
+
+#if TgLibVersNb < 80100 // _get_properties_multi_attr_prop<Tango::DevString>
+
+    // This is a hook dealing with a bug in Tango 8.0.5 related to AttrProp<Tango::DevString> specialisation
+    template<>
+    inline void _get_properties_multi_attr_prop<Tango::DevString>(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+        Tango::AttributeConfig_3 tg_attr_cfg;
+        att.get_properties_3(tg_attr_cfg);
+
+        if(multi_attr_prop.ptr() == Py_None)
+        {
+            PYTANGO_MOD
+            multi_attr_prop = pytango.attr("MultiAttrProp")();
+        }
+
+        multi_attr_prop.attr("label") = tg_attr_cfg.label;
+        multi_attr_prop.attr("description") = tg_attr_cfg.description;
+        multi_attr_prop.attr("unit") = tg_attr_cfg.unit;
+        multi_attr_prop.attr("standard_unit") = tg_attr_cfg.standard_unit;
+        multi_attr_prop.attr("display_unit") = tg_attr_cfg.display_unit;
+        multi_attr_prop.attr("format") = tg_attr_cfg.format;
+        multi_attr_prop.attr("min_value") = tg_attr_cfg.min_value;
+        multi_attr_prop.attr("max_value") = tg_attr_cfg.max_value;
+        multi_attr_prop.attr("min_alarm") = tg_attr_cfg.att_alarm.min_alarm;
+        multi_attr_prop.attr("max_alarm") = tg_attr_cfg.att_alarm.max_alarm;
+        multi_attr_prop.attr("min_warning") = tg_attr_cfg.att_alarm.min_warning;
+        multi_attr_prop.attr("max_warning") = tg_attr_cfg.att_alarm.max_warning;
+        multi_attr_prop.attr("delta_t") = tg_attr_cfg.att_alarm.delta_t;
+        multi_attr_prop.attr("delta_val") = tg_attr_cfg.att_alarm.delta_val;
+        multi_attr_prop.attr("event_period") = tg_attr_cfg.event_prop.per_event.period;
+        multi_attr_prop.attr("archive_period") = tg_attr_cfg.event_prop.arch_event.period;
+        multi_attr_prop.attr("rel_change") = tg_attr_cfg.event_prop.ch_event.rel_change;
+        multi_attr_prop.attr("abs_change") = tg_attr_cfg.event_prop.ch_event.abs_change;
+        multi_attr_prop.attr("archive_rel_change") = tg_attr_cfg.event_prop.arch_event.rel_change;
+        multi_attr_prop.attr("archive_abs_change") = tg_attr_cfg.event_prop.arch_event.abs_change;
+    }
     
+#endif // _get_properties_multi_attr_prop<Tango::DevString>
+
+    inline boost::python::object get_properties_multi_attr_prop(Tango::Attribute &att,
+                                                boost::python::object &multi_attr_prop)
+    {
+    	long tangoTypeConst = att.get_data_type();
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _get_properties_multi_attr_prop, att, multi_attr_prop);
+		return multi_attr_prop;
+    }
+
     void set_properties(Tango::Attribute &att, boost::python::object &attr_cfg,
                         boost::python::object &dev)
     {
@@ -433,6 +486,20 @@ namespace PyAttribute
         att.set_properties(tg_attr_cfg, dev_ptr);
     }
 
+    template<typename TangoScalarType>
+    inline void _set_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	Tango::MultiAttrProp<TangoScalarType> tg_multi_attr_prop;
+    	from_py_object(multi_attr_prop,tg_multi_attr_prop);
+    	att.set_properties(tg_multi_attr_prop);
+    }
+
+    void set_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	long tangoTypeConst = att.get_data_type();
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_properties_multi_attr_prop, att, multi_attr_prop);
+    }
+
     void set_upd_properties(Tango::Attribute &att, boost::python::object &attr_cfg)
     {
         Tango::AttributeConfig_3 tg_attr_cfg;
@@ -478,27 +545,18 @@ namespace PyAttribute
         return self.is_polled();
     }
 
-#if TgLibVersNb >= 80100 // set_min_alarm
 
-    template<long tangoTypeConst>
+    template<typename TangoScalarType>
     inline void _set_min_alarm(Tango::Attribute &self, boost::python::object value)
     {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
 		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
 		self.set_min_alarm(c_value);
     }
 
-#else // set_min_alarm
-
-    template<typename TangoScalarType>
-    inline void __set_min_alarm(Tango::Attribute &self, boost::python::object value)
-    {
-		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
-		self.set_min_alarm(c_value);
-    }
+#if TgLibVersNb < 80100 // set_min_alarm
 
     template<>
-    inline void __set_min_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    inline void _set_min_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
     {
     	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
     	Tango::Except::throw_exception((const char *)"API_MethodArgument",
@@ -506,13 +564,6 @@ namespace PyAttribute
     				  (const char *)"Attribute::set_min_alarm()");
     }
 
-    template<long tangoTypeConst>
-    inline void _set_min_alarm(Tango::Attribute &self, boost::python::object value)
-    {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-		__set_min_alarm<TangoScalarType>(self,value);
-    }
-
 #endif // set_min_alarm
 
     inline void set_min_alarm(Tango::Attribute &self, boost::python::object value)
@@ -533,31 +584,22 @@ namespace PyAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_alarm, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_min_alarm, self, value);
     	}
     }
 
-#if TgLibVersNb >= 80100 // set_max_alarm
 
-    template<long tangoTypeConst>
+    template<typename TangoScalarType>
     inline void _set_max_alarm(Tango::Attribute &self, boost::python::object value)
     {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
 		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
 		self.set_max_alarm(c_value);
     }
 
-#else // set_max_alarm
-
-    template<typename TangoScalarType>
-    inline void __set_max_alarm(Tango::Attribute &self, boost::python::object value)
-    {
-		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
-		self.set_max_alarm(c_value);
-    }
+#if TgLibVersNb < 80100 // set_max_alarm
 
     template<>
-    inline void __set_max_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    inline void _set_max_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
     {
     	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
     	Tango::Except::throw_exception((const char *)"API_MethodArgument",
@@ -565,13 +607,6 @@ namespace PyAttribute
     				  (const char *)"Attribute::set_max_alarm()");
     }
 
-    template<long tangoTypeConst>
-    inline void _set_max_alarm(Tango::Attribute &self, boost::python::object value)
-    {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-		__set_max_alarm<TangoScalarType>(self,value);
-    }
-
 #endif // set_max_alarm
 
     inline void set_max_alarm(Tango::Attribute &self, boost::python::object value)
@@ -592,31 +627,22 @@ namespace PyAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_alarm, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_max_alarm, self, value);
     	}
     }
 
-#if TgLibVersNb >= 80100 // set_min_warning
 
-    template<long tangoTypeConst>
+    template<typename TangoScalarType>
     inline void _set_min_warning(Tango::Attribute &self, boost::python::object value)
     {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
 		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
 		self.set_min_warning(c_value);
     }
 
-#else // set_min_warning
-
-    template<typename TangoScalarType>
-    inline void __set_min_warning(Tango::Attribute &self, boost::python::object value)
-    {
-		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
-		self.set_min_warning(c_value);
-    }
+#if TgLibVersNb < 80100 // set_min_warning
 
     template<>
-    inline void __set_min_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    inline void _set_min_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
     {
     	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
     	Tango::Except::throw_exception((const char *)"API_MethodArgument",
@@ -624,13 +650,6 @@ namespace PyAttribute
     				  (const char *)"Attribute::set_min_warning()");
     }
 
-    template<long tangoTypeConst>
-    inline void _set_min_warning(Tango::Attribute &self, boost::python::object value)
-    {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-		__set_min_warning<TangoScalarType>(self,value);
-    }
-
 #endif // set_min_warning
 
     inline void set_min_warning(Tango::Attribute &self, boost::python::object value)
@@ -651,31 +670,22 @@ namespace PyAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_warning, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_min_warning, self, value);
     	}
     }
 
-#if TgLibVersNb >= 80100 // set_max_warning
 
-    template<long tangoTypeConst>
+    template<typename TangoScalarType>
     inline void _set_max_warning(Tango::Attribute &self, boost::python::object value)
     {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
 		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
 		self.set_max_warning(c_value);
     }
 
-#else // set_max_warning
-
-    template<typename TangoScalarType>
-    inline void __set_max_warning(Tango::Attribute &self, boost::python::object value)
-    {
-		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
-		self.set_max_warning(c_value);
-    }
+#if TgLibVersNb < 80100 // set_max_warning
 
     template<>
-    inline void __set_max_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    inline void _set_max_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
     {
     	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
     	Tango::Except::throw_exception((const char *)"API_MethodArgument",
@@ -683,13 +693,6 @@ namespace PyAttribute
     				  (const char *)"Attribute::set_max_warning()");
     }
 
-    template<long tangoTypeConst>
-    inline void _set_max_warning(Tango::Attribute &self, boost::python::object value)
-    {
-		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-		__set_max_warning<TangoScalarType>(self,value);
-    }
-
 #endif // set_max_warning
 
     inline void set_max_warning(Tango::Attribute &self, boost::python::object value)
@@ -710,7 +713,7 @@ namespace PyAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_warning, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_max_warning, self, value);
     	}
     }
 
@@ -733,7 +736,7 @@ namespace PyAttribute
 		if(tangoTypeConst == Tango::DEV_ENCODED)
 			tangoTypeConst = Tango::DEV_UCHAR;
 
-        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_min_alarm, att);
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_min_alarm, att);
         return 0;
     }
 
@@ -756,7 +759,7 @@ namespace PyAttribute
 		if(tangoTypeConst == Tango::DEV_ENCODED)
 			tangoTypeConst = Tango::DEV_UCHAR;
 
-        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_max_alarm, att);
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_max_alarm, att);
         return 0;
     }
 
@@ -779,7 +782,7 @@ namespace PyAttribute
 		if(tangoTypeConst == Tango::DEV_ENCODED)
 			tangoTypeConst = Tango::DEV_UCHAR;
 
-        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_min_warning, att);
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_min_warning, att);
         return 0;
     }
 
@@ -802,7 +805,7 @@ namespace PyAttribute
 		if(tangoTypeConst == Tango::DEV_ENCODED)
 			tangoTypeConst = Tango::DEV_UCHAR;
 
-        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, return __get_max_warning, att);
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_max_warning, att);
         return 0;
     }
 
@@ -928,9 +931,11 @@ void export_attribute()
         .def("_get_properties", &PyAttribute::get_properties)
         .def("_get_properties_2", &PyAttribute::get_properties_2)
         .def("_get_properties_3", &PyAttribute::get_properties_3)
+        .def("_get_properties_multi_attr_prop", &PyAttribute::get_properties_multi_attr_prop)
         
         .def("_set_properties", &PyAttribute::set_properties)
         .def("_set_properties_3", &PyAttribute::set_properties_3)
+        .def("_set_properties_multi_attr_prop", &PyAttribute::set_properties_multi_attr_prop)
         
         .def("set_upd_properties",
 			(void (*) (Tango::Attribute &, boost::python::object &))
diff --git a/src/server/attribute.h b/src/server/attribute.h
index 0e0f0aa..24e3bce 100644
--- a/src/server/attribute.h
+++ b/src/server/attribute.h
@@ -60,11 +60,16 @@ namespace PyAttribute
     boost::python::object get_properties_3(Tango::Attribute &,
                                            boost::python::object &);
 
+    boost::python::object get_properties_multi_attr_prop(Tango::Attribute &,
+                                                    boost::python::object &);
+
     void set_properties(Tango::Attribute &, boost::python::object &,
                         boost::python::object &);
     
     void set_properties_3(Tango::Attribute &, boost::python::object &,
                           boost::python::object &);
+
+    void set_properties_multi_attr_prop(Tango::Attribute &, boost::python::object &);
 };
 
 
diff --git a/src/server/command.cpp b/src/server/command.cpp
index 17d4a2f..9c3e79d 100644
--- a/src/server/command.cpp
+++ b/src/server/command.cpp
@@ -209,7 +209,7 @@ void extract_scalar<Tango::DEV_ENCODED>(const CORBA::Any &any, boost::python::ob
          template<long type>
          static void dev_var_x_array_deleter__(void * ptr_)
          {
-             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                  delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
              );
          }
@@ -218,7 +218,7 @@ void extract_scalar<Tango::DEV_ENCODED>(const CORBA::Any &any, boost::python::ob
          static void dev_var_x_array_deleter__(PyObject* obj)
          {
              void * ptr_ = PyCapsule_GetPointer(obj, NULL);
-             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                  delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
              );
          }
@@ -275,7 +275,7 @@ CORBA::Any *PyCmd::execute(Tango::DeviceImpl *dev, const CORBA::Any &param_any)
         // So, the result is that param_py = param_any.
         // It is done with some template magic.
         boost::python::object param_py;
-        TANGO_DO_ON_DEVICE_DATA_TYPE(in_type, 
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(in_type,
             extract_scalar<tangoTypeConst>(param_any, param_py);
         , 
             extract_array<tangoTypeConst>(param_any, param_py);
@@ -298,7 +298,7 @@ CORBA::Any *PyCmd::execute(Tango::DeviceImpl *dev, const CORBA::Any &param_any)
         unique_pointer<CORBA::Any> ret_any_guard(ret_any);
 
         // It does: ret_any = ret_py_obj
-        TANGO_DO_ON_DEVICE_DATA_TYPE(out_type, 
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(out_type,
             insert_scalar<tangoTypeConst>(ret_py_obj, *ret_any);
         ,
             insert_array<tangoTypeConst>(ret_py_obj, *ret_any);
diff --git a/src/server/wattribute.cpp b/src/server/wattribute.cpp
index c6a04ca..eb15e26 100644
--- a/src/server/wattribute.cpp
+++ b/src/server/wattribute.cpp
@@ -90,7 +90,7 @@ namespace PyWAttribute
 		if(type == Tango::DEV_ENCODED)
 			type = Tango::DEV_UCHAR;
 
-		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, return __get_min_value, att);
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, return __get_min_value, att);
         return 0;
     }
 
@@ -112,7 +112,7 @@ namespace PyWAttribute
 		if(type == Tango::DEV_ENCODED)
 			type = Tango::DEV_UCHAR;
 
-		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, return __get_max_value, att);
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, return __get_max_value, att);
         return 0;
     }
 
@@ -171,7 +171,7 @@ namespace PyWAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_min_value, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, _set_min_value, self, value);
     	}
     }
 
@@ -230,7 +230,7 @@ namespace PyWAttribute
 			else if(tangoTypeConst == Tango::DEV_ENCODED)
 				tangoTypeConst = Tango::DEV_UCHAR;
 
-			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tangoTypeConst, _set_max_value, self, value);
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, _set_max_value, self, value);
     	}
     }
 /// @}
@@ -331,7 +331,7 @@ namespace PyWAttribute
 
         if (format == Tango::SCALAR)
         {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_scalar,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_scalar,
                                               att, value);
         }
         else
@@ -348,7 +348,7 @@ namespace PyWAttribute
                         o.str(),
                         "set_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value,
                                               PySequence_Size(value.ptr()), 0);
         }
@@ -387,7 +387,7 @@ namespace PyWAttribute
                         o.str(),
                         "set_write_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value, x, 0);
         }
     }
@@ -425,7 +425,7 @@ namespace PyWAttribute
                         o.str(),
                         (const char *)"set_write_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value, x, y);
         }
     }
@@ -531,18 +531,18 @@ namespace PyWAttribute
         const bool isScalar = fmt == Tango::SCALAR;
 
         if (isScalar) {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __get_write_value_scalar, att, &value);
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __get_write_value_scalar, att, &value);
         } else {
             switch (extract_as) {
                 case PyTango::ExtractAsNumpy: {
 #               ifndef DISABLE_PYTANGO_NUMPY
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                         __get_write_value_array_numpy, att, &value);
                     break;
 #               endif
                 }
                 case PyTango::ExtractAsList: {
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                         __get_write_value_array_lists, att, &value);
                     break;
                 }
diff --git a/src/tgutils.h b/src/tgutils.h
index ba5b9a2..5a8f9ef 100644
--- a/src/tgutils.h
+++ b/src/tgutils.h
@@ -26,6 +26,10 @@
 #include <cassert>
 #include <tango.h>
 
+#ifndef TgLibVersNb
+#   define TgLibVersNb 80005
+#endif
+
 namespace Tango
 {
     typedef std::vector<DbHistory> DbHistoryList;
@@ -163,88 +167,173 @@ DEF_TANGO_SCALAR_ARRAY_NAMES( DEV_ULONG64, DEVVAR_ULONG64ARRAY );
 
 
 
-#define __TANGO_DEPEND_ON_TYPE_AUX(typename_, DOIT) \
+#define __TANGO_DEPEND_ON_TYPE_AUX_ID(typename_, DOIT) \
     case Tango:: typename_: { \
         static const long tangoTypeConst = Tango:: typename_; \
         DOIT; \
         break; \
     }
 
-#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(tid, DOIT) if (true) { \
+#define __TANGO_DEPEND_ON_TYPE_AUX_NAME(tid_, DOIT) \
+    case Tango:: tid_: { \
+        typedef typename TANGO_const2type(Tango:: tid_) TangoType; \
+        DOIT; \
+        break; \
+    }
+
+#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(tid, DOIT) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STRING, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_BOOLEAN, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STATE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ENCODED, DOIT) \
+        default: \
+            assert(false); \
+    } } else (void)0
+
+#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, DOIT) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STRING, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_BOOLEAN, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STATE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ENCODED, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STRING, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_BOOLEAN, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STATE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ENCODED, DOIT) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tid, fn, ...) \
-    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(tid, fn<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tid, fn, ...) \
+    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(tid, fn<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, fn, ...) \
+    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, fn<TangoType>(__VA_ARGS__))
 
 /// @todo Not sure about who I choosed to comment out from here...
-#define TANGO_DO_ON_DEVICE_DATA_TYPE(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
+#define TANGO_DO_ON_DEVICE_DATA_TYPE_ID(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_VOID, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_BOOLEAN, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STRING, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_CHARARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STATE, DOIT_SIMPLE) \
-/*        __TANGO_DEPEND_ON_TYPE_AUX(CONST_DEV_STRING, DOIT_SIMPLE) */\
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT_SIMPLE)*/ \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEV_INT, DOIT_SIMPLE) */\
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ENCODED, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_VOID, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_BOOLEAN, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STRING, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_CHARARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STATE, DOIT_SIMPLE) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(CONST_DEV_STRING, DOIT_SIMPLE) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT_SIMPLE)*/ \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_INT, DOIT_SIMPLE) */\
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ENCODED, DOIT_SIMPLE) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_DEVICE_DATA_TYPE(tid, fn_simple, fn_array, ...) \
-    TANGO_DO_ON_DEVICE_DATA_TYPE(tid, fn_simple<tangoTypeConst>(__VA_ARGS__), fn_array<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_DO_ON_DEVICE_DATA_TYPE_NAME(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_VOID, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_BOOLEAN, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STRING, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_CHARARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STATE, DOIT_SIMPLE) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(CONST_DEV_STRING, DOIT_SIMPLE) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT_SIMPLE)*/ \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_INT, DOIT_SIMPLE) */\
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ENCODED, DOIT_SIMPLE) \
+        default: \
+            assert(false); \
+    } } else (void)0
 
-#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, DOIT) if (true) { \
+#define TANGO_CALL_ON_DEVICE_DATA_TYPE_ID(tid, fn_simple, fn_array, ...) \
+    TANGO_DO_ON_DEVICE_DATA_TYPE_ID(tid, fn_simple<tangoTypeConst>(__VA_ARGS__), fn_array<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_DEVICE_DATA_TYPE_NAME(tid, fn_simple, fn_array, ...) \
+    TANGO_DO_ON_DEVICE_DATA_TYPE_NAME(tid, fn_simple<TangoType>(__VA_ARGS__), fn_array<TangoType>(__VA_ARGS__))
+
+#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, DOIT) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, fn, ...) \
-    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, fn<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, DOIT) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT) \
+        default: \
+            assert(false); \
+    } } else (void)0
+
+#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, fn, ...) \
+    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, fn<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, fn, ...) \
+    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, fn<tangoTypeConst>(__VA_ARGS__))
diff --git a/src/to_py.h b/src/to_py.h
index d12f2f6..c394c26 100644
--- a/src/to_py.h
+++ b/src/to_py.h
@@ -328,6 +328,37 @@ boost::python::object to_py(const Tango::PeriodicEventProp &);
 boost::python::object to_py(const Tango::ArchiveEventProp &);
 boost::python::object to_py(const Tango::EventProperties &);
 
+template<typename T>
+void to_py(Tango::MultiAttrProp<T> &multi_attr_prop, boost::python::object &py_multi_attr_prop)
+{
+    if(py_multi_attr_prop.ptr() == Py_None)
+    {
+        PYTANGO_MOD
+        py_multi_attr_prop = pytango.attr("MultiAttrProp")();
+    }
+
+    py_multi_attr_prop.attr("label") = multi_attr_prop.label;
+    py_multi_attr_prop.attr("description") = multi_attr_prop.description;
+    py_multi_attr_prop.attr("unit") = multi_attr_prop.unit;
+    py_multi_attr_prop.attr("standard_unit") = multi_attr_prop.standard_unit;
+    py_multi_attr_prop.attr("display_unit") = multi_attr_prop.display_unit;
+    py_multi_attr_prop.attr("format") = multi_attr_prop.format;
+    py_multi_attr_prop.attr("min_value") = multi_attr_prop.min_value.get_str();
+    py_multi_attr_prop.attr("max_value") = multi_attr_prop.max_value.get_str();
+    py_multi_attr_prop.attr("min_alarm") = multi_attr_prop.min_alarm.get_str();
+    py_multi_attr_prop.attr("max_alarm") = multi_attr_prop.max_alarm.get_str();
+    py_multi_attr_prop.attr("min_warning") = multi_attr_prop.min_warning.get_str();
+    py_multi_attr_prop.attr("max_warning") = multi_attr_prop.max_warning.get_str();
+    py_multi_attr_prop.attr("delta_t") = multi_attr_prop.delta_t.get_str();
+    py_multi_attr_prop.attr("delta_val") = multi_attr_prop.delta_val.get_str();
+    py_multi_attr_prop.attr("event_period") = multi_attr_prop.event_period.get_str();
+    py_multi_attr_prop.attr("archive_period") = multi_attr_prop.archive_period.get_str();
+    py_multi_attr_prop.attr("rel_change") = multi_attr_prop.rel_change.get_str();
+    py_multi_attr_prop.attr("abs_change") = multi_attr_prop.abs_change.get_str();
+    py_multi_attr_prop.attr("archive_rel_change") = multi_attr_prop.archive_rel_change.get_str();
+    py_multi_attr_prop.attr("archive_abs_change") = multi_attr_prop.archive_abs_change.get_str();
+}
+
 boost::python::object to_py(const Tango::AttributeConfig &, 
                             boost::python::object py_attr_conf);
 boost::python::object to_py(const Tango::AttributeConfig_2 &,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git



More information about the debian-science-commits mailing list