diff --git a/README.md b/README.md
index 01a1f0f3bd5346be3abfee03e1ef89fc4290066f..65d47484fa671a49ac39671844c6f8801ba4c38d 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,8 @@ Next change the version in the following places:
 
 # 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.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,
diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION
index fd9620c08c1510d4be7d653d09b499dec0f4eb20..989b29cc323f5dacffba2e29082af6e69efafb82 100644
--- a/tangostationcontrol/VERSION
+++ b/tangostationcontrol/VERSION
@@ -1 +1 @@
-0.32.1
+0.32.2
diff --git a/tangostationcontrol/tangostationcontrol/devices/apsct.py b/tangostationcontrol/tangostationcontrol/devices/apsct.py
index b17a82068d51fae576c317861e4e409afdfd80fa..7c7c1890e17719bbecdd180ecc221c730636cc84 100644
--- a/tangostationcontrol/tangostationcontrol/devices/apsct.py
+++ b/tangostationcontrol/tangostationcontrol/devices/apsct.py
@@ -204,9 +204,9 @@ class APSCT(OPCUADevice):
     # overloaded functions
     # --------
 
-    def _read_hardware_powered_R(self):
+    def _read_hardware_powered_fraction_R(self):
         """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):
         """Turns on the 200MHz clock."""
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py
index ddb2773d64810c3c5174d6677a918706deb7e338..5122e67ec89fe71cb107ccd106903f3f8600469b 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py
@@ -156,14 +156,14 @@ class BeamDevice(AsyncDevice):
 
     Tracking_enabled_R = attribute(
         access=AttrWriteType.READ,
-        doc="Whether the tile beam is updated periodically",
+        doc="Whether the beam is updated periodically",
         dtype=bool,
         fget=lambda self: bool(self.Beam_tracker and self.Beam_tracker.is_alive()),
     )
 
     Tracking_enabled_RW = attribute(
         access=AttrWriteType.READ_WRITE,
-        doc="Whether the tile beam should be updated periodically",
+        doc="Whether the beam should be updated periodically",
         dtype=bool,
         fget=lambda self: self._tracking_enabled_rw,
     )
@@ -218,7 +218,7 @@ class BeamDevice(AsyncDevice):
         # store the new values
         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()
         logger.info("Pointing direction update requested")
 
@@ -234,6 +234,10 @@ class BeamDevice(AsyncDevice):
     # 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):
         super()._init_device()
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
index 8a8ede8e7f9ffcca30b4351a2268ded4b350722f..406046c857acf894c7186d84f4b85721e46823e2 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
@@ -226,9 +226,11 @@ class LOFARDevice(Device):
         fget=lambda self: numpy.int64(self._access_count),
     )
 
-    hardware_powered_R = attribute(
-        dtype=bool,
-        fget=lambda self: self._read_hardware_powered_R(),
+    hardware_powered_fraction_R = attribute(
+        doc="Fraction of hardware that is powered on (0 = nothing, 1 = all).",
+        dtype=numpy.float64,
+        fget=lambda self: self._read_hardware_powered_fraction_R(),
+        fisallowed="is_attribute_access_allowed",
     )
 
     event_thread_running_R = attribute(
@@ -647,11 +649,11 @@ class LOFARDevice(Device):
         # increase the number of accesses
         self._access_count += 1
 
-    def _read_hardware_powered_R(self):
-        """Overloadable function called in read attribute hardware_powered_R"""
+    def _read_hardware_powered_fraction_R(self):
+        """Overloadable function called to ask whether all hardware is powered."""
 
         # If device backs no hardware, assume it's powered
-        return True
+        return 1.0
 
     def properties_changed(self):
         pass
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/recv_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/recv_device.py
index 3551c33cd97c3bd5e8db90c63deecf5d3f0c2dbb..fff0279ebe0598c9c518666215625c68126c3b90 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/recv_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/recv_device.py
@@ -386,6 +386,17 @@ class RECVDevice(OPCUADevice):
     # 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):
         """Power the RCUs."""
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/ccd.py b/tangostationcontrol/tangostationcontrol/devices/ccd.py
index 6eb0d9d6ee95c9c3e06061a5840d3a1723995026..9aecfc11fbfa24a095e7ed8516bdc326b04d2511 100644
--- a/tangostationcontrol/tangostationcontrol/devices/ccd.py
+++ b/tangostationcontrol/tangostationcontrol/devices/ccd.py
@@ -217,9 +217,9 @@ class CCD(OPCUADevice):
         self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout)
         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"""
-        return self.read_attribute("CCD_PWR_on_R")
+        return 1.0 * self.read_attribute("CCD_PWR_on_R")
 
     def _power_hardware_on(self):
         """Forward the clock signal."""
diff --git a/tangostationcontrol/tangostationcontrol/devices/ec.py b/tangostationcontrol/tangostationcontrol/devices/ec.py
index 3bc7354e2cfa77603f22906121d05883c795416a..85893daf0bb4c1d01359f86ee231cacb8b450fbf 100644
--- a/tangostationcontrol/tangostationcontrol/devices/ec.py
+++ b/tangostationcontrol/tangostationcontrol/devices/ec.py
@@ -113,11 +113,11 @@ class EC(OPCUADevice):
     # overloaded functions
     # --------
 
-    def _read_hardware_powered_R(self):
+    def _read_hardware_powered_fraction_R(self):
         # the device and translator are one, so if
         # the translator is reachable, the hardware
         # is powered.
-        return self.read_attribute("connected_R")
+        return 1.0 * self.read_attribute("connected_R")
 
     # --------
     # Commands
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
index 56a716b2d881acbf0ee3c74dcbf27e311463439c..77e54b87e27497ba6d9995c9acd11aa60acfdc12 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
@@ -669,6 +669,10 @@ class Beamlet(OPCUADevice):
     # 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):
         super().configure_for_initialise()
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
index 256b082b895ad7f840992c183297f8ed4dafe758..9a259373d79c60872f526b435ed7b0814832976a 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
@@ -195,6 +195,10 @@ class BST(Statistics):
     # 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):
         self.proxy.write_attribute(
             "FPGA_bst_offload_enable_RW", self.FPGA_bst_offload_enable_RW_default
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py b/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
index cdfc9f2218b322bd312213d00325a0d93a67a949..fb136f35d1cae485bbdbb7d1a1bbf7eaa42368ac 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
@@ -366,6 +366,19 @@ class SDPFirmware(OPCUADevice):
             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):
         """Boot the SDP Firmware user image"""
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
index 5baa9b113419fd1c2c24022c754adc089cdd4698..76f0c0df9ee2d27d5fb744939c4d56fa0ec08351 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
@@ -555,6 +555,17 @@ class SDP(OPCUADevice):
     # 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):
         super().configure_for_initialise()
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
index 63d05a5cb838eaacba01c79118ba62ac93ebacf8..a237a3ac2473bc8f8d11c121937788b091da523f 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
@@ -222,6 +222,10 @@ class SST(Statistics):
     # 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):
         self.proxy.write_attribute(
             "FPGA_sst_offload_enable_RW", self.FPGA_sst_offload_enable_RW_default
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
index 45d7cbe3c510f47f809ce5c874c570296261fc83..49f6407fac17134de03ca180501b21b860cd5bbf 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
@@ -722,6 +722,31 @@ class XST(Statistics):
     # 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):
         self.proxy.write_attribute(
             "FPGA_xst_processing_enable_RW", self.FPGA_xst_processing_enable_RW_default
diff --git a/tangostationcontrol/tangostationcontrol/devices/unb2.py b/tangostationcontrol/tangostationcontrol/devices/unb2.py
index 55d9309721dc9ea957d1c31b4a4884a3073bb627..85d7e4de354acdab7998440a5263382229d3b61d 100644
--- a/tangostationcontrol/tangostationcontrol/devices/unb2.py
+++ b/tangostationcontrol/tangostationcontrol/devices/unb2.py
@@ -427,10 +427,16 @@ class UNB2(OPCUADevice):
     # overloaded functions
     # --------
 
-    def _read_hardware_powered_R(self):
+    def _read_hardware_powered_fraction_R(self):
         """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):
         """Power the Uniboards."""
@@ -438,7 +444,9 @@ class UNB2(OPCUADevice):
         self.UNB2_on()
         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):
         """Disable the Uniboards."""