Hi Reynald,
Thanks for your detailed reply. Let me try to answer as best I can.
- I did not overload the dev_state method.
- I am using PyTango8 8.1.1, with standard Python POGO code generation (not PythonHL)
I am recreating the problem very easily with a minimal working example here. The following is the device code. It is a dumb device, with 2 states ON/ALARM, and a single attribute “temperature”.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
##############################################################################
## license :
##============================================================================
##
## File : Tester.py
##
## Project : AAVS
##
## This file is part of Tango device class.
##
## Tango 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 3 of the License, or
## (at your option) any later version.
##
## Tango 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 Tango. If not, see <http://www.gnu.org/licenses/>.
##
##
## $Author : andrea.demarco$
##
## $Revision : $
##
## $Date : $
##
## $HeadUrl : $
##============================================================================
## This file is generated by POGO
## (Program Obviously used to Generate tango Object)
##
## (c) - Software Engineering Group - ESRF
##############################################################################
""""""
__all__ = ["Tester", "TesterClass", "main"]
__docformat__ = 'restructuredtext'
import PyTango
import sys
# Add additional import
#----- PROTECTED REGION ID(Tester.additionnal_import) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.additionnal_import
## Device States Description
## ON :
## ALARM :
class Tester (PyTango.Device_4Impl):
#--------- Add you global variables here --------------------------
#----- PROTECTED REGION ID(Tester.global_variables) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.global_variables
def __init__(self,cl, name):
PyTango.Device_4Impl.__init__(self,cl,name)
self.debug_stream("In __init__()")
Tester.init_device(self)
#----- PROTECTED REGION ID(Tester.__init__) ENABLED START -----#
self.set_state(PyTango.DevState.ON)
#----- PROTECTED REGION END -----# // Tester.__init__
def delete_device(self):
self.debug_stream("In delete_device()")
#----- PROTECTED REGION ID(Tester.delete_device) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.delete_device
def init_device(self):
self.debug_stream("In init_device()")
self.get_device_properties(self.get_device_class())
self.attr_temperature_read = 0.0
#----- PROTECTED REGION ID(Tester.init_device) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.init_device
def always_executed_hook(self):
self.debug_stream("In always_excuted_hook()")
#----- PROTECTED REGION ID(Tester.always_executed_hook) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.always_executed_hook
#-----------------------------------------------------------------------------
# Tester read/write attribute methods
#-----------------------------------------------------------------------------
def read_temperature(self, attr):
self.debug_stream("In read_temperature()")
#----- PROTECTED REGION ID(Tester.temperature_read) ENABLED START -----#
attr.set_value(self.attr_temperature_read)
self.debug_stream("Temperature: %f" % self.attr_temperature_read)
#----- PROTECTED REGION END -----# // Tester.temperature_read
def write_temperature(self, attr):
self.debug_stream("In write_temperature()")
data=attr.get_write_value()
#----- PROTECTED REGION ID(Tester.temperature_write) ENABLED START -----#
self.attr_temperature_read = data
#----- PROTECTED REGION END -----# // Tester.temperature_write
#----- PROTECTED REGION ID(Tester.initialize_dynamic_attributes) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.initialize_dynamic_attributes
def read_attr_hardware(self, data):
self.debug_stream("In read_attr_hardware()")
#----- PROTECTED REGION ID(Tester.read_attr_hardware) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.read_attr_hardware
#-----------------------------------------------------------------------------
# Tester command methods
#-----------------------------------------------------------------------------
#----- PROTECTED REGION ID(Tester.programmer_methods) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.programmer_methods
class TesterClass(PyTango.DeviceClass):
#--------- Add you global class variables here --------------------------
#----- PROTECTED REGION ID(Tester.global_class_variables) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.global_class_variables
def dyn_attr(self, dev_list):
"""Invoked to create dynamic attributes for the given devices.
Default implementation calls
:meth:`Tester.initialize_dynamic_attributes` for each device
:param dev_list: list of devices
:type dev_list: :class:`PyTango.DeviceImpl`"""
for dev in dev_list:
try:
dev.initialize_dynamic_attributes()
except:
import traceback
dev.warn_stream("Failed to initialize dynamic attributes")
dev.debug_stream("Details: " + traceback.format_exc())
#----- PROTECTED REGION ID(Tester.dyn_attr) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.dyn_attr
# Class Properties
class_property_list = {
}
# Device Properties
device_property_list = {
}
# Command definitions
cmd_list = {
}
# Attribute definitions
attr_list = {
'temperature':
[[PyTango.DevDouble,
PyTango.SCALAR,
PyTango.READ_WRITE]],
}
def main():
try:
py = PyTango.Util(sys.argv)
py.add_class(TesterClass,Tester,'Tester')
#----- PROTECTED REGION ID(Tester.add_classes) ENABLED START -----#
#----- PROTECTED REGION END -----# // Tester.add_classes
U = PyTango.Util.instance()
U.server_init()
U.server_run()
except PyTango.DevFailed,e:
print '-------> Received a DevFailed exception:',e
except Exception,e:
print '-------> An unforeseen exception occured....',e
if __name__ == '__main__':
main()
In order to test the code, I have the following client side code that I am debugging with. Essentially:
(1) Create a device proxy.
(2) Read current temperature attribute (starts at 0.0)
(3) Set a fake temperature of 45 and read it again (correctly 45.0)
(4) Configure the attribute a FIRST time with alarm settings of 40 (min) and 100 (max), and start polling every second.
(5) Heat up the device a bit by putting it to 65 and read it again (correctly 65.0)
(6) Reconfigure the alarm a SECOND time, with alarm settings of 40 (min) and 60 (max), whilst retaining the previous polling on.
#INIT device
tpm = PyTango.DeviceProxy("test/tester/1")
print tpm
# Get temperature
print "Temperature: %f" % (tpm.temperature)
# Get new temperature
tpm.temperature = 45
print "Temperature: %f" % (tpm.temperature)
# Get attribute info for temperature
temp_attr_config = tpm.get_attribute_config("temperature")
temp_attr_config.alarms.max_alarm = '100'
temp_attr_config.alarms.min_alarm = '40'
temp_attr_config.min_value = '0'
temp_attr_config.max_value = '75'
tpm.set_attribute_config(temp_attr_config)
tpm.poll_attribute(attr_name="temperature", period=1000)
# Start heating up
tpm.temperature = 65
print "Temperature: %f" % (tpm.temperature)
temp_attr_config = tpm.get_attribute_config("temperature")
temp_attr_config.alarms.max_alarm = '60'
temp_attr_config.alarms.min_alarm = '40'
temp_attr_config.min_value = '0'
temp_attr_config.max_value = '75'
tpm.set_attribute_config(temp_attr_config)
From the debug stream:
1457457266 [140141034260224] DEBUG test/tester/1 In always_excuted_hook()
1457457266 [140141034260224] DEBUG test/tester/1 In read_attr_hardware()
1457457266 [140141034260224] DEBUG test/tester/1 In read_temperature()
1457457266 [140141034260224] DEBUG test/tester/1 Temperature: 0.000000
1457457266 [140141034260224] DEBUG test/tester/1 In always_excuted_hook()
1457457266 [140141034260224] DEBUG test/tester/1 In write_temperature()
1457457267 [140141034260224] DEBUG test/tester/1 In always_excuted_hook()
1457457267 [140141034260224] DEBUG test/tester/1 In read_attr_hardware()
1457457267 [140141034260224] DEBUG test/tester/1 In read_temperature()
1457457267 [140141034260224] DEBUG test/tester/1 Temperature: 45.000000
1457457271 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457271 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457271 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457271 [140140555007744] DEBUG test/tester/1 Temperature: 45.000000
1457457272 [140141034260224] DEBUG test/tester/1 In always_excuted_hook()
1457457272 [140141034260224] DEBUG test/tester/1 In write_temperature()
1457457272 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457272 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457272 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457272 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
1457457273 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457273 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457273 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457273 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
1457457274 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457274 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457274 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457274 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
1457457275 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457275 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457275 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457275 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
1457457275 [140140555007744] ERROR test/tester/1 MAX ALARM for attribute temperature
1457457276 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457276 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457276 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457276 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
1457457277 [140140555007744] DEBUG test/tester/1 In always_excuted_hook()
1457457277 [140140555007744] DEBUG test/tester/1 In read_attr_hardware()
1457457277 [140140555007744] DEBUG test/tester/1 In read_temperature()
1457457277 [140140555007744] DEBUG test/tester/1 Temperature: 65.000000
If I open the device in AtkPanel, I can see the temperature attribute in orange colour (ALARM), but the device state is still green (ON).
Something seems really wrong 
EDIT: If I simply start the device, and modify the temperature via AtkPanel, and set up alarm max/min via Jive, then the device works as expected - the device goes to ALARM state! So something is wrong with how the attribute/alarm is being configured via my code, or via PyTango…
Andrea