Skip to content
Snippets Groups Projects
Commit b55d1790 authored by Jan David Mol's avatar Jan David Mol
Browse files

Merge branch 'L2SS-449-add-deviceproxy-to-devices' into 'master'

Resolve L2SS-449 "Add deviceproxy to devices"

Closes L2SS-449

See merge request !175
parents d8afde2d f042aeaf
No related branches found
No related tags found
1 merge request!175Resolve L2SS-449 "Add deviceproxy to devices"
......@@ -16,7 +16,6 @@ from abc import abstractmethod
# PyTango imports
from tango.server import Device, command, DeviceMeta, attribute
from tango import AttrWriteType, DevState, DebugIt, Attribute, DeviceProxy
import time
import math
......@@ -87,6 +86,15 @@ class lofar_device(Device, metaclass=AbstractDeviceMetas):
self.set_state(DevState.OFF)
self.set_status("Device is in the OFF state.")
# register a proxy to ourselves, to interact with
# our attributes and commands as a client would.
#
# this is required to get/set attributes.
#
# we cannot write directly to our attribute, as that would not
# trigger a write_{name} call. See https://www.tango-controls.org/community/forum/c/development/c/accessing-own-deviceproxy-class/?page=1#post-2021
self.proxy = DeviceProxy(self.get_name())
@log_exceptions()
def delete_device(self):
"""Hook to delete resources allocated in init_device.
......@@ -231,12 +239,6 @@ class lofar_device(Device, metaclass=AbstractDeviceMetas):
2) Any remaining default properties are set.
"""
# we cannot write directly to our attribute, as that would not
# trigger a write_{name} call. See https://www.tango-controls.org/community/forum/c/development/c/accessing-own-deviceproxy-class/?page=1#post-2021
# obtain a proxy to myself, to write values
proxy = DeviceProxy(self.get_name())
# collect all attributes for which defaults are provided
attributes_with_defaults = [name for name in dir(self)
# collect all attribute members
......@@ -254,7 +256,7 @@ class lofar_device(Device, metaclass=AbstractDeviceMetas):
# set the attribute to the configured default
self.debug_stream(f"Setting attribute {name} to {default_value}")
proxy.write_attribute(name, default_value)
self.proxy.write_attribute(name, default_value)
except Exception as e:
# log which attribute we're addressing
raise Exception(f"Cannot assign default to attribute {name}") from e
......@@ -281,13 +283,11 @@ class lofar_device(Device, metaclass=AbstractDeviceMetas):
pollperiod: how often to check the attribute, in seconds.
"""
attr = getattr(self, attr_name)
# Poll every half a second
for _ in range(math.ceil(timeout/pollperiod)):
if attr != value:
if getattr(self.proxy, attr_name) != value:
return
time.sleep(pollperiod)
raise Exception(f"{attr} != {value} after f{timeout} seconds still.")
raise Exception(f"{attr_name} != {value} after {timeout} seconds still.")
......@@ -57,8 +57,8 @@ class RECV(opcua_device):
# ----------
# Attributes
# ----------
ANT_status_R = attribute(dtype=str, max_dim_x=3, max_dim_y=32)
RCU_LED_colour_R = attribute(dtype=numpy.uint32, max_dim_x=32, fget=lambda self: (2 * self.RCU_LED_green_on_R + 4 * self.RCU_LED_red_on_R).astype(numpy.uint32))
ANT_status_R = attribute(dtype=(str,), max_dim_x=3, max_dim_y=32)
RCU_LED_colour_R = attribute(dtype=(numpy.uint32,), max_dim_x=32, fget=lambda self: (2 * self.proxy.RCU_LED_green_on_R + 4 * self.proxy.RCU_LED_red_on_R).astype(numpy.uint32))
ANT_mask_RW = attribute_wrapper(comms_annotation=["ANT_mask_RW" ],datatype=numpy.bool_ , dims=(3,32), access=AttrWriteType.READ_WRITE)
HBAT_BF_delays_R = attribute_wrapper(comms_annotation=["HBAT_BF_delays_R" ],datatype=numpy.int64 , dims=(32,96))
......@@ -170,8 +170,8 @@ class RECV(opcua_device):
This function can be used as input to modify the RCU_mask_RW. """
rcu_mask = self.RCU_mask_RW
i2c_errors = self.RCU_I2C_STATUS_R
rcu_mask = self.proxy.RCU_mask_RW
i2c_errors = self.proxy.RCU_I2C_STATUS_R
nr_rcus = len(rcu_mask)
rcu_status = [""] * nr_rcus
......@@ -195,10 +195,10 @@ class RECV(opcua_device):
This function can be used as input to modify the Ant_mask_RW. """
ant_mask = self.ANT_mask_RW
rcu_mask = self.RCU_mask_RW
adc_lock = self.RCU_ADC_locked_R
i2c_errors = self.RCU_I2C_STATUS_R
ant_mask = self.proxy.ANT_mask_RW
rcu_mask = self.proxy.RCU_mask_RW
adc_lock = self.proxy.RCU_ADC_locked_R
i2c_errors = self.proxy.RCU_I2C_STATUS_R
nr_rcus = len(ant_mask)
nr_ants_per_rcu = len(ant_mask[0])
......
......@@ -13,12 +13,14 @@ from tango import DevState
from tangostationcontrol.test.clients.test_client import test_client
from tangostationcontrol.clients.attribute_wrapper import *
from tangostationcontrol.devices.lofar_device import *
import tangostationcontrol.devices.lofar_device
# Test imports
from tango.test_context import DeviceTestContext
from tangostationcontrol.test import base
import asyncio
import mock
scalar_dims = (1,)
spectrum_dims = (4,)
......@@ -38,6 +40,11 @@ def dev_init(device):
class TestAttributeTypes(base.TestCase):
def setUp(self):
# Avoid the device trying to access itself as a client
self.deviceproxy_patch = mock.patch.object(tangostationcontrol.devices.lofar_device,'DeviceProxy')
self.deviceproxy_patch.start()
self.addCleanup(self.deviceproxy_patch.stop)
class str_scalar_device(lofar_device):
scalar_R = attribute_wrapper(comms_annotation="str_scalar_R", datatype=numpy.str)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment