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

Change hardware_powered_R into a fraction to see partial powerups, and support it for more devices

parent 27837eb9
No related branches found
No related tags found
1 merge request!893Change hardware_powered_R into a fraction to see partial powerups, and support it for more devices
Showing
with 108 additions and 20 deletions
...@@ -166,6 +166,8 @@ Next change the version in the following places: ...@@ -166,6 +166,8 @@ Next change the version in the following places:
# Release Notes # Release Notes
* 0.32.2 Change hardware_powered_R to hardware_powered_fraction_R to report partial power.
Implemented hardware_powered_fraction_R for more devices.
* 0.32.1 Do not serve stale metrics * 0.32.1 Do not serve stale metrics
* 0.32.0 Add available_in_power_state_R attribute to determine from which station state a device will be available * 0.32.0 Add available_in_power_state_R attribute to determine from which station state a device will be available
* 0.31.4 Bugfixes for DTS configuration, * 0.31.4 Bugfixes for DTS configuration,
......
0.32.1 0.32.2
...@@ -204,9 +204,9 @@ class APSCT(OPCUADevice): ...@@ -204,9 +204,9 @@ class APSCT(OPCUADevice):
# overloaded functions # overloaded functions
# -------- # --------
def _read_hardware_powered_R(self): def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power""" """Read attribute which monitors the power"""
return self.read_attribute("APSCT_PWR_on_R") return 1.0 * self.read_attribute("APSCT_PWR_on_R")
def _power_hardware_on(self): def _power_hardware_on(self):
"""Turns on the 200MHz clock.""" """Turns on the 200MHz clock."""
......
...@@ -156,14 +156,14 @@ class BeamDevice(AsyncDevice): ...@@ -156,14 +156,14 @@ class BeamDevice(AsyncDevice):
Tracking_enabled_R = attribute( Tracking_enabled_R = attribute(
access=AttrWriteType.READ, access=AttrWriteType.READ,
doc="Whether the tile beam is updated periodically", doc="Whether the beam is updated periodically",
dtype=bool, dtype=bool,
fget=lambda self: bool(self.Beam_tracker and self.Beam_tracker.is_alive()), fget=lambda self: bool(self.Beam_tracker and self.Beam_tracker.is_alive()),
) )
Tracking_enabled_RW = attribute( Tracking_enabled_RW = attribute(
access=AttrWriteType.READ_WRITE, access=AttrWriteType.READ_WRITE,
doc="Whether the tile beam should be updated periodically", doc="Whether the beam should be updated periodically",
dtype=bool, dtype=bool,
fget=lambda self: self._tracking_enabled_rw, fget=lambda self: self._tracking_enabled_rw,
) )
...@@ -218,7 +218,7 @@ class BeamDevice(AsyncDevice): ...@@ -218,7 +218,7 @@ class BeamDevice(AsyncDevice):
# store the new values # store the new values
self._beam_manager.new_pointing_direction = numpy.array(value, dtype="<U32") self._beam_manager.new_pointing_direction = numpy.array(value, dtype="<U32")
# force update across tiles if pointing changes # force update if pointing changes
self.Beam_tracker.force_update() self.Beam_tracker.force_update()
logger.info("Pointing direction update requested") logger.info("Pointing direction update requested")
...@@ -234,6 +234,10 @@ class BeamDevice(AsyncDevice): ...@@ -234,6 +234,10 @@ class BeamDevice(AsyncDevice):
# overloaded functions # overloaded functions
# -------- # --------
async def _read_hardware_powered_fraction_R(self):
# We consider 'powered' if the beam tracker is running
return 1.0 * await self.async_read_attribute("Tracking_enabled_R")
def _init_device(self, beam_manager: AbstractBeamManager): def _init_device(self, beam_manager: AbstractBeamManager):
super()._init_device() super()._init_device()
......
...@@ -226,9 +226,11 @@ class LOFARDevice(Device): ...@@ -226,9 +226,11 @@ class LOFARDevice(Device):
fget=lambda self: numpy.int64(self._access_count), fget=lambda self: numpy.int64(self._access_count),
) )
hardware_powered_R = attribute( hardware_powered_fraction_R = attribute(
dtype=bool, doc="Fraction of hardware that is powered on (0 = nothing, 1 = all).",
fget=lambda self: self._read_hardware_powered_R(), dtype=numpy.float64,
fget=lambda self: self._read_hardware_powered_fraction_R(),
fisallowed="is_attribute_access_allowed",
) )
event_thread_running_R = attribute( event_thread_running_R = attribute(
...@@ -647,11 +649,11 @@ class LOFARDevice(Device): ...@@ -647,11 +649,11 @@ class LOFARDevice(Device):
# increase the number of accesses # increase the number of accesses
self._access_count += 1 self._access_count += 1
def _read_hardware_powered_R(self): def _read_hardware_powered_fraction_R(self):
"""Overloadable function called in read attribute hardware_powered_R""" """Overloadable function called to ask whether all hardware is powered."""
# If device backs no hardware, assume it's powered # If device backs no hardware, assume it's powered
return True return 1.0
def properties_changed(self): def properties_changed(self):
pass pass
......
...@@ -386,6 +386,17 @@ class RECVDevice(OPCUADevice): ...@@ -386,6 +386,17 @@ class RECVDevice(OPCUADevice):
# overloaded functions # overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
mask = self.read_attribute("RCU_mask_RW")
powered = self.read_attribute("RCU_PWR_good_R")
try:
return numpy.count_nonzero(powered & mask) / numpy.count_nonzero(mask)
except ZeroDivisionError:
return 1.0
def _power_hardware_on(self): def _power_hardware_on(self):
"""Power the RCUs.""" """Power the RCUs."""
......
...@@ -217,9 +217,9 @@ class CCD(OPCUADevice): ...@@ -217,9 +217,9 @@ class CCD(OPCUADevice):
self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout) self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout)
logger.debug("Put CCD in off state") logger.debug("Put CCD in off state")
def _read_hardware_powered_R(self): def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power""" """Read attribute which monitors the power"""
return self.read_attribute("CCD_PWR_on_R") return 1.0 * self.read_attribute("CCD_PWR_on_R")
def _power_hardware_on(self): def _power_hardware_on(self):
"""Forward the clock signal.""" """Forward the clock signal."""
......
...@@ -113,11 +113,11 @@ class EC(OPCUADevice): ...@@ -113,11 +113,11 @@ class EC(OPCUADevice):
# overloaded functions # overloaded functions
# -------- # --------
def _read_hardware_powered_R(self): def _read_hardware_powered_fraction_R(self):
# the device and translator are one, so if # the device and translator are one, so if
# the translator is reachable, the hardware # the translator is reachable, the hardware
# is powered. # is powered.
return self.read_attribute("connected_R") return 1.0 * self.read_attribute("connected_R")
# -------- # --------
# Commands # Commands
......
...@@ -669,6 +669,10 @@ class Beamlet(OPCUADevice): ...@@ -669,6 +669,10 @@ class Beamlet(OPCUADevice):
# Overloaded functions # Overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
return 1.0 * any(self.read_attribute("FPGA_beamlet_output_enable_R"))
def configure_for_initialise(self): def configure_for_initialise(self):
super().configure_for_initialise() super().configure_for_initialise()
......
...@@ -195,6 +195,10 @@ class BST(Statistics): ...@@ -195,6 +195,10 @@ class BST(Statistics):
# Overloaded functions # Overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
return 1.0 * any(self.read_attribute("FPGA_bst_offload_enable_R"))
def _power_hardware_on(self): def _power_hardware_on(self):
self.proxy.write_attribute( self.proxy.write_attribute(
"FPGA_bst_offload_enable_RW", self.FPGA_bst_offload_enable_RW_default "FPGA_bst_offload_enable_RW", self.FPGA_bst_offload_enable_RW_default
......
...@@ -366,6 +366,19 @@ class SDPFirmware(OPCUADevice): ...@@ -366,6 +366,19 @@ class SDPFirmware(OPCUADevice):
self.Firmware_Boot_timeout, self.Firmware_Boot_timeout,
) )
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
boot_image = self.read_attribute("FPGA_boot_image_R")
mask = self.read_attribute("TR_fpga_mask_R")
try:
return numpy.count_nonzero((boot_image == 1) & mask) / numpy.count_nonzero(
mask
)
except ZeroDivisionError:
return 1.0
def _power_hardware_on(self): def _power_hardware_on(self):
"""Boot the SDP Firmware user image""" """Boot the SDP Firmware user image"""
......
...@@ -555,6 +555,17 @@ class SDP(OPCUADevice): ...@@ -555,6 +555,17 @@ class SDP(OPCUADevice):
# overloaded functions # overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
mask = self.control.read_parent_attribute("TR_fpga_mask_R")
powered = self.read_attribute("FPGA_processing_enable_R")
try:
return numpy.count_nonzero(powered & mask) / numpy.count_nonzero(mask)
except ZeroDivisionError:
return 1.0
def configure_for_initialise(self): def configure_for_initialise(self):
super().configure_for_initialise() super().configure_for_initialise()
......
...@@ -222,6 +222,10 @@ class SST(Statistics): ...@@ -222,6 +222,10 @@ class SST(Statistics):
# Overloaded functions # Overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
return 1.0 * any(self.read_attribute("FPGA_sst_offload_enable_R"))
def _power_hardware_on(self): def _power_hardware_on(self):
self.proxy.write_attribute( self.proxy.write_attribute(
"FPGA_sst_offload_enable_RW", self.FPGA_sst_offload_enable_RW_default "FPGA_sst_offload_enable_RW", self.FPGA_sst_offload_enable_RW_default
......
...@@ -722,6 +722,31 @@ class XST(Statistics): ...@@ -722,6 +722,31 @@ class XST(Statistics):
# Overloaded functions # Overloaded functions
# -------- # --------
def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power"""
processing_enabled = self.read_attribute("FPGA_xst_processing_enable_R")
offload_enabled = self.read_attribute("FPGA_xst_offload_enable_R")
expected_processing_enabled = numpy.array(
self.FPGA_xst_processing_enable_RW_default, dtype=bool
)
expected_offload_enabled = numpy.array(
self.FPGA_xst_offload_enable_RW_default, dtype=bool
)
mask = expected_processing_enabled | expected_offload_enabled
try:
# "powered" means processing and offload is as expected for the FPGAs required
return numpy.count_nonzero(
(processing_enabled == expected_processing_enabled)
& (offload_enabled == expected_offload_enabled)
& mask
) / numpy.count_nonzero(mask)
except ZeroDivisionError:
return 1.0
def _power_hardware_on(self): def _power_hardware_on(self):
self.proxy.write_attribute( self.proxy.write_attribute(
"FPGA_xst_processing_enable_RW", self.FPGA_xst_processing_enable_RW_default "FPGA_xst_processing_enable_RW", self.FPGA_xst_processing_enable_RW_default
......
...@@ -427,10 +427,16 @@ class UNB2(OPCUADevice): ...@@ -427,10 +427,16 @@ class UNB2(OPCUADevice):
# overloaded functions # overloaded functions
# -------- # --------
def _read_hardware_powered_R(self): def _read_hardware_powered_fraction_R(self):
"""Read attribute which monitors the power""" """Read attribute which monitors the power"""
# Return True if all uniboards are powered
return all(self.read_attribute("UNB2_PWR_on_R")) mask = self.read_attribute("UNB2_mask_RW")
powered = self.read_attribute("UNB2_PWR_on_R")
try:
return numpy.count_nonzero(powered & mask) / numpy.count_nonzero(mask)
except ZeroDivisionError:
return 1.0
def _power_hardware_on(self): def _power_hardware_on(self):
"""Power the Uniboards.""" """Power the Uniboards."""
...@@ -438,7 +444,9 @@ class UNB2(OPCUADevice): ...@@ -438,7 +444,9 @@ class UNB2(OPCUADevice):
self.UNB2_on() self.UNB2_on()
self.wait_attribute("UNB2TR_translator_busy_R", False, self.UNB2_On_Off_timeout) self.wait_attribute("UNB2TR_translator_busy_R", False, self.UNB2_On_Off_timeout)
self.wait_attribute("hardware_powered_R", True, self.UNB2_On_Off_timeout) self.wait_attribute(
"hardware_powered_fraction_R", 1.0, self.UNB2_On_Off_timeout
)
def _power_hardware_off(self): def _power_hardware_off(self):
"""Disable the Uniboards.""" """Disable the Uniboards."""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment