1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
* SPDX-FileCopyrightText: All Contributors to the PyTango project
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef PYTANGO_ATTRIBUTE_UTILS_H
#define PYTANGO_ATTRIBUTE_UTILS_H
#include "common_header.h"
#include "convertors/type_casters.h"
#include "server/attribute_utils.h"
#define __SET_ALARM_WARNING(self, c_value, target) \
switch(target) { \
case TargetValue::ALARM_MIN: \
self.set_min_alarm(c_value); \
break; \
case TargetValue::WARNING_MIN: \
self.set_min_warning(c_value); \
break; \
case TargetValue::WARNING_MAX: \
self.set_max_warning(c_value); \
break; \
case TargetValue::ALARM_MAX: \
self.set_max_alarm(c_value); \
break; \
default: \
throw std::invalid_argument("Unknown target"); \
}
template <int tangoTypeConst>
inline void _set_value_limit(Tango::Attribute &self, py::object &value, TargetValue &target) {
using TangoScalarType = typename TANGO_const2type(tangoTypeConst);
TangoScalarType c_value;
python_scalar_to_cpp<tangoTypeConst>::convert(value, c_value);
__SET_ALARM_WARNING(self, c_value, target)
}
inline void _set_value_limit(Tango::Attribute &self, std::string &c_value, TargetValue &target) {
__SET_ALARM_WARNING(self, c_value, target)
}
#define __SET_VALUE(self, c_value, target) \
switch(target) { \
case TargetValue::VALUE_MIN: \
self.set_min_value(c_value); \
break; \
case TargetValue::VALUE_MAX: \
self.set_max_value(c_value); \
break; \
default: \
throw std::invalid_argument("Unknown target"); \
}
template <int tangoTypeConst>
inline void _set_value_limit(Tango::WAttribute &self, py::object &value, TargetValue &target) {
using TangoScalarType = typename TANGO_const2type(tangoTypeConst);
TangoScalarType c_value;
python_scalar_to_cpp<tangoTypeConst>::convert(value, c_value);
__SET_VALUE(self, c_value, target)
}
inline void _set_value_limit(Tango::WAttribute &self, std::string &c_value, TargetValue &target) {
__SET_VALUE(self, c_value, target)
}
template <typename AttrType>
void set_value_limit(AttrType &self, py::object &value, TargetValue target) {
if(py::str::check_(value)) {
std::string c_value = value.cast<std::string>();
_set_value_limit(self, c_value, target);
} else {
long tango_type = self.get_data_type();
// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
if(tango_type == Tango::DEV_STRING || tango_type == Tango::DEV_BOOLEAN ||
tango_type == Tango::DEV_STATE) {
tango_type = Tango::DEV_DOUBLE;
} else if(tango_type == Tango::DEV_ENCODED) {
tango_type = Tango::DEV_UCHAR;
}
TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tango_type, _set_value_limit, self, value, target);
}
}
#define __GET_ALARM_WARNING(att, tg_val, source) \
switch(source) { \
case TargetValue::ALARM_MIN: \
att.get_min_alarm(tg_val); \
break; \
case TargetValue::WARNING_MIN: \
att.get_min_warning(tg_val); \
break; \
case TargetValue::WARNING_MAX: \
att.get_max_warning(tg_val); \
break; \
case TargetValue::ALARM_MAX: \
att.get_max_alarm(tg_val); \
break; \
default: \
throw std::invalid_argument("Unknown target"); \
}
template <int tangoTypeConst>
inline py::object _get_value_limit(Tango::Attribute &att, TargetValue &source) {
using TangoScalarType = typename TANGO_const2type(tangoTypeConst);
TangoScalarType tg_val;
__GET_ALARM_WARNING(att, tg_val, source)
return py::cast(tg_val);
}
#define __GET_VALUE(att, tg_val, source) \
switch(source) { \
case TargetValue::VALUE_MIN: \
att.get_min_value(tg_val); \
break; \
case TargetValue::VALUE_MAX: \
att.get_max_value(tg_val); \
break; \
default: \
throw std::invalid_argument("Unknown target"); \
}
template <int tangoTypeConst>
inline py::object _get_value_limit(Tango::WAttribute &att, TargetValue &source) {
using TangoScalarType = typename TANGO_const2type(tangoTypeConst);
TangoScalarType tg_val;
__GET_VALUE(att, tg_val, source)
return py::cast(tg_val);
}
template <typename AttrType>
py::object get_value_limit(AttrType &att, TargetValue source) {
long tango_type = att.get_data_type();
if(tango_type == Tango::DEV_ENCODED) {
tango_type = Tango::DEV_UCHAR;
}
TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tango_type, return _get_value_limit, att, source);
return py::none();
}
#endif // PYTANGO_ATTRIBUTE_UTILS_H
|