diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4b4dd9211ae01862e9e5afa62f625e409c9ab340..8437f0727d43d009280282235e589254b42d74c0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -97,7 +97,7 @@ docker_build_image_all:
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh unb2-sim latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apsct latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu latest
-    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beam latest
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-tilebeam latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beamlet latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-boot latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-docker latest
@@ -252,17 +252,17 @@ docker_build_image_device_apspu:
   script:
 #    Do not remove 'bash' or statement will be ignored by primitive docker shell
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu $tag
-docker_build_image_device_beam:
+docker_build_image_device_tilebeam:
   extends: .base_docker_images_except
   only:
     refs:
       - merge_requests
     changes:
-      - docker-compose/device-beam.yml
+      - docker-compose/device-tilebeam.yml
       - docker-compose/lofar-device-base/*
   script:
 #    Do not remove 'bash' or statement will be ignored by primitive docker shell
-    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beam $tag
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-tilebeam $tag
 docker_build_image_device_beamlet:
   extends: .base_docker_images_except
   only:
diff --git a/.gitmodules b/.gitmodules
index ef820d4039a54bf590e5c675c97a718b0681dc6e..295ed3b37fc8ff4b3674422af3b799f3041f45ed 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,6 @@
 	path = docker-compose/tango-prometheus-exporter/ska-tango-grafana-exporter
 	url = https://git.astron.nl/lofar2.0/ska-tango-grafana-exporter.git
 	branch = station-control
+[submodule "tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python"]
+	path = tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python
+	url = https://gitlab.com/tango-controls/hdbpp/libhdbpp-python
diff --git a/CDB/LOFAR_ConfigDb.json b/CDB/LOFAR_ConfigDb.json
index 621c845891df2b53856d3b997c1b9b462fb1f41e..a2ed6f1742c94908c4080e8e47b9e8bfad078461 100644
--- a/CDB/LOFAR_ConfigDb.json
+++ b/CDB/LOFAR_ConfigDb.json
@@ -14,10 +14,10 @@
                 }
             }
         },
-        "Beam": {
+        "TileBeam": {
             "STAT": {
-                "Beam": {
-                    "STAT/Beam/1": {}
+                "TileBeam": {
+                    "STAT/TileBeam/1": {}
                 }
             }
         },
diff --git a/README.md b/README.md
index 30562c680b5d739c56b42ab9da8c03aeacecb0a9..09eedaf9a238c8a3407cc0ab2d0d267bc106af54 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,21 @@
 
 Station Control software related to Tango devices.
 
+# Index
+
+* [Docker compose documentation](docker-compose/README.md)
+  * [Timescaledb](docker-compose/timescaledb/README.md)
+  * [Jupyter startup files](docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/README.md)
+  * [Tango Prometheus exporter](https://git.astron.nl/lofar2.0/ska-tango-grafana-exporter)
+* [ReadTheDocs (Sphinx / ReStructuredText) documentation](tangostationcontrol/docs/README.md)
+* Source code documentation
+  * [Attribute wrapper documentation](tangostationcontrol/tangostationcontrol/clients/README.md)
+  * [Archiver documentation](tangostationcontrol/tangostationcontrol/toolkit/README.md)
+  * [Adding a new tango device](tangostationcontrol/tangostationcontrol/devices/README.md)
+  * [HDF5 statistics](tangostationcontrol/tangostationcontrol/statistics_writer/README.md)
+* [Unit tests](tangostationcontrol/tangostationcontrol/test/README.md)
+* [Integration tests](tangostationcontrol/tangostationcontrol/integration_test/README.md)
+
 # Installation
 
 ## Prerequisites
diff --git a/docker-compose/device-beam.yml b/docker-compose/device-tilebeam.yml
similarity index 82%
rename from docker-compose/device-beam.yml
rename to docker-compose/device-tilebeam.yml
index 6a276157f5593fcfe5bd90f1b231ccf0560b37e4..1d243a6e18dc34f43309ec95f0d65e2c34cf2ee2 100644
--- a/docker-compose/device-beam.yml
+++ b/docker-compose/device-tilebeam.yml
@@ -8,8 +8,8 @@ volumes:
   iers-data: {}
 
 services:
-  device-beam:
-    image: device-beam
+  device-tilebeam:
+    image: device-tilebeam
     # build explicitly, as docker-compose does not understand a local image
     # being shared among services.
     build:
@@ -17,7 +17,7 @@ services:
         dockerfile: docker-compose/lofar-device-base/Dockerfile
         args:
             SOURCE_IMAGE: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}-tango-itango:${TANGO_ITANGO_VERSION}
-    container_name: ${CONTAINER_NAME_PREFIX}device-beam
+    container_name: ${CONTAINER_NAME_PREFIX}device-tilebeam
     logging:
       driver: "json-file"
       options:
@@ -39,5 +39,5 @@ services:
       - bin/start-ds.sh
       # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA
       # can't know about our Docker port forwarding
-      - l2ss-beam Beam STAT -v -ORBendPoint giop:tcp:0:5711 -ORBendPointPublish giop:tcp:${HOSTNAME}:5711
+      - l2ss-tilebeam TileBeam STAT -v -ORBendPoint giop:tcp:0:5711 -ORBendPointPublish giop:tcp:${HOSTNAME}:5711
     restart: unless-stopped
diff --git a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
index 39497983356d061978acea77086db0d7b22cb88c..82afee40e570b375aec7339ddfa81013d9b39f61 100644
--- a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
+++ b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
@@ -7,9 +7,9 @@ sst = DeviceProxy("STAT/SST/1")
 xst = DeviceProxy("STAT/XST/1")
 unb2 = DeviceProxy("STAT/UNB2/1")
 boot = DeviceProxy("STAT/Boot/1")
-beam = DeviceProxy("STAT/Beam/1")
+tilebeam = DeviceProxy("STAT/TileBeam/1")
 beamlet = DeviceProxy("STAT/Beamlet/1")
 docker = DeviceProxy("STAT/Docker/1")
 
 # Put them in a list in case one wants to iterate
-devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, beam, beamlet, docker]
+devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, tilebeam, beamlet, docker]
diff --git a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/README b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/README.md
similarity index 100%
rename from docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/README
rename to docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/README.md
diff --git a/docker-compose/tango-prometheus-exporter/README b/docker-compose/tango-prometheus-exporter/README.md
similarity index 100%
rename from docker-compose/tango-prometheus-exporter/README
rename to docker-compose/tango-prometheus-exporter/README.md
diff --git a/jupyter-notebooks/Beamforming_Test.ipynb b/jupyter-notebooks/Beamforming_Test.ipynb
index 0ae1c7631d123aafe85e5bc4c91ffa0c200f8c0f..323982e348f818f54349f6f7b526adc6a793730a 100644
--- a/jupyter-notebooks/Beamforming_Test.ipynb
+++ b/jupyter-notebooks/Beamforming_Test.ipynb
@@ -105,11 +105,11 @@
     }
    ],
    "source": [
-    "# Beam device\n",
-    "b_name = 'STAT/Beam/1'\n",
-    "b = DeviceProxy(b_name)\n",
-    "state = str(b.state())\n",
-    "print(b_name + ' : ' + state)"
+    "# TileBeam device\n",
+    "tb_name = 'STAT/TileBeam/1'\n",
+    "tb = DeviceProxy(tb_name)\n",
+    "state = str(tb.state())\n",
+    "print(tb_name + ' : ' + state)"
    ]
   },
   {
@@ -130,15 +130,15 @@
     "# Start Beam device\n",
     "if state == \"OFF\":\n",
     "    time.sleep(1)\n",
-    "    b.initialise()\n",
+    "    tb.initialise()\n",
     "    time.sleep(1)\n",
-    "state = str(b.state())\n",
+    "state = str(tb.state())\n",
     "if state == \"STANDBY\":\n",
-    "    b.set_defaults()\n",
-    "    b.on()\n",
-    "state = str(b.state())\n",
+    "    tb.set_defaults()\n",
+    "    tb.on()\n",
+    "state = str(tb.state())\n",
     "if state == \"ON\":\n",
-    "    print(f\"Device {b_name} is now in ON state\")"
+    "    print(f\"Device {tb_name} is now in ON state\")"
    ]
   },
   {
@@ -158,9 +158,9 @@
    ],
    "source": [
     "# Test Beam attribute\n",
-    "beam = b\n",
-    "print(96==len(beam.HBAT_pointing_direction_R))\n",
-    "print(96==len(beam.HBAT_pointing_timestamp_R))"
+    "tilebeam = tb\n",
+    "print(96==len(tilebeam.HBAT_pointing_direction_R))\n",
+    "print(96==len(tilebeam.HBAT_pointing_timestamp_R))"
    ]
   },
   {
@@ -182,7 +182,7 @@
    "source": [
     "# Test HBAT delays\n",
     "pointing_direction = numpy.array([[\"J2000\",\"0deg\",\"0deg\"]] * 96).flatten()\n",
-    "delays = b.HBAT_delays(pointing_direction)\n",
+    "delays = tb.HBAT_delays(pointing_direction)\n",
     "print(delays)\n",
     "print(96*16==len(delays))"
    ]
@@ -239,7 +239,7 @@
    "source": [
     "# Test whole main function\n",
     "print(recv.read_attribute('HBAT_BF_delays_RW').value)\n",
-    "beam.HBAT_set_pointing(pointing_direction)\n",
+    "tilebeam.HBAT_set_pointing(pointing_direction)\n",
     "print(recv.read_attribute('HBAT_BF_delays_RW').value)"
    ]
   },
@@ -254,9 +254,9 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "StationControl",
+   "display_name": "Python 3",
    "language": "python",
-   "name": "stationcontrol"
+   "name": "python3"
   },
   "language_info": {
    "codemirror_mode": {
@@ -268,7 +268,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.3"
+   "version": "3.8.10"
   }
  },
  "nbformat": 4,
diff --git a/jupyter-notebooks/HdbppReader_demonstrator.ipynb b/jupyter-notebooks/HdbppReader_demonstrator.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..ea1786979fa6083cc7660176f1ece3da2bba21ad
--- /dev/null
+++ b/jupyter-notebooks/HdbppReader_demonstrator.ipynb
@@ -0,0 +1,1172 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "d0328351",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import sys, time\n",
+    "sys.path.append('/hosthome/tango/tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python')\n",
+    "from hdbpp_reader.timescaledb import TimescaleDbReader"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "c2295969",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Initialise a Reader object\n",
+    "reader = TimescaleDbReader({'database':'hdb', 'user':'postgres', 'password':'password', 'port':5432,'host':'archiver-timescale'})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "24cd0dbc",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'user': 'postgres',\n",
+       " 'password': 'password',\n",
+       " 'host': 'archiver-timescale',\n",
+       " 'database': 'hdb',\n",
+       " 'port': 5432}"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reader.parse_config('postgres:password@archiver-timescale:5432/hdb')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "2e01bf2a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<connection object at 0x7fcf8f18ee08; dsn: 'user=postgres password=xxx dbname=hdb host=archiver-timescale port=5432', closed: 0>"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Check connection\n",
+    "reader.get_connection()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "582e2c9e",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['tango://databaseds:10000/stat/sdp/1/fpga_temp_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/version_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/opcua_missing_attributes_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_green_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_green_on_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_red_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_red_on_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_mask_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_id_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_number_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_version_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_1v8_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_2v5_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_3v3_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_analog_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_digital_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_good_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_temp_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_i2c_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_monitor_rate_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_translator_busy_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_colour_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_iout_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_temp_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_vout_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/state',\n",
+       " 'tango://databaseds:10000/stat/recv/1/status',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/version_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/opcua_missing_attributes_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_enable_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_enable_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_eth_destination_mac_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_eth_destination_mac_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_ip_destination_address_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_ip_destination_address_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_udp_destination_port_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_hdr_udp_destination_port_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_scale_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_beamlet_output_scale_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_boot_image_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_boot_image_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_global_node_index_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_pps_present_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_pps_capture_cnt_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_pps_expected_cnt_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_pps_expected_cnt_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_processing_enable_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_processing_enable_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_scrap_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_scrap_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_antenna_band_index_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_block_period_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_f_adc_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_fsub_type_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_nyquist_sampling_zone_index_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_nyquist_sampling_zone_index_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_observation_id_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_observation_id_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_station_id_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_sdp_info_station_id_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_time_since_last_pps_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_fpga_mask_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_sdp_config_first_fpga_nr_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_sdp_config_nof_beamsets_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_sdp_config_nof_fpgas_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_start_time_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_tod_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_tod_pps_delta_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_bsn_monitor_input_bsn_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_bsn_monitor_input_nof_packets_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_bsn_monitor_input_nof_valid_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_bsn_monitor_input_nof_err_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_error_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_processing_error_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_input_error_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/state',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/status',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_firmware_version_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/fpga_hardware_version_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_fpga_mask_rw',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_fpga_communication_error_r',\n",
+       " 'tango://databaseds:10000/stat/sdp/1/tr_software_version_r']"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Get the list of all the archived attributes\n",
+    "reader.get_attributes()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "9f985ceb",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['tango://databaseds:10000/stat/recv/1/version_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/opcua_missing_attributes_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_green_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_green_on_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_red_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_red_on_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_mask_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_id_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_number_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_version_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_1v8_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_2v5_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_3v3_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_analog_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_digital_on_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_pwr_good_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_temp_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_i2c_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_monitor_rate_rw',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recvtr_translator_busy_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_led_colour_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/rcu_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_iout_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_temp_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/recv_vout_error_r',\n",
+       " 'tango://databaseds:10000/stat/recv/1/state',\n",
+       " 'tango://databaseds:10000/stat/recv/1/status']"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Given a name pattern, return a list of archived attributes\n",
+    "device_name = 'STAT/RECV/1'\n",
+    "reader.get_attributes(pattern=f'*{device_name}*'.lower())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "5517c508",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Check if an attribute is archived\n",
+    "attr_name = 'rcu_mask_rw'\n",
+    "reader.is_attribute_archived(f'{device_name}/{attr_name}'.lower())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "740064f3",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Return the list of the last n value for a given attribute(s)\n",
+    "# ! Cannot figure out why it does not work ... on the other hand, the relative code \n",
+    "# in the next cell works!\n",
+    "a = 'tango://databaseds:10000/stat/sdp/1/fpga_temp_r'\n",
+    "columns = [\"value_r\", \"value_w\", \"quality\", \"att_error_desc_id\"]\n",
+    "reader.get_last_attributes_values(attributes=a,columns=columns,n=3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "d48fe536",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(datetime.datetime(2022, 3, 9, 12, 0, 27, 686930, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  1),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 34, 497576, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 23, 838368, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2)]"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reader._cursor.execute(\"SELECT att_conf_id, table_name, att_name FROM att_conf WHERE att_name LIKE %s;\", ('%'+a+'%',))\n",
+    "att_id = reader._cursor.fetchall()\n",
+    "\n",
+    "reader._cursor.execute(f\"SELECT data_time, value_r, value_w, quality, att_error_desc_id FROM {att_id[0][1]} WHERE att_conf_id={att_id[0][0]} ORDER BY data_time DESC LIMIT 3\")\n",
+    "reader._cursor.fetchall()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "fcab2a21",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(datetime.datetime(2022, 3, 9, 12, 0, 27, 686930, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  1),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 34, 497576, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 23, 838368, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 23, 401983, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 12, 908590, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 12, 398194, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 1, 974671, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 38, 1, 400801, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 51, 57525, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 50, 398277, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 40, 124000, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 39, 402424, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 29, 194141, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 28, 403995, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 18, 325812, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 17, 414731, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 7, 423699, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 37, 6, 406963, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 56, 399116, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 55, 406792, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 45, 491806, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 44, 401894, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 34, 594970, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 33, 385793, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 23, 718610, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 23, 402214, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 12, 785296, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 12, 392858, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 1, 840443, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 36, 1, 404531, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 50, 913943, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 50, 401988, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 39, 984898, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 39, 393043, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 29, 69789, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 28, 409644, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 18, 114191, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 17, 388089, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 7, 192311, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 35, 6, 400084, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 56, 295447, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 55, 390150, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 45, 458677, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 44, 386107, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 34, 598981, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 33, 384623, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 23, 717252, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 22, 394157, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 12, 660277, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 11, 390295, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 1, 641750, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 34, 0, 385438, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 50, 633679, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 49, 396047, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 39, 494091, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 38, 392001, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 27, 532083, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 33, 7, 927971, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  1),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 31, 15, 82880, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 31, 4, 961433, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 31, 4, 405487, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 54, 841743, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 54, 402356, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 44, 727440, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  2),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 44, 400452, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 33, 414200, tzinfo=datetime.timezone.utc),\n",
+       "  [0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0,\n",
+       "   0.0],\n",
+       "  None,\n",
+       "  0,\n",
+       "  None),\n",
+       " (datetime.datetime(2022, 3, 8, 15, 30, 15, 378183, tzinfo=datetime.timezone.utc),\n",
+       "  None,\n",
+       "  None,\n",
+       "  1,\n",
+       "  1)]"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Get the last attribute values given a start date and optionally a stop date\n",
+    "reader.get_attribute_values(a, start_date='2022-03-08 00:00:00')"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "StationControl",
+   "language": "python",
+   "name": "stationcontrol"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/jupyter-notebooks/Tile Beam Steering.ipynb b/jupyter-notebooks/Tile Beam Steering.ipynb
index 8041f6b99ed6431fc5a46044a1bc5d44ee39590d..956b8bb1572a9c17e65cc35fce56b51ced89a496 100644
--- a/jupyter-notebooks/Tile Beam Steering.ipynb	
+++ b/jupyter-notebooks/Tile Beam Steering.ipynb	
@@ -32,7 +32,7 @@
    ],
    "source": [
     "# point all tiles at the horizon at 24°\n",
-    "beam.HBAT_pointing_direction_RW=[(\"AZELGEO\",\"24deg\",\"0deg\")]*96\n",
+    "tilebeam.HBAT_pointing_direction_RW=[(\"AZELGEO\",\"24deg\",\"0deg\")]*96\n",
     "    \n",
     "# wait for pointing to be applied\n",
     "time.sleep(0.5)\n",
@@ -94,7 +94,7 @@
    "source": [
     "for angle, direction in zip(angles, directions):\n",
     "    # set angles\n",
-    "    beam.HBAT_pointing_direction_RW=[(\"AZELGEO\",f\"{angle}deg\",\"0deg\")]*96\n",
+    "    tilebeam.HBAT_pointing_direction_RW=[(\"AZELGEO\",f\"{angle}deg\",\"0deg\")]*96\n",
     "    \n",
     "    # obtain delays\n",
     "    time.sleep(0.5)\n",
@@ -143,7 +143,7 @@
     "\n",
     "for idx, (angle, direction) in enumerate(zip(angles, directions)):\n",
     "    # set angles\n",
-    "    beam.HBAT_pointing_direction_RW=[(\"AZELGEO\",f\"{angle}deg\",\"0deg\")]*96\n",
+    "    tilebeam.HBAT_pointing_direction_RW=[(\"AZELGEO\",f\"{angle}deg\",\"0deg\")]*96\n",
     "    \n",
     "    # obtain delays\n",
     "    time.sleep(0.5)\n",
@@ -172,9 +172,9 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "StationControl",
+   "display_name": "Python 3",
    "language": "python",
-   "name": "stationcontrol"
+   "name": "python3"
   },
   "language_info": {
    "codemirror_mode": {
@@ -186,7 +186,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.3"
+   "version": "3.8.10"
   }
  },
  "nbformat": 4,
diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh
index 17fa54803986d93886138a0bc3a1815a04f330e0..c3351457189b36495fb5f1738098e9b947e41c1b 100755
--- a/sbin/run_integration_test.sh
+++ b/sbin/run_integration_test.sh
@@ -14,13 +14,13 @@ cd "$LOFAR20_DIR/docker-compose" || exit 1
 # Build only the required images, please do not build everything that makes CI
 # take really long to finish, especially grafana / jupyter / prometheus.
 # jupyter is physically large > 2.5gb and overlayfs is really slow.
-make build device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-beam
+make build device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-tilebeam
 make build sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim
 make build databaseds dsconfig elk integration-test
 make build archiver-timescale hdbppts-cm hdbppts-es
 
 # Start and stop sequence
-make stop device-boot device-docker device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-beam sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim hdbppts-es hdbppts-cm archiver-timescale
+make stop device-boot device-docker device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-tilebeam sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim hdbppts-es hdbppts-cm archiver-timescale
 make start databaseds dsconfig elk
 
 # Give dsconfig and databaseds time to start
@@ -38,7 +38,7 @@ make start sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim
 # Give the simulators time to start
 sleep 5
 
-make start device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beam device-beamlet
+make start device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-tilebeam device-beamlet
 # Archive devices -> starting order is important
 make start archiver-timescale hdbppts-cm hdbppts-es
 
diff --git a/tangostationcontrol/README.md b/tangostationcontrol/README.md
deleted file mode 100644
index 0fef1b58aa82065b03353315cdd63ded8e2a3cd2..0000000000000000000000000000000000000000
--- a/tangostationcontrol/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Tango Station Control Device wrappers
-
-This code provides an attribute_wrapper class in place of attributes for tango devices. the attribute wrappers contain additional code 
-that moves a lot of the complexity and redundant code to the background. 
-
-The tango Device class is also abstracted further to a "lofar_device" class. This class wraps 
-
-The only things required on the users part are to declare the attributes using the attribute_wrapper (see `example/example_device`),
-declare what client the attribute has to use in the initialisation and provide support for the used clients. 
-To see how to add support for new clients, see `clients/README.md`
-
-In addition it also provides an abstraction to the tango device, specifically for hardware devices. Examples of hardware devices 
-can be found in TODO and an empty template can be found in `HW_device_template.py`
-
-Requires numpy 
-```pip install numpy```
-
-Requires opcua 
-```pip install opcua```
-
-Requires pytango 
-```pip install pytango```
-
-### usage
-You can start the device by calling it in any console with:
-<Device_name>.py instance_name
diff --git a/tangostationcontrol/docs/source/beam_tracking.rst b/tangostationcontrol/docs/source/beam_tracking.rst
index a689739a5b471fed20655f52a1219bd267892993..a9860420af79ffa6ddc9e348abfb122911a8efc9 100644
--- a/tangostationcontrol/docs/source/beam_tracking.rst
+++ b/tangostationcontrol/docs/source/beam_tracking.rst
@@ -34,7 +34,7 @@ Coordinates in a celestial coordinate system result in a different direction dep
 Positions
 --------------------
 
-The positions of the antennas are required in ITRF, a carthesian geocentric coordinate system ("XYZ" with its origin at the center of the Earth). These coordinates provide an absolute 3D position on Earth and form the basis for most delay computations. These positions are not stationary however, due to the tectonic plate movement. Instead, we use source coordinates in ETRS89 (also carthesian geocentric), and convert those to ITRF using updated and extrapolated tectonic models (see ``tangostationcontrol.beam.geo.ETRS_to_ITRF``).
+The positions of the antennas are required in ITRF, a carthesian geocentric coordinate system ("XYZ" with its origin at the center of the Earth). These coordinates provide an absolute 3D position on Earth and form the basis for most delay computations. These positions are not stationary however, due to the tectonic plate movement. Instead, we use source coordinates in ETRS89 (also carthesian geocentric), and convert those to ITRF using updated and extrapolated tectonic models (see ``tangostationcontrol.tilebeam.geo.ETRS_to_ITRF``).
 
 :recv.HBAT_reference_ETRS: (property) The reference position of each HBA tile, in ETRS89.
 
@@ -65,7 +65,7 @@ The positions of the elements within an HBA tile are handled differently. Instea
 - The R axis is roughly down,
 - The HBA tiles on a station all lie on the same PQ plane, so R == 0.
 
-These facts allow us to use the following information to calculate the absolute position of each tile element. The conversion takes the relative offsets of the elements within a tile, rotates them in PQR space, rotates those into relative ETRS offsets, and finally into absolute positions in ETRS. See ``tangostationcontrol.beam.hba_tile`` for these computations.
+These facts allow us to use the following information to calculate the absolute position of each tile element. The conversion takes the relative offsets of the elements within a tile, rotates them in PQR space, rotates those into relative ETRS offsets, and finally into absolute positions in ETRS. See ``tangostationcontrol.tilebeam.hba_tile`` for these computations.
 
 :recv.HBAT_base_antenna_offsets: (property) The relative offsets of each element within a tile, with respect to the tile's reference position (the center of the ground plane).
 
diff --git a/tangostationcontrol/docs/source/devices/beam.rst b/tangostationcontrol/docs/source/devices/tilebeam.rst
similarity index 86%
rename from tangostationcontrol/docs/source/devices/beam.rst
rename to tangostationcontrol/docs/source/devices/tilebeam.rst
index 8075cde9903c8818d7752a2d8675f9f8e9397a3b..e0c4ce810434da3347b0ec9804937c9d69d9ec66 100644
--- a/tangostationcontrol/docs/source/devices/beam.rst
+++ b/tangostationcontrol/docs/source/devices/tilebeam.rst
@@ -1,7 +1,7 @@
 Beam
 ====================
 
-The ``beam == DeviceProxy("STAT/Beam/1")`` device sets up the beamforming on the station. It configures the HBA tile beam former, which adds the signals of its 16 elements within the tile. These element signals can be delayed a configurable amount of time, allowing their sum to become more sensitive in a certain direction. Each tile can have their own pointing direction configured.
+The ``tilebeam == DeviceProxy("STAT/TileBeam/1")`` device sets up the beamforming on the station. It configures the HBA tile beam former, which adds the signals of its 16 elements within the tile. These element signals can be delayed a configurable amount of time, allowing their sum to become more sensitive in a certain direction. Each tile can have their own pointing direction configured.
 
 Beam Tracking
 --------------------
@@ -81,6 +81,6 @@ We use `python-casacore <https://casacore.github.io/python-casacore/index.html>`
 
   :returns: ``str``
 
-:use_measures(dir): Activate the measures tables in the provided directory. This necessitates turning off and restarting the Beam device, so the command will always appear to fail. Turn the device back and the selected measures tables will be active.
+:use_measures(dir): Activate the measures tables in the provided directory. This necessitates turning off and restarting the TileBeam device, so the command will always appear to fail. Turn the device back and the selected measures tables will be active.
 
   :returns: ``(does not return)``
diff --git a/tangostationcontrol/docs/source/index.rst b/tangostationcontrol/docs/source/index.rst
index f72e468ddd068cf5be6901373ad420919de9500e..0fd199ad8648ca1783d0565cd9f9c336ac4f0ab3 100644
--- a/tangostationcontrol/docs/source/index.rst
+++ b/tangostationcontrol/docs/source/index.rst
@@ -19,7 +19,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st
    installation
    interfaces/overview
    devices/using
-   devices/beam
+   devices/tilebeam
    devices/beamlet
    devices/boot
    devices/docker
diff --git a/tangostationcontrol/requirements.txt b/tangostationcontrol/requirements.txt
index a93c35d3d5a643afaf0d78f53cdd2c36be65f8f2..0cb186f10ceb7b41693b948a4abd81b17c61c053 100644
--- a/tangostationcontrol/requirements.txt
+++ b/tangostationcontrol/requirements.txt
@@ -11,5 +11,5 @@ h5py >= 3.1.0 # BSD
 psutil >= 5.8.0 # BSD
 docker >= 5.0.3 # Apache 2
 python-logstash-async >= 2.3.0 # MIT
-python-casacore >= 3.3.1 # GPL2
+python-casacore >= 3.3.1 # LGPLv3
 etrs-itrs@git+https://github.com/brentjens/etrs-itrs # license pending
diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg
index 44e21e97a1b61338773a49d2fcd3601a2d4f9d8c..cfc0a249b75a93c5fc80b4dc892434f779581e8e 100644
--- a/tangostationcontrol/setup.cfg
+++ b/tangostationcontrol/setup.cfg
@@ -35,7 +35,7 @@ where=./
 console_scripts =
     l2ss-apsct = tangostationcontrol.devices.apsct:main
     l2ss-apspu = tangostationcontrol.devices.apspu:main
-    l2ss-beam = tangostationcontrol.devices.beam:main
+    l2ss-tilebeam = tangostationcontrol.devices.tilebeam:main
     l2ss-beamlet = tangostationcontrol.devices.sdp.beamlet:main
     l2ss-boot = tangostationcontrol.devices.boot:main
     l2ss-docker-device = tangostationcontrol.devices.docker_device:main
diff --git a/tangostationcontrol/tangostationcontrol/clients/README.md b/tangostationcontrol/tangostationcontrol/clients/README.md
index 9d68591c393f1d7da49bbc770101cdabf2cd7ca9..3aa6a653df55601fe776c6acbde1f68c4350afee 100644
--- a/tangostationcontrol/tangostationcontrol/clients/README.md
+++ b/tangostationcontrol/tangostationcontrol/clients/README.md
@@ -1,4 +1,4 @@
-#Attribute wrapper use guide
+# Attribute wrapper use guide
 
 The attribute wrapper is an abstraction layer around tango attributes. This abstraction layer provides an easier and more consistent way of creating and using attributes and allows for easy reuse of code. 
 
@@ -6,7 +6,7 @@ You can find example uses of the attribute wrapper inside the devices folder: ht
 
 Inside lofar/tango/tangostationcontrol/tangostationcontrol/devices/lofar_device.py we import the attribute wrapper. Here we also create a dictionary containing all attribute values in the devices with the setup_value_dict method. This dictionary is set up when the device is initialized. This file, together with the opcua_client.py may be of interest as they are created as generic base classes. 
 
-##Functions/methods
+## Functions/methods
 `__init__`:
 	Comms_id:		user-supplied identifier that is attached to this object, to identify which communication class will need to be attached
 	Comms_annotation:	: data passed along to the attribute. can be given any form of data. handling is up to client implementation
@@ -41,7 +41,7 @@ Wrap an attribute write function to annotate its exceptions with our comms_annot
 
 
 
-##Example Device / usage
+## Example Device / usage
 Here an example of a Tango Device that uses the attribute wrapper is presented. 
 The device class is a sub-class of opcua_device, which is, in turn, a sub-class of lofar_device class which implements the attribute initialisation methods (attr_list and setup_value_dict ) as stated above.
 ```python
@@ -71,7 +71,7 @@ Once the Tango device is up and running, one can interact with the device attrib
 > 
 > d.HBAT_BF_delays_RW = [....]		# write attribute value
 
-##How clients work:
+## How clients work:
 Clients work by providing a communication interface or data accessor for the attribute. The implementation of this is largely up to the user, but must contain a `setup_attribute` function that returns a valid read and write function. 
 
 Once a client has been initialized, the attributes can be assigned their read/write functions. 
@@ -83,16 +83,16 @@ Clients can be set up in the device, during the initialization and then can be a
 
 `tangostationcontrol/tangostationcontrol/clients/comms_client.py` provides a generic client class for us and may be of interest. 
 
-##Dependencies
+## Dependencies
 Attribute wrappers wraps around tango attributes. As such, Tango needs to be installed. 
 The attribute wrapper relies on 1 internal file. tango/tangostationcontrol/devices/device_decorators.py, which is imported by the attribute_wrapper.py. This file is used for ensuring the read/write functions are only called in the correct device state. 
 
 
 
-##Closing
+## Closing
 The advantages of using attribute_wrapper class instead of the standard Tango Attribute class can be noted in the following example where, in the first part, an implementation of the standard class is presented, while in the second part the analogous implementation using an attribute_wrapper is shown.
 
-##From official Tango documentation #
+## From official Tango documentation
 ```python
 class PowerSupply(Device):
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/boot.py b/tangostationcontrol/tangostationcontrol/devices/boot.py
index 3ae76d7f8c3e2254962f794f8159ec307a2c0d17..ba9279092ba0fc3685eb3401b78e630f9ea5cd2a 100644
--- a/tangostationcontrol/tangostationcontrol/devices/boot.py
+++ b/tangostationcontrol/tangostationcontrol/devices/boot.py
@@ -218,7 +218,7 @@ class Boot(lofar_device):
     DeviceProxy_Time_Out = device_property(
         dtype='DevDouble',
         mandatory=False,
-        default_value=10.0,
+        default_value=30.0,
     )
 
     # Initialise the hardware when initialising a station. Can end badly when using simulators.
@@ -241,7 +241,7 @@ class Boot(lofar_device):
                        "STAT/SST/1",
                        "STAT/XST/1",
                        "STAT/Beamlet/1",
-                       "STAT/Beam/1",   # Accesses RECV and Beamlet
+                       "STAT/TileBeam/1",   # Accesses RECV and Beamlet
                       ],
     )
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/lofar_device.py
index 6943f86d4bde44010662cbcea45cb350ca271cea..067f09538d4cb972c0b1a186e726792b69132fbd 100644
--- a/tangostationcontrol/tangostationcontrol/devices/lofar_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/lofar_device.py
@@ -13,7 +13,7 @@
 
 # PyTango imports
 from tango.server import attribute, command, Device, DeviceMeta
-from tango import AttrWriteType, DevState, DebugIt, Attribute, DeviceProxy, AttrDataFormat
+from tango import AttrWriteType, DevState, DebugIt, Attribute, DeviceProxy, AttrDataFormat, DevSource
 import time
 import math
 import numpy
@@ -83,26 +83,6 @@ class lofar_device(Device, metaclass=DeviceMeta):
 
         return self.get_state() in [DevState.STANDBY, DevState.ON, DevState.ALARM]
 
-    def clear_poll_cache(self):
-        """ Remove all attributes from the poll cache, to remove stale entries
-            once we know the values can be read. """
-
-        # we use proxy.attribute_query_list(), as proxy.get_attribute_list() will throw if we
-        # call it too soon when starting everything (database, device) from scratch.
-        attr_names = [config.name for config in self.proxy.attribute_list_query()]
-
-        for attr_name in attr_names:
-            if self.proxy.is_attribute_polled(attr_name):
-                # save poll period
-                poll_period = self.proxy.get_attribute_poll_period(attr_name)
-
-                try:
-                    # stop polling to remove cache entry
-                    self.proxy.stop_poll_attribute(attr_name)
-                finally:
-                    # start polling again
-                    self.proxy.poll_attribute(attr_name, poll_period)
-
     @log_exceptions()
     def init_device(self):
         """ Instantiates the device in the OFF state. """
@@ -123,6 +103,7 @@ class lofar_device(Device, metaclass=DeviceMeta):
         # 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())
+        self.proxy.set_source(DevSource.DEV)
 
     @log_exceptions()
     def delete_device(self):
@@ -163,8 +144,14 @@ class lofar_device(Device, metaclass=DeviceMeta):
 
         self.configure_for_initialise()
 
-        # any values read so far are stale. clear the polling cache.
-        self.clear_poll_cache()
+        # WARNING: any values read so far are stale.
+        # Proxies either need to wait for the next poll round, or
+        # use proxy.set_source(DevSource.DEV) to avoid the cache
+        # alltogether.
+        #
+        # Actually clearing the polling cache runs into performance
+        # problems if a lot of attributes are polled, and into race
+        # conditions with the polling thread itself.
 
         self.set_state(DevState.STANDBY)
         self.set_status("Device is in the STANDBY state.")
diff --git a/tangostationcontrol/tangostationcontrol/devices/recv.py b/tangostationcontrol/tangostationcontrol/devices/recv.py
index 2eb1de134e70586d45eaae65647a0fe0529b5d61..eaf0f189b53ca3f64606d196298f6c9dc27708a1 100644
--- a/tangostationcontrol/tangostationcontrol/devices/recv.py
+++ b/tangostationcontrol/tangostationcontrol/devices/recv.py
@@ -92,7 +92,7 @@ class RECV(opcua_device):
         doc='Maximum amount of time to wait after turning dithering on or off',
         dtype='DevFloat',
         mandatory=False,
-        default_value=10.0
+        default_value=20.0
     )
 
     # ----- Calibration values
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
index c84fe448cf2841af39068cef90b09909bb056650..bedae17dac39d06b39635d2ee9a2fed508fac5f4 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
@@ -194,12 +194,17 @@ class SDP(opcua_device):
     # --------
 
     def _prepare_hardware(self):
+        # FPGA firmware loading disabled, as it causes SDPTR to crash,
+        # see https://support.astron.nl/jira/browse/L2SDP-670
+        """
         # FPGAs need the correct firmware loaded 
         self.FPGA_boot_image_RW = [1] * self.N_pn
 
         # wait for the firmware to be loaded (ignoring masked out elements)
         mask = self.proxy.TR_fpga_mask_RW
         self.wait_attribute("FPGA_boot_image_R", lambda attr: ((attr == 1) | ~mask).all(), 10)
+        """
+        pass
 
     # --------
     # Commands
diff --git a/tangostationcontrol/tangostationcontrol/devices/beam.py b/tangostationcontrol/tangostationcontrol/devices/tilebeam.py
similarity index 99%
rename from tangostationcontrol/tangostationcontrol/devices/beam.py
rename to tangostationcontrol/tangostationcontrol/devices/tilebeam.py
index afcdf78871e321a2489339f747f61351643790b2..948a3657279bf489039bd372b1a096052d3556ec 100644
--- a/tangostationcontrol/tangostationcontrol/devices/beam.py
+++ b/tangostationcontrol/tangostationcontrol/devices/tilebeam.py
@@ -3,7 +3,7 @@
 # Distributed under the terms of the APACHE license.
 # See LICENSE.txt for more info.
 
-""" Beam Device Server for LOFAR2.0
+""" TileBeam Device Server for LOFAR2.0
 
 """
 
@@ -28,10 +28,10 @@ logger = logging.getLogger()
 
 
 
-__all__ = ["Beam", "main", "BeamTracker"]
+__all__ = ["TileBeam", "main", "BeamTracker"]
 
 @device_logging_to_python()
-class Beam(lofar_device):
+class TileBeam(lofar_device):
 
     # -----------------
     # Device Properties
@@ -320,7 +320,7 @@ class Beam(lofar_device):
 # ----------
 def main(**kwargs):
     """Main function of the ObservationControl module."""
-    return entry(Beam, **kwargs)
+    return entry(TileBeam, **kwargs)
 
 # ----------
 # Beam Tracker
diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_beam.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py
similarity index 97%
rename from tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_beam.py
rename to tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py
index 381678118b123793767aff753e4461b7916fe5bd..4948dd7f70a1d1c122dcd3a3c50cda6184bb44d3 100644
--- a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_beam.py
+++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py
@@ -24,12 +24,12 @@ class NumpyEncoder(json.JSONEncoder):
         return json.JSONEncoder.default(self, obj)
 
 
-class TestDeviceBeam(AbstractTestBases.TestDeviceBase):
+class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase):
 
     pointing_direction = numpy.array([["J2000","0deg","0deg"]] * 96).flatten()
 
     def setUp(self):
-        super().setUp("STAT/Beam/1")
+        super().setUp("STAT/TileBeam/1")
     
     def setup_recv_proxy(self):
         # setup RECV
@@ -146,7 +146,7 @@ class TestDeviceBeam(AbstractTestBases.TestDeviceBase):
         numpy.testing.assert_equal(calculated_HBAT_delay_steps[0], expected_HBAT_delay_steps)
         numpy.testing.assert_equal(calculated_HBAT_delay_steps[48], expected_HBAT_delay_steps)
 
-    def test_beam_tracking(self):
+    def test_tilebeam_tracking(self):
         # setup RECV as well
         recv_proxy = self.setup_recv_proxy()
 
diff --git a/tangostationcontrol/tangostationcontrol/test/devices/test_beam_device.py b/tangostationcontrol/tangostationcontrol/test/devices/test_beam_device.py
index 48ce76bf15d0c445b58320d223285153b7d57259..905c5a3b12f43a85562c32f1e509fe5e3a1e7baf 100644
--- a/tangostationcontrol/tangostationcontrol/test/devices/test_beam_device.py
+++ b/tangostationcontrol/tangostationcontrol/test/devices/test_beam_device.py
@@ -9,7 +9,7 @@
 
 from tango.test_context import DeviceTestContext
 
-from tangostationcontrol.devices import beam, lofar_device
+from tangostationcontrol.devices import tilebeam, lofar_device
 
 import mock
 
@@ -22,7 +22,7 @@ class TestBeamDevice(base.TestCase):
 
         # Patch DeviceProxy to allow making the proxies during initialisation
         # that we otherwise avoid using
-        for device in [beam, lofar_device]:
+        for device in [tilebeam, lofar_device]:
             proxy_patcher = mock.patch.object(
                 device, 'DeviceProxy')
             proxy_patcher.start()
@@ -30,14 +30,14 @@ class TestBeamDevice(base.TestCase):
     
     def test_get_pointing_directions(self):
         """Verify can read pointings attribute and length matches without err"""
-        with DeviceTestContext(beam.Beam, process=True, timeout=10) as proxy:
+        with DeviceTestContext(tilebeam.TileBeam, process=True, timeout=10) as proxy:
             proxy.initialise()
             self.assertEqual(96, len(proxy.read_attribute(
                 "HBAT_pointing_direction_R").value))
 
     def test_get_pointing_timestamps(self):
         """Verify can read timestamps attribute and length matches without err"""
-        with DeviceTestContext(beam.Beam, process=True, timeout=10) as proxy:
+        with DeviceTestContext(tilebeam.TileBeam, process=True, timeout=10) as proxy:
             proxy.initialise()
             self.assertEqual(96, len(proxy.read_attribute(
                 "HBAT_pointing_timestamp_R").value))
diff --git a/tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python b/tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python
new file mode 160000
index 0000000000000000000000000000000000000000..7f3168261290109d64057fd526827bf33089774f
--- /dev/null
+++ b/tangostationcontrol/tangostationcontrol/toolkit/libhdbpp-python
@@ -0,0 +1 @@
+Subproject commit 7f3168261290109d64057fd526827bf33089774f
diff --git a/tangostationcontrol/tox.ini b/tangostationcontrol/tox.ini
index 97d91f8b083b7774a2b3a60cf8fa254572fa70f5..0dd2a01453d6e5d8a10cbf155df9408eae3a78d5 100644
--- a/tangostationcontrol/tox.ini
+++ b/tangostationcontrol/tox.ini
@@ -78,4 +78,4 @@ commands =
 [flake8]
 filename = *.py,.stestr.conf,.txt
 select = W292,B601,B602,T100,M001,F401,B001,B002,B003,B004,B005,B006,B007,B008,B009,B010,B011,B012,B013,B014.B015,B016,B017,B018
-exclude=.tox,.egg-info
+exclude=.tox,.egg-info,libhdbpp-python