diff --git a/README.md b/README.md
index 1c047091c54c2a3b81e225bb2b6097ae5488b02f..b3c2deb1c9244ebf6e01cd1e745852ce6fcab415 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,7 @@ Next change the version in the following places:
 
 # Release Notes
 
+* 0.28.1 Bugfixes / rollout fixes
 * 0.28.0 Make `StationManager` device asynchronous
 * 0.27.2 Add new attributes in OPCUA devices
 * 0.27.1 Bugfixes / rollout fixes
diff --git a/docker/grafana/stationcontrol-dashboards.yaml b/docker/grafana/stationcontrol-dashboards.yaml
index 50d300483241f1c5c4b1c992d834bfa4d71014f6..1933efa7f1d3f1c42040b881c76174f6cc9c8e13 100644
--- a/docker/grafana/stationcontrol-dashboards.yaml
+++ b/docker/grafana/stationcontrol-dashboards.yaml
@@ -2,7 +2,7 @@ apiVersion: 1
 
 providers:
   # <string> an unique provider name. Required
-  - name: 'StationControl'
+  - name: 'StationControl (panels)'
     # <int> Org id. Default to 1
     orgId: 1
     # <string> name of the dashboard folder.
@@ -16,7 +16,28 @@ providers:
     # <int> how often Grafana will scan for changed dashboards
     updateIntervalSeconds: 60
     # <bool> allow updating provisioned dashboards from the UI
-    allowUiUpdates: false
+    allowUiUpdates: true
+    options:
+      # <string, required> path to dashboard files on disk. Required when using the 'file' type
+      path: /var/lib/grafana/panels
+      # <bool> use folder names from filesystem to create folders in Grafana
+      foldersFromFilesStructure: true
+  # <string> an unique provider name. Required
+  - name: 'StationControl (dashboards)'
+    # <int> Org id. Default to 1
+    orgId: 1
+    # <string> name of the dashboard folder.
+    folder: ''
+    # <string> folder UID. will be automatically generated if not specified
+    folderUid: ''
+    # <string> provider type. Default to 'file'
+    type: file
+    # <bool> disable dashboard deletion
+    disableDeletion: true
+    # <int> how often Grafana will scan for changed dashboards
+    updateIntervalSeconds: 60
+    # <bool> allow updating provisioned dashboards from the UI
+    allowUiUpdates: true
     options:
       # <string, required> path to dashboard files on disk. Required when using the 'file' type
       path: /var/lib/grafana/dashboards
diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION
index 697f087f376ad7f03d3702f9f0e0987315e73f73..48f7a71df4beb09d86a9e249e41dfff11d606e40 100644
--- a/tangostationcontrol/VERSION
+++ b/tangostationcontrol/VERSION
@@ -1 +1 @@
-0.28.0
+0.28.1
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/power_hierarchy.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/power_hierarchy.py
index f710c2524b01444f27345dd7172671760dc8e732..efebe69bba22712b1d95ac23a400eba6f435ef57 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/power_hierarchy.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/power_hierarchy.py
@@ -31,8 +31,8 @@ class PowerHierarchyDevice(AbstractHierarchyDevice):
     POWER_CHILD_PROPERTY = "Power_Children"
 
     HIBERNATE_TIMEOUT = 60.0
-    STANDBY_TIMEOUT = 60.0
-    ON_TIMEOUT = 60.0
+    STANDBY_TIMEOUT = 300.0
+    ON_TIMEOUT = 300.0
 
     def init(
         self,
diff --git a/tangostationcontrol/tangostationcontrol/devices/calibration.py b/tangostationcontrol/tangostationcontrol/devices/calibration.py
index 7ca47bfc63878ac2911140f23579e42eb1c8c0b8..ff3cb3280b754e624eaf7aa46bb5dee3bfc8c4bf 100644
--- a/tangostationcontrol/tangostationcontrol/devices/calibration.py
+++ b/tangostationcontrol/tangostationcontrol/devices/calibration.py
@@ -199,6 +199,7 @@ class Calibration(LOFARDevice):
 
         Run whenever the following changes:
             sdpfirmware.clock_RW
+            sdpfirmware.FPGA_boot_image_R
             antennafield.RCU_band_select_RW
         """
 
@@ -317,6 +318,17 @@ class Calibration(LOFARDevice):
                     ),
                 )
             )
+            self.event_subscriptions.append(
+                (
+                    prx,
+                    prx.subscribe_event(
+                        "FPGA_boot_image_R",
+                        EventType.CHANGE_EVENT,
+                        self._clock_changed_event,
+                        stateless=True,
+                    ),
+                )
+            )
 
     def configure_for_on(self):
         # Calibrate all antennafields, as we did not receive
diff --git a/tangostationcontrol/tangostationcontrol/devices/ec.py b/tangostationcontrol/tangostationcontrol/devices/ec.py
index 78ce80e022928d6afa61fe8c141ce2265dfd9888..3bc7354e2cfa77603f22906121d05883c795416a 100644
--- a/tangostationcontrol/tangostationcontrol/devices/ec.py
+++ b/tangostationcontrol/tangostationcontrol/devices/ec.py
@@ -24,11 +24,7 @@ __all__ = ["EC"]
 
 
 @device_logging_to_python()
-@device_metrics(
-    exclude=[
-        "*_RW",
-    ]
-)
+@device_metrics()
 class EC(OPCUADevice):
     """EC Device Server for LOFAR2.0"""
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/observation_control.py b/tangostationcontrol/tangostationcontrol/devices/observation_control.py
index ca21bfc15d13e0726eb4e3990e6caed773503055..c57453e690d095d4f6ec521ac479924c319c8658 100644
--- a/tangostationcontrol/tangostationcontrol/devices/observation_control.py
+++ b/tangostationcontrol/tangostationcontrol/devices/observation_control.py
@@ -5,13 +5,12 @@ import logging
 
 import numpy
 from tango import (
-    DevState,
     DebugIt,
     Util,
     DevBoolean,
     DevString,
 )
-from tango.server import Device, command, attribute
+from tango.server import command, attribute
 from tangostationcontrol.observation.observation_controller import ObservationController
 from tangostationcontrol.common.lofar_logging import (
     device_logging_to_python,
@@ -122,8 +121,7 @@ class ObservationControl(LOFARDevice):
     @DebugIt()
     def init_device(self):
         logger.debug("[ObservationControl] init device")
-        Device.init_device(self)
-        self.set_state(DevState.OFF)
+        super().init_device()
 
         # Increase the number of polling threads for this device server.
         # NB: This server hosts both ObservationControl and Observation
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
index dd1e99c061e340219c75f41b464686f07c313b99..5f2fb24a6b3a2a06a3082fbd6c38f17308a5d2ee 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
@@ -224,12 +224,20 @@ class Beamlet(OPCUADevice):
         datatype=numpy.uint8,
         dims=(N_pn,),
     )
-    FPGA_beamlet_output_nof_destinations_RW = AttributeWrapper(
+    _FPGA_beamlet_output_nof_destinations_RW = AttributeWrapper(
+        doc="Number of UDP streams to create. NB: sdp.FPGA_processing_enable_R must be all False when setting this value! Use beamlet_output_nof_destinations_RW instead!",
         comms_annotation=["FPGA_beamlet_output_nof_destinations_RW"],
         datatype=numpy.uint8,
         dims=(N_pn,),
         access=AttrWriteType.READ_WRITE,
     )
+    FPGA_beamlet_output_nof_destinations_RW = attribute(
+        doc="Number of UDP streams to create.",
+        dtype=(numpy.uint8,),
+        max_dim_x=N_pn,
+        access=AttrWriteType.READ_WRITE,
+    )
+
     FPGA_beamlet_output_nof_destinations_act_R = AttributeWrapper(
         comms_annotation=["FPGA_beamlet_output_nof_destinations_act_R"],
         datatype=numpy.uint8,
@@ -668,6 +676,23 @@ class Beamlet(OPCUADevice):
 
         return default_settings
 
+    def read_FPGA_beamlet_output_nof_destinations_RW(self):
+        # report effective number of output destinations
+        return self.read_attribute("FPGA_beamlet_output_nof_destinations_act_R")
+
+    def write_FPGA_beamlet_output_nof_destinations_RW(self, value):
+        old_FPGA_processing_enable = self.sdp_proxy.FPGA_processing_enable_RW
+        try:
+            # need to turn off FPGA processing when setting this value
+            self.sdp_proxy.FPGA_processing_enable_RW = [False] * N_pn
+
+            self.proxy.write_attribute(
+                "_FPGA_beamlet_output_nof_destinations_RW", value
+            )
+        finally:
+            # restore previous setting
+            self.sdp_proxy.FPGA_processing_enable_RW = old_FPGA_processing_enable
+
     def read_subband_select_RW(self):
         # We can only return a single value, so we assume the FPGA is configured coherently.
         # Which is something that is to be checked by an independent monitoring system anyway.
@@ -730,12 +755,6 @@ class Beamlet(OPCUADevice):
             )
         )
 
-    def configure_for_on(self):
-        super().configure_for_on()
-
-        # after everything is configured, FPGA processing can be turned on
-        self.sdp_proxy.FPGA_processing_enable_RW = [True] * N_pn
-
     def configure_for_off(self):
         super().configure_for_off()
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py b/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
index 9df30ad7518a80066b5e3cf5398e9775b573a2b5..f024dab2618a6005ffdd8fd3fc205e8ecf3260a4 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/firmware.py
@@ -37,8 +37,9 @@ __all__ = ["SDPFirmware"]
 @device_logging_to_python()
 @device_metrics(
     exclude=[
-        "FPGA_boot_image_*",
         "FPGA_scrap_*",
+        "FPGA_flash_*",
+        "FPGA_ucp_*",
         "*_RW",
     ],
     include=[
@@ -131,6 +132,8 @@ class SDPFirmware(OPCUADevice):
         datatype=numpy.int32,
         dims=(N_pn,),
         doc="Active FPGA image (0=factory, 1=user)",
+        polling_period=DEFAULT_POLLING_PERIOD,
+        abs_change=1,
     )
     FPGA_boot_image_RW = AttributeWrapper(
         comms_annotation=["FPGA_boot_image_RW"],