From 81b8e25237007e11bfc99b38e57cbc27ec63751c Mon Sep 17 00:00:00 2001 From: thijs snijder <snijder@astron.nl> Date: Thu, 28 Apr 2022 14:54:59 +0200 Subject: [PATCH] worked on polling thread for temperature_manager --- .../devices/temperature_manager.py | 92 ++++++++++++------- .../test_device_temperature_manager.py | 16 ---- .../test_device_temperature_manager.py | 45 +++++++++ 3 files changed, 103 insertions(+), 50 deletions(-) delete mode 100644 tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py create mode 100644 tangostationcontrol/tangostationcontrol/test/devices/test_device_temperature_manager.py diff --git a/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py b/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py index 20dd1875b..d1905e9d5 100644 --- a/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py +++ b/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py @@ -15,28 +15,43 @@ from tangostationcontrol.common.lofar_logging import device_logging_to_python, l from tango._tango import DevState from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy -from tango import Util, DeviceProxy, DevSource, DeviceAttribute, AttributeInfo, AttrDataFormat, attr_config -from tango.server import attribute, device_property - +from tango import Util, DeviceProxy, DevSource, DeviceAttribute, AttributeInfo, AttrDataFormat, DebugIt, DevState +from tangostationcontrol.devices.device_decorators import only_in_states, fault_on_error +from tango.server import attribute, device_property, command +import time import logging +from threading import Thread logger = logging.getLogger() __all__ = ["TemperatureManager", "main"] -class temp_attr: - def __init__(self, dev, attr): +class devAttr: + def __init__(self, dev : DeviceProxy, attr : AttributeInfo): self.dev = dev self.attr = attr - # fetch attribute configuration - attr_config = self.dev.get_attribute_config(attr.name) + attr_config = self.dev.get_attribute_config(self.attr.name) self.is_scalar = attr_config.data_format == AttrDataFormat.SCALAR +def take_action(device_attribute : devAttr): + device_attribute.dev.fault() + +def read_alarm_state(device_attribute : devAttr): + val = device_attribute.dev.read_attribute(device_attribute.attr.name) + + # The "_temp_error_r" is a value or list of bools. If any of the bools is true that means there is an alarm + if device_attribute.is_scalar: + is_in_alarm = val.value + else: + is_in_alarm = any(val.value) + + if is_in_alarm: + logger.warning(f"Warning!! A device: {device_attribute.dev} has entered a temperature alarm state") @device_logging_to_python() class TemperatureManager(lofar_device): @@ -64,26 +79,28 @@ class TemperatureManager(lofar_device): @log_exceptions() def configure_for_initialise(self): - # Set a reference of RECV device that is correlated to this BEAM device + self.poll = False util = Util.instance() instance_number = self.get_name().split('/')[2] ds_inst = util.get_ds_inst_name() # all hardware device proxies go here - self.sdp_proxy = DeviceProxy(f"{ds_inst}/SDP/{instance_number}") - self.pdu_proxy = DeviceProxy(f"{ds_inst}/PDU/{instance_number}") - self.recv_proxy = DeviceProxy(f"{ds_inst}/RECV/{instance_number}") - self.unb2_proxy = DeviceProxy(f"{ds_inst}/UNB2/{instance_number}") - self.apsct_proxy = DeviceProxy(f"{ds_inst}/APSCT/{instance_number}") - self.apspu_proxy = DeviceProxy(f"{ds_inst}/APSPU/{instance_number}") + sdp_proxy = DeviceProxy(f"{ds_inst}/SDP/{instance_number}") + pdu_proxy = DeviceProxy(f"{ds_inst}/PDU/{instance_number}") + recv_proxy = DeviceProxy(f"{ds_inst}/RECV/{instance_number}") + unb2_proxy = DeviceProxy(f"{ds_inst}/UNB2/{instance_number}") + apsct_proxy = DeviceProxy(f"{ds_inst}/APSCT/{instance_number}") + apspu_proxy = DeviceProxy(f"{ds_inst}/APSPU/{instance_number}") # for easy iteration - dev_list = [self.sdp_proxy, self.pdu_proxy, self.recv_proxy, self.unb2_proxy, self.apsct_proxy, self.apspu_proxy] - self.temp_attr_list = [] + dev_list = [sdp_proxy, pdu_proxy, recv_proxy, unb2_proxy, apsct_proxy, apspu_proxy] + + self.temp_error_attr_list = [] for dev in dev_list: + logger.info(f"Looking for temperature alarm attributes in device {dev}") dev.set_source(DevSource.DEV) # get a list of AttributeInfo objects @@ -92,8 +109,10 @@ class TemperatureManager(lofar_device): # make a list of all temperature attributes for attr in attribute_list: if "_temp_error_r" in attr.name.lowercase(): - self.temp_attr_list.append(temp_attr(dev, attr)) + self.temp_error_attr_list.append(devAttr(dev, attr)) + logger.info(f"Found temperature alarm attribute {attr.name} in device {dev}") + self.polling_thread = Thread(target=self.polling_loop) super().configure_for_initialise() @log_exceptions() @@ -104,28 +123,33 @@ class TemperatureManager(lofar_device): def configure_for_off(self): super().configure_for_off() - def read_alarm_state(self, devAttr): - val = devAttr.dev.read_attribute(devAttr.attr.name) - - if devAttr.is_scalar: - if val.value: - # there is an alarm state - else: - if any(val.value): - # there is something in the alarm state - pass - - def polling_loop(self): - - for i in self.temp_attr_list: - self.read_alarm_state(i) - - + @command() + @only_in_states([DevState.ON]) + def enable_polling(self): + self.poll = True + self.polling_thread.start() + logger.info(f"Temperature manager is now polling for alarms") + @command() + @only_in_states([DevState.ON]) + def disable_polling(self): + self.poll = False + self.polling_thread.join() + logger.info(f"Temperature manager has stopped polling for alarms") + TEMP_MANAGER_polling_state_R = attribute(dtype=bool) + def read_TEMP_MANAGER_polling_state_R(self): + return self.poll + def polling_loop(self): + while self.poll: + # we'll see how to change this later + time.sleep(1) + # go through all the temperature alarm attributes and check if there is an alarm + for i in self.temp_error_attr_list: + read_alarm_state(i) # ---------- diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py deleted file mode 100644 index ea884acf1..000000000 --- a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# -# This file is part of the LOFAR 2.0 Station Software -# -# -# -# Distributed under the terms of the APACHE license. -# See LICENSE.txt for more info. -from .base import AbstractTestBases - -class TestTemperatureManager(AbstractTestBases.TestDeviceBase): - - def setUp(self): - """Intentionally recreate the device object in each test""" - super().setUp("STAT/TemperatureManager/1") diff --git a/tangostationcontrol/tangostationcontrol/test/devices/test_device_temperature_manager.py b/tangostationcontrol/tangostationcontrol/test/devices/test_device_temperature_manager.py new file mode 100644 index 000000000..ef6cfee66 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/test/devices/test_device_temperature_manager.py @@ -0,0 +1,45 @@ + +# -*- coding: utf-8 -*- +# +# This file is part of the LOFAR 2.0 Station Software +# +# +# +# Distributed under the terms of the APACHE license. +# See LICENSE.txt for more info. +from tango.test_context import DeviceTestContext +from tangostationcontrol.devices import temperature_manager, lofar_device + +import mock + +from tangostationcontrol.test import base + + + + +class TestTemperatureManagerDevice(base.TestCase): + + def setUp(self): + super(TestTemperatureManagerDevice, self).setUp() + + # Patch DeviceProxy to allow making the proxies during initialisation + # that we otherwise avoid using + for device in [temperature_manager, lofar_device]: + proxy_patcher = mock.patch.object( + device, 'DeviceProxy') + proxy_patcher.start() + self.addCleanup(proxy_patcher.stop) + + def test_init(self): + with DeviceTestContext(temperature_manager.TemperatureManager, process=True, timeout=10) as proxy: + proxy.initialise() + proxy.on() + + proxy.enable_polling() + self.assertTrue(proxy.TEMP_MANAGER_polling_state_R) + + proxy.disable_polling() + self.assertFalse(proxy.TEMP_MANAGER_polling_state_R) + + + -- GitLab