# -*- coding: utf-8 -*- # ***************************************************************************** # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Module authors: # Enrico Faulhaber # Markus Zolliker # # ***************************************************************************** """Define Mixin Features for real Modules implemented in the server""" from secop.datatypes import ArrayOf, BoolType, EnumType, \ FloatRange, StringType, StructOf, TupleOf from secop.core import Command, Done, Drivable, Feature, \ Parameter, Property, PersistentParam, Readable from secop.errors import BadValueError, ConfigError from secop.lib import clamp class HasSimpleOffset(Feature): """has a client side offset parameter this is just a storage! """ offset = PersistentParam('offset (physical value + offset = HW value)', FloatRange(unit='deg'), readonly=False, default=0) class HasTargetLimits(Feature): """user limits implementation to be done in the subclass according to standard """ target_limits = PersistentParam('user limits', readonly=False, default=(-9e99, 9e99), datatype=TupleOf(FloatRange(unit='deg'), FloatRange(unit='deg'))) def check_limits(self, value): """check if value is valid""" min_, max_ = self.target_limits if not min_ <= value <= max_: raise BadValueError('limits violation: %g outside [%g, %g]' % (value, min_, max_)) # --- legacy mixins, not agreed as standard --- class HasOffset(Feature): """has an offset parameter implementation to be done in the subclass """ offset = Parameter('offset (physical value + offset = HW value)', FloatRange(unit='$'), readonly=False, default=0) class HasLimits(Feature): """user limits implementation to be done in the subclass for a drivable, abslimits is roughly the same as the target datatype limits, except for the offset """ target_limits = Parameter('user limits for target', readonly=False, default=(-9e99, 9e99), datatype=TupleOf(FloatRange(unit='$'), FloatRange(unit='$'))) def earlyInit(self): super().earlyInit() dt = self.parameters['target'].datatype self.target_limits = dt.min, dt.max def check_limits(self, value): """check if value is valid""" min_, max_ = self.target_limits if not min_ <= value <= max_: raise BadValueError('limits violation: %g outside [%g, %g]' % (value, min_, max_))