diff --git a/devices/test/clients/test_attr_wrapper.py b/devices/test/clients/test_attr_wrapper.py
index ccf4c25f8a6ce4ef075e8b5a72bf9dfc9108da0a..a293923acbf21774e9f221b650353f3410104a88 100644
--- a/devices/test/clients/test_attr_wrapper.py
+++ b/devices/test/clients/test_attr_wrapper.py
@@ -28,572 +28,572 @@ str_image_val = [['1','1'],['1','1'],['1','1']]
 
 
 def dev_init(device):
-	device.set_state(DevState.INIT)
-	device.test_client = test_client(device.Fault, device)
-	for i in device.attr_list():
-		i.set_comm_client(device.test_client)
-	device.test_client.start()
+    device.set_state(DevState.INIT)
+    device.test_client = test_client(device.Fault, device)
+    for i in device.attr_list():
+        i.set_comm_client(device.test_client)
+    device.test_client.start()
 
 
 class TestAttributeTypes(base.TestCase):
 
-	class str_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="str_scalar_R", datatype=str)
-		scalar_RW = attribute_wrapper(comms_annotation="str_scalar_RW", datatype=str, access=AttrWriteType.READ_WRITE)
+    class str_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="str_scalar_R", datatype=str)
+        scalar_RW = attribute_wrapper(comms_annotation="str_scalar_RW", datatype=str, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class bool_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="bool_scalar_R", datatype=numpy.bool_)
-		scalar_RW = attribute_wrapper(comms_annotation="bool_scalar_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE)
+    class bool_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="bool_scalar_R", datatype=numpy.bool_)
+        scalar_RW = attribute_wrapper(comms_annotation="bool_scalar_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float32_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="float32_scalar_R", datatype=numpy.float32)
-		scalar_RW = attribute_wrapper(comms_annotation="float32_scalar_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE)
+    class float32_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="float32_scalar_R", datatype=numpy.float32)
+        scalar_RW = attribute_wrapper(comms_annotation="float32_scalar_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float64_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="float64_scalar_R", datatype=numpy.float64)
-		scalar_RW = attribute_wrapper(comms_annotation="float64_scalar_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE)
+    class float64_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="float64_scalar_R", datatype=numpy.float64)
+        scalar_RW = attribute_wrapper(comms_annotation="float64_scalar_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class double_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="double_scalar_R", datatype=numpy.double)
-		scalar_RW = attribute_wrapper(comms_annotation="double_scalar_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE)
+    class double_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="double_scalar_R", datatype=numpy.double)
+        scalar_RW = attribute_wrapper(comms_annotation="double_scalar_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint8_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="uint8_scalar_R", datatype=numpy.uint8)
-		scalar_RW = attribute_wrapper(comms_annotation="uint8_scalar_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE)
+    class uint8_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="uint8_scalar_R", datatype=numpy.uint8)
+        scalar_RW = attribute_wrapper(comms_annotation="uint8_scalar_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint16_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="uint16_scalar_R", datatype=numpy.uint16)
-		scalar_RW = attribute_wrapper(comms_annotation="uint16_scalar_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE)
+    class uint16_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="uint16_scalar_R", datatype=numpy.uint16)
+        scalar_RW = attribute_wrapper(comms_annotation="uint16_scalar_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint32_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="uint32_scalar_R", datatype=numpy.uint32)
-		scalar_RW = attribute_wrapper(comms_annotation="uint32_scalar_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE)
+    class uint32_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="uint32_scalar_R", datatype=numpy.uint32)
+        scalar_RW = attribute_wrapper(comms_annotation="uint32_scalar_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint64_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="uint64_scalar_R", datatype=numpy.uint64)
-		scalar_RW = attribute_wrapper(comms_annotation="uint64_scalar_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE)
+    class uint64_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="uint64_scalar_R", datatype=numpy.uint64)
+        scalar_RW = attribute_wrapper(comms_annotation="uint64_scalar_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int16_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="int16_scalar_R", datatype=numpy.int16)
-		scalar_RW = attribute_wrapper(comms_annotation="int16_scalar_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE)
+    class int16_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="int16_scalar_R", datatype=numpy.int16)
+        scalar_RW = attribute_wrapper(comms_annotation="int16_scalar_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int32_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="int32_scalar_R", datatype=numpy.int32)
-		scalar_RW = attribute_wrapper(comms_annotation="int32_scalar_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE)
+    class int32_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="int32_scalar_R", datatype=numpy.int32)
+        scalar_RW = attribute_wrapper(comms_annotation="int32_scalar_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int64_scalar_device(hardware_device):
-		scalar_R = attribute_wrapper(comms_annotation="int64_scalar_R", datatype=numpy.int64)
-		scalar_RW = attribute_wrapper(comms_annotation="int64_scalar_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE)
+    class int64_scalar_device(hardware_device):
+        scalar_R = attribute_wrapper(comms_annotation="int64_scalar_R", datatype=numpy.int64)
+        scalar_RW = attribute_wrapper(comms_annotation="int64_scalar_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class str_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="str_spectrum_R", datatype=str, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="str_spectrum_RW", datatype=str, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class str_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="str_spectrum_R", datatype=str, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="str_spectrum_RW", datatype=str, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class bool_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="bool_spectrum_R", datatype=numpy.bool_, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="bool_spectrum_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class bool_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="bool_spectrum_R", datatype=numpy.bool_, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="bool_spectrum_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float32_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="float32_spectrum_R", datatype=numpy.float32, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="float32_spectrum_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class float32_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="float32_spectrum_R", datatype=numpy.float32, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="float32_spectrum_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float64_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="float64_spectrum_R", datatype=numpy.float64, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="float64_spectrum_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class float64_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="float64_spectrum_R", datatype=numpy.float64, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="float64_spectrum_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class double_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="double_spectrum_R", datatype=numpy.double, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="double_spectrum_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class double_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="double_spectrum_R", datatype=numpy.double, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="double_spectrum_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint8_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="uint8_spectrum_R", datatype=numpy.uint8, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="uint8_spectrum_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class uint8_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="uint8_spectrum_R", datatype=numpy.uint8, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="uint8_spectrum_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint16_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="uint16_spectrum_R", datatype=numpy.uint16, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="uint16_spectrum_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class uint16_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="uint16_spectrum_R", datatype=numpy.uint16, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="uint16_spectrum_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint32_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="uint32_spectrum_R", datatype=numpy.uint32, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="uint32_spectrum_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class uint32_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="uint32_spectrum_R", datatype=numpy.uint32, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="uint32_spectrum_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint64_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="uint64_spectrum_R", datatype=numpy.uint64, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="uint64_spectrum_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class uint64_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="uint64_spectrum_R", datatype=numpy.uint64, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="uint64_spectrum_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int16_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="int16_spectrum_R", datatype=numpy.int16, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="int16_spectrum_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class int16_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="int16_spectrum_R", datatype=numpy.int16, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="int16_spectrum_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int32_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="int32_spectrum_R", datatype=numpy.int32, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="int32_spectrum_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class int32_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="int32_spectrum_R", datatype=numpy.int32, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="int32_spectrum_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class int64_spectrum_device(hardware_device):
-		spectrum_R = attribute_wrapper(comms_annotation="int64_spectrum_R", datatype=numpy.int64, dims=spectrum_dims)
-		spectrum_RW = attribute_wrapper(comms_annotation="int64_spectrum_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
+    class int64_spectrum_device(hardware_device):
+        spectrum_R = attribute_wrapper(comms_annotation="int64_spectrum_R", datatype=numpy.int64, dims=spectrum_dims)
+        spectrum_RW = attribute_wrapper(comms_annotation="int64_spectrum_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE, dims=spectrum_dims)
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class str_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="str_image_R", datatype=str, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="str_image_RW", datatype=str, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class str_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="str_image_R", datatype=str, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="str_image_RW", datatype=str, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class bool_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="bool_image_R", datatype=numpy.bool_, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="bool_image_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class bool_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="bool_image_R", datatype=numpy.bool_, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="bool_image_RW", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float32_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="float32_image_R", datatype=numpy.float32, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="float32_image_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class float32_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="float32_image_R", datatype=numpy.float32, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="float32_image_RW", datatype=numpy.float32, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class float64_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="float64_image_R", datatype=numpy.float64, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="float64_image_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class float64_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="float64_image_R", datatype=numpy.float64, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="float64_image_RW", datatype=numpy.float64, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class double_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="double_image_R", datatype=numpy.double, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="double_image_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class double_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="double_image_R", datatype=numpy.double, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="double_image_RW", datatype=numpy.double, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint8_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="uint8_image_R", datatype=numpy.uint8, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="uint8_image_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE, dims=(2,3))
+    class uint8_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="uint8_image_R", datatype=numpy.uint8, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="uint8_image_RW", datatype=numpy.uint8, access=AttrWriteType.READ_WRITE, dims=(2,3))
 
-		def configure_for_initialise(self):
-			dev_init(self)
+        def configure_for_initialise(self):
+            dev_init(self)
 
-	class uint16_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="uint16_image_R", datatype=numpy.uint16, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="uint16_image_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	class uint32_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="uint32_image_R", datatype=numpy.uint32, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="uint32_image_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	class uint64_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="uint64_image_R", datatype=numpy.uint64, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="uint64_image_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	class int16_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="int16_image_R", datatype=numpy.int16, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="int16_image_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	class int32_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="int32_image_R", datatype=numpy.int32, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="int32_image_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	class int64_image_device(hardware_device):
-		image_R = attribute_wrapper(comms_annotation="int64_image_R", datatype=numpy.int64, dims=(2,3))
-		image_RW = attribute_wrapper(comms_annotation="int64_image_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE, dims=(2,3))
-
-		def configure_for_initialise(self):
-			dev_init(self)
-
-	def read_R_test(self, dev, dtype, test_type):
-		'''Test device'''
-		with DeviceTestContext(dev, process=True) as proxy:
-
-			#initialise
-			proxy.initialise()
-			proxy.on()
-
-			if test_type == "scalar":
-				expected = numpy.zeros((1,), dtype=dtype)
-				val = proxy.scalar_RW
-			elif test_type == "spectrum":
-				expected = numpy.zeros(spectrum_dims, dtype=dtype)
-				val = proxy.spectrum_R
-			elif test_type == "image":
-				expected = numpy.zeros(image_dims, dtype=dtype)
-				val = numpy.array(proxy.image_R) #is needed for STR since they act differently
-
-				# cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
-				self.assertEqual(val.shape, expected.shape, " image R array dimensions got mangled. Expected {}, got  {}".format(expected.shape, val.shape))
-				val.reshape(-1)
-			else:
-				self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
-
-			if test_type == "scalar":
-				comparison = expected == val
-				self.assertTrue(comparison, " Value could not be read or was not what was expected. Expected: {}, got {}".format(expected, val))
-			else:
-				comparison = expected == val
-				equal_arrays = comparison.all()
-				self.assertTrue(equal_arrays, " Value could not be read or was not what was expected. Expected: {}, got {}".format(expected, val))
-
-			print(" Test passed! Managed to read R attribute value. got: {}".format(val))
-
-	def write_RW_test(self, dev, dtype, test_type):
-		'''Test device'''
-		with DeviceTestContext(dev, process=True) as proxy:
-
-			#initialise
-			proxy.initialise()
-			proxy.on()
-
-			if test_type == "scalar":
-
-				if dtype is str or dtype is numpy.str_:
-					val = str_scalar_val
-				else:
-					val = dtype(1)
-				proxy.scalar_RW = val
-			elif test_type == "spectrum":
-				if dtype is str or dtype is numpy.str_:
-					val = str_spectrum_val
-				else:
-					val = numpy.full(spectrum_dims, dtype=dtype, fill_value=1)
-				print(val)
-				proxy.spectrum_RW = val
-			elif test_type == "image":
-				if dtype is str or dtype is numpy.str_:
-					val = str_image_val
-				else:
-					val = numpy.full(image_dims, dtype=dtype, fill_value=1)
-				proxy.image_RW = val
-			else:
-				self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
-
-			# can't really test anything here except that the writing didnt cause an error.
-			# reading back happens in readback_test
-
-			print(" Test passed! Managed to write: ".format(val))
-
-	def read_RW_test(self, dev, dtype, test_type):
-		'''Test device'''
-		try:
-			with DeviceTestContext(dev, process=True) as proxy:
-
-				#initialise
-				proxy.initialise()
-				proxy.on()
-
-				if test_type == "scalar":
-					expected = numpy.zeros((1,), dtype=dtype)
-					val = proxy.scalar_RW
-				elif test_type == "spectrum":
-					expected = numpy.zeros(spectrum_dims, dtype=dtype)
-					val = proxy.spectrum_RW
-				elif test_type == "image":
-					expected = numpy.zeros(image_dims, dtype=dtype)
-					val = numpy.array(proxy.image_RW) #is needed for STR since they act differently
-
-					# cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
-					self.assertEqual(val.shape, expected.shape, " image R array dimensions got mangled. Expected {}, got  {}".format(expected.shape, val.shape))
-					val.reshape(-1)
-				else:
-					self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
-
-				if test_type != "scalar":
-					# spectrums and the now flattened images can be compared with .all()
-					comparison = expected == val
-					equal_arrays = comparison.all()
-					self.assertTrue(equal_arrays, " Value could not be handled by the atrribute_wrappers internal RW storer")
-				else:
-					comparison = expected == val
-					self.assertTrue(comparison, " Value could not be handled by the atrribute_wrappers internal RW storer")
-
-				print(" Test passed! Managed to read internal RW value. got: {}".format(val))
-		except Exception as e:
-			info = "Test failure in {} {} read RW test. Expected: {}, got {}".format(test_type, dtype, expected, val)
-			raise Exception(info) from e
-
-	def readback_test(self, dev, dtype, test_type):
-		'''Test device'''
-		try:
-			with DeviceTestContext(dev, process=True) as proxy:
-
-				#initialise
-				proxy.initialise()
-				proxy.on()
-
-				if test_type == "scalar":
-					if dtype is str or dtype is numpy.str_:
-						val = str_scalar_val
-					else:
-						val = dtype(1)
-					proxy.scalar_RW = val
-					result_R = proxy.scalar_R
-					result_RW = proxy.scalar_RW
-				elif test_type == "spectrum":
-					if dtype is str or dtype is numpy.str_:
-						val = str_spectrum_val
-					else:
-						val = numpy.full(spectrum_dims, dtype=dtype, fill_value=1)
-					proxy.spectrum_RW = val
-					result_R = proxy.spectrum_R
-					result_RW = proxy.spectrum_RW
-				elif test_type == "image":
-					if dtype is str or dtype is numpy.str_:
-						val = str_image_val
-					else:
-						val = numpy.full(image_dims, dtype=dtype, fill_value=1)
-
-					# info += " write value: {}".format(val)
-					proxy.image_RW = val
-					result_R = proxy.image_R
-					result_RW = proxy.image_RW
-
-					if dtype != str:
-						self.assertEqual(result_R.shape, image_dims, "not the correct dimensions")
-
-						result_R = result_R.reshape(-1)
-						result_RW = result_RW.reshape(-1)
-						val = val.reshape(-1)
-
-				else:
-					# if the test isn't scalar/spectrum or image its wrong
-					self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
-					
-				if test_type == "scalar":
-					comparison = result_RW == val
-					self.assertTrue(comparison, " Value could not be handled by the atrribute_wrappers internal RW storer. attempted to write: {}".format(val))
-					comparison = result_R == val
-					self.assertTrue(comparison, " value in the clients R attribute not equal to what was written. read: {}, wrote {}".format(result_R, val))
-				elif dtype != str:
-					comparison = result_RW == val
-					equal_arrays = comparison.all()
-					self.assertTrue(equal_arrays, " Value could not be handled by the atrribute_wrappers internal RW storer. attempted to write: {}".format(val))
-					comparison = result_R == val
-					equal_arrays = comparison.all()
-					self.assertTrue(equal_arrays, " value in the clients R attribute not equal to what was written. read: {}, wrote {}".format(result_R, val))
-				else:
-					if test_type == "image":
-						self.assertEqual(len(result_RW)*len(result_RW[0]), 6, "array dimensions do not match the expected dimensions. expected {}, got: {}".format(val, len(result_RW) * len(result_RW[0])))
-						self.assertEqual(len(result_RW) * len(result_RW[0]), 6,"array dimensions do not match the expected dimensions. expected {}, got: {}".format(val, len(result_R) * len([0])))
-					else:
-						self.assertEqual(len(result_RW), 4,"array dimensions do not match the expected dimensions. expected {}, got: {}".format(4, len(result_RW)))
-						self.assertEqual(len(result_R), 4, "array dimensions do not match the expected dimensions. expected {}, got: {}".format(4, len(result_R)))
-
-				print(" Test passed! Managed write and read back a value: {}".format(val))
-
-		except Exception as e:
-			info = "Test failure in {} {} readback test  \n\tW: {} \n\tRW: {} \n\tR: {}".format(test_type, dtype, val, result_RW, result_R)
-			raise Exception(info) from e
-
-
-	"""
-	List of different types to be used with attributes testing, using any other
-	might have unexpected results. Each type is bound to a device scalar,
-	spectrum and image class
-	"""
-	attribute_type_tests = [
-		{
-			'type': str, 'scalar': str_scalar_device,
-			'spectrum': str_spectrum_device, "image": str_image_device
-		},
-		{
-			'type': numpy.bool_, 'scalar': bool_scalar_device,
-			'spectrum': bool_spectrum_device, "image":  bool_image_device
-		},
-		{
-			'type': numpy.float32, 'scalar': float32_scalar_device,
-			'spectrum': float32_spectrum_device, "image": float32_image_device
-		},
-		{
-			'type': numpy.float64, 'scalar': float64_scalar_device,
-			'spectrum': float64_spectrum_device, "image": float64_image_device
-		},
-		{
-			'type': numpy.double, 'scalar': double_scalar_device,
-			'spectrum': double_spectrum_device, "image": double_image_device
-		},
-		{
-			'type': numpy.uint8, 'scalar': uint8_scalar_device,
-			'spectrum': uint8_spectrum_device, "image": uint8_image_device
-		},
-		{
-			'type': numpy.uint16, 'scalar': uint16_scalar_device,
-			'spectrum': uint16_spectrum_device, "image": uint16_image_device
-		},
-		{
-			'type': numpy.uint32, 'scalar': uint32_scalar_device,
-			'spectrum': uint32_spectrum_device, "image": uint32_image_device
-		},
-		{
-			'type': numpy.uint64, 'scalar': uint64_scalar_device,
-			'spectrum': uint64_spectrum_device, "image": uint64_image_device
-		},
-		{
-			'type': numpy.int16, 'scalar': int16_scalar_device,
-			'spectrum': int16_spectrum_device, "image": int16_image_device
-		},
-		{
-			'type': numpy.int32, 'scalar': int32_scalar_device,
-			'spectrum': int32_spectrum_device, "image": int32_image_device
-		},
-		{
-			'type': numpy.int64, 'scalar': int64_scalar_device,
-			'spectrum': int64_spectrum_device, "image": int64_image_device
-		}
-	]
-
-	def test_scalar_R(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_R_test(
-				attribute_type_test['scalar'], attribute_type_test['type'],
-				'scalar')
-
-	def test_scalar_RW(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_RW_test(
-				attribute_type_test['scalar'], attribute_type_test['type'],
-				'scalar')
-
-	def test_scalar_W(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.write_RW_test(
-				attribute_type_test['scalar'], attribute_type_test['type'],
-				'scalar')
-
-	def test_scalar_readback(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.readback_test(
-				attribute_type_test['scalar'], attribute_type_test['type'],
-				'scalar')
-
-	def test_spectrum_R(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_R_test(
-				attribute_type_test['spectrum'], attribute_type_test['type'],
-				'spectrum')
-
-	def test_spectrum_RW(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_RW_test(
-				attribute_type_test['spectrum'], attribute_type_test['type'],
-				'spectrum')
-
-	def test_spectrum_W(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.write_RW_test(
-				attribute_type_test['spectrum'], attribute_type_test['type'],
-				'spectrum')
-
-	def test_spectrum_readback(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.readback_test(
-				attribute_type_test['spectrum'], attribute_type_test['type'],
-				'spectrum')
-
-	def test_image_R(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_R_test(
-				attribute_type_test['image'], attribute_type_test['type'],
-				'image')
-
-	def test_image_RW(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.read_RW_test(
-				attribute_type_test['image'], attribute_type_test['type'],
-				'image')
-
-	def test_image_W(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.write_RW_test(attribute_type_test['image'], attribute_type_test['type'], 'image')
-
-	def test_image_readback(self):
-		for attribute_type_test in self.attribute_type_tests:
-			self.readback_test(
-				attribute_type_test['image'], attribute_type_test['type'],
-				'image')
+    class uint16_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="uint16_image_R", datatype=numpy.uint16, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="uint16_image_RW", datatype=numpy.uint16, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    class uint32_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="uint32_image_R", datatype=numpy.uint32, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="uint32_image_RW", datatype=numpy.uint32, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    class uint64_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="uint64_image_R", datatype=numpy.uint64, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="uint64_image_RW", datatype=numpy.uint64, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    class int16_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="int16_image_R", datatype=numpy.int16, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="int16_image_RW", datatype=numpy.int16, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    class int32_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="int32_image_R", datatype=numpy.int32, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="int32_image_RW", datatype=numpy.int32, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    class int64_image_device(hardware_device):
+        image_R = attribute_wrapper(comms_annotation="int64_image_R", datatype=numpy.int64, dims=(2,3))
+        image_RW = attribute_wrapper(comms_annotation="int64_image_RW", datatype=numpy.int64, access=AttrWriteType.READ_WRITE, dims=(2,3))
+
+        def configure_for_initialise(self):
+            dev_init(self)
+
+    def read_R_test(self, dev, dtype, test_type):
+        '''Test device'''
+        with DeviceTestContext(dev, process=True) as proxy:
+
+            #initialise
+            proxy.initialise()
+            proxy.on()
+
+            if test_type == "scalar":
+                expected = numpy.zeros((1,), dtype=dtype)
+                val = proxy.scalar_RW
+            elif test_type == "spectrum":
+                expected = numpy.zeros(spectrum_dims, dtype=dtype)
+                val = proxy.spectrum_R
+            elif test_type == "image":
+                expected = numpy.zeros(image_dims, dtype=dtype)
+                val = numpy.array(proxy.image_R) #is needed for STR since they act differently
+
+                # cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
+                self.assertEqual(val.shape, expected.shape, " image R array dimensions got mangled. Expected {}, got  {}".format(expected.shape, val.shape))
+                val.reshape(-1)
+            else:
+                self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
+
+            if test_type == "scalar":
+                comparison = expected == val
+                self.assertTrue(comparison, " Value could not be read or was not what was expected. Expected: {}, got {}".format(expected, val))
+            else:
+                comparison = expected == val
+                equal_arrays = comparison.all()
+                self.assertTrue(equal_arrays, " Value could not be read or was not what was expected. Expected: {}, got {}".format(expected, val))
+
+            print(" Test passed! Managed to read R attribute value. got: {}".format(val))
+
+    def write_RW_test(self, dev, dtype, test_type):
+        '''Test device'''
+        with DeviceTestContext(dev, process=True) as proxy:
+
+            #initialise
+            proxy.initialise()
+            proxy.on()
+
+            if test_type == "scalar":
+
+                if dtype is str or dtype is numpy.str_:
+                    val = str_scalar_val
+                else:
+                    val = dtype(1)
+                proxy.scalar_RW = val
+            elif test_type == "spectrum":
+                if dtype is str or dtype is numpy.str_:
+                    val = str_spectrum_val
+                else:
+                    val = numpy.full(spectrum_dims, dtype=dtype, fill_value=1)
+                print(val)
+                proxy.spectrum_RW = val
+            elif test_type == "image":
+                if dtype is str or dtype is numpy.str_:
+                    val = str_image_val
+                else:
+                    val = numpy.full(image_dims, dtype=dtype, fill_value=1)
+                proxy.image_RW = val
+            else:
+                self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
+
+            # can't really test anything here except that the writing didnt cause an error.
+            # reading back happens in readback_test
+
+            print(" Test passed! Managed to write: ".format(val))
+
+    def read_RW_test(self, dev, dtype, test_type):
+        '''Test device'''
+        try:
+            with DeviceTestContext(dev, process=True) as proxy:
+
+                #initialise
+                proxy.initialise()
+                proxy.on()
+
+                if test_type == "scalar":
+                    expected = numpy.zeros((1,), dtype=dtype)
+                    val = proxy.scalar_RW
+                elif test_type == "spectrum":
+                    expected = numpy.zeros(spectrum_dims, dtype=dtype)
+                    val = proxy.spectrum_RW
+                elif test_type == "image":
+                    expected = numpy.zeros(image_dims, dtype=dtype)
+                    val = numpy.array(proxy.image_RW) #is needed for STR since they act differently
+
+                    # cant use all() for 2d arrays so instead compare the dimensions and then flatten to 2d
+                    self.assertEqual(val.shape, expected.shape, " image R array dimensions got mangled. Expected {}, got  {}".format(expected.shape, val.shape))
+                    val.reshape(-1)
+                else:
+                    self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
+
+                if test_type != "scalar":
+                    # spectrums and the now flattened images can be compared with .all()
+                    comparison = expected == val
+                    equal_arrays = comparison.all()
+                    self.assertTrue(equal_arrays, " Value could not be handled by the atrribute_wrappers internal RW storer")
+                else:
+                    comparison = expected == val
+                    self.assertTrue(comparison, " Value could not be handled by the atrribute_wrappers internal RW storer")
+
+                print(" Test passed! Managed to read internal RW value. got: {}".format(val))
+        except Exception as e:
+            info = "Test failure in {} {} read RW test. Expected: {}, got {}".format(test_type, dtype, expected, val)
+            raise Exception(info) from e
+
+    def readback_test(self, dev, dtype, test_type):
+        '''Test device'''
+        try:
+            with DeviceTestContext(dev, process=True) as proxy:
+
+                #initialise
+                proxy.initialise()
+                proxy.on()
+
+                if test_type == "scalar":
+                    if dtype is str or dtype is numpy.str_:
+                        val = str_scalar_val
+                    else:
+                        val = dtype(1)
+                    proxy.scalar_RW = val
+                    result_R = proxy.scalar_R
+                    result_RW = proxy.scalar_RW
+                elif test_type == "spectrum":
+                    if dtype is str or dtype is numpy.str_:
+                        val = str_spectrum_val
+                    else:
+                        val = numpy.full(spectrum_dims, dtype=dtype, fill_value=1)
+                    proxy.spectrum_RW = val
+                    result_R = proxy.spectrum_R
+                    result_RW = proxy.spectrum_RW
+                elif test_type == "image":
+                    if dtype is str or dtype is numpy.str_:
+                        val = str_image_val
+                    else:
+                        val = numpy.full(image_dims, dtype=dtype, fill_value=1)
+
+                    # info += " write value: {}".format(val)
+                    proxy.image_RW = val
+                    result_R = proxy.image_R
+                    result_RW = proxy.image_RW
+
+                    if dtype != str:
+                        self.assertEqual(result_R.shape, image_dims, "not the correct dimensions")
+
+                        result_R = result_R.reshape(-1)
+                        result_RW = result_RW.reshape(-1)
+                        val = val.reshape(-1)
+
+                else:
+                    # if the test isn't scalar/spectrum or image its wrong
+                    self.assertEqual(1,2, " {} is not a valid test_type. please use either scalar, spectrum or image".format(test_type))
+
+                if test_type == "scalar":
+                    comparison = result_RW == val
+                    self.assertTrue(comparison, " Value could not be handled by the atrribute_wrappers internal RW storer. attempted to write: {}".format(val))
+                    comparison = result_R == val
+                    self.assertTrue(comparison, " value in the clients R attribute not equal to what was written. read: {}, wrote {}".format(result_R, val))
+                elif dtype != str:
+                    comparison = result_RW == val
+                    equal_arrays = comparison.all()
+                    self.assertTrue(equal_arrays, " Value could not be handled by the atrribute_wrappers internal RW storer. attempted to write: {}".format(val))
+                    comparison = result_R == val
+                    equal_arrays = comparison.all()
+                    self.assertTrue(equal_arrays, " value in the clients R attribute not equal to what was written. read: {}, wrote {}".format(result_R, val))
+                else:
+                    if test_type == "image":
+                        self.assertEqual(len(result_RW)*len(result_RW[0]), 6, "array dimensions do not match the expected dimensions. expected {}, got: {}".format(val, len(result_RW) * len(result_RW[0])))
+                        self.assertEqual(len(result_RW) * len(result_RW[0]), 6,"array dimensions do not match the expected dimensions. expected {}, got: {}".format(val, len(result_R) * len([0])))
+                    else:
+                        self.assertEqual(len(result_RW), 4,"array dimensions do not match the expected dimensions. expected {}, got: {}".format(4, len(result_RW)))
+                        self.assertEqual(len(result_R), 4, "array dimensions do not match the expected dimensions. expected {}, got: {}".format(4, len(result_R)))
+
+                print(" Test passed! Managed write and read back a value: {}".format(val))
+
+        except Exception as e:
+            info = "Test failure in {} {} readback test  \n\tW: {} \n\tRW: {} \n\tR: {}".format(test_type, dtype, val, result_RW, result_R)
+            raise Exception(info) from e
+
+
+    """
+    List of different types to be used with attributes testing, using any other
+    might have unexpected results. Each type is bound to a device scalar,
+    spectrum and image class
+    """
+    attribute_type_tests = [
+        {
+            'type': str, 'scalar': str_scalar_device,
+            'spectrum': str_spectrum_device, "image": str_image_device
+        },
+        {
+            'type': numpy.bool_, 'scalar': bool_scalar_device,
+            'spectrum': bool_spectrum_device, "image":  bool_image_device
+        },
+        {
+            'type': numpy.float32, 'scalar': float32_scalar_device,
+            'spectrum': float32_spectrum_device, "image": float32_image_device
+        },
+        {
+            'type': numpy.float64, 'scalar': float64_scalar_device,
+            'spectrum': float64_spectrum_device, "image": float64_image_device
+        },
+        {
+            'type': numpy.double, 'scalar': double_scalar_device,
+            'spectrum': double_spectrum_device, "image": double_image_device
+        },
+        {
+            'type': numpy.uint8, 'scalar': uint8_scalar_device,
+            'spectrum': uint8_spectrum_device, "image": uint8_image_device
+        },
+        {
+            'type': numpy.uint16, 'scalar': uint16_scalar_device,
+            'spectrum': uint16_spectrum_device, "image": uint16_image_device
+        },
+        {
+            'type': numpy.uint32, 'scalar': uint32_scalar_device,
+            'spectrum': uint32_spectrum_device, "image": uint32_image_device
+        },
+        {
+            'type': numpy.uint64, 'scalar': uint64_scalar_device,
+            'spectrum': uint64_spectrum_device, "image": uint64_image_device
+        },
+        {
+            'type': numpy.int16, 'scalar': int16_scalar_device,
+            'spectrum': int16_spectrum_device, "image": int16_image_device
+        },
+        {
+            'type': numpy.int32, 'scalar': int32_scalar_device,
+            'spectrum': int32_spectrum_device, "image": int32_image_device
+        },
+        {
+            'type': numpy.int64, 'scalar': int64_scalar_device,
+            'spectrum': int64_spectrum_device, "image": int64_image_device
+        }
+    ]
+
+    def test_scalar_R(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_R_test(
+                attribute_type_test['scalar'], attribute_type_test['type'],
+                'scalar')
+
+    def test_scalar_RW(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_RW_test(
+                attribute_type_test['scalar'], attribute_type_test['type'],
+                'scalar')
+
+    def test_scalar_W(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.write_RW_test(
+                attribute_type_test['scalar'], attribute_type_test['type'],
+                'scalar')
+
+    def test_scalar_readback(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.readback_test(
+                attribute_type_test['scalar'], attribute_type_test['type'],
+                'scalar')
+
+    def test_spectrum_R(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_R_test(
+                attribute_type_test['spectrum'], attribute_type_test['type'],
+                'spectrum')
+
+    def test_spectrum_RW(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_RW_test(
+                attribute_type_test['spectrum'], attribute_type_test['type'],
+                'spectrum')
+
+    def test_spectrum_W(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.write_RW_test(
+                attribute_type_test['spectrum'], attribute_type_test['type'],
+                'spectrum')
+
+    def test_spectrum_readback(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.readback_test(
+                attribute_type_test['spectrum'], attribute_type_test['type'],
+                'spectrum')
+
+    def test_image_R(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_R_test(
+                attribute_type_test['image'], attribute_type_test['type'],
+                'image')
+
+    def test_image_RW(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.read_RW_test(
+                attribute_type_test['image'], attribute_type_test['type'],
+                'image')
+
+    def test_image_W(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.write_RW_test(attribute_type_test['image'], attribute_type_test['type'], 'image')
+
+    def test_image_readback(self):
+        for attribute_type_test in self.attribute_type_tests:
+            self.readback_test(
+                attribute_type_test['image'], attribute_type_test['type'],
+                'image')