From c916468a78909da924f947f6588128db87603781 Mon Sep 17 00:00:00 2001
From: stedif <stefano.difrischia@inaf.it>
Date: Tue, 8 Mar 2022 17:28:41 +0100
Subject: [PATCH] L2SS-652: test jupyter-notebook-demnostrator

---
 .../HdbppReader_demonstrator.ipynb            | 977 +++++++++++++++++-
 .../hdbpp_reader/timescaledb/timescaledb.py   |   1 +
 2 files changed, 936 insertions(+), 42 deletions(-)

diff --git a/jupyter-notebooks/HdbppReader_demonstrator.ipynb b/jupyter-notebooks/HdbppReader_demonstrator.ipynb
index 112929de1..b072495de 100644
--- a/jupyter-notebooks/HdbppReader_demonstrator.ipynb
+++ b/jupyter-notebooks/HdbppReader_demonstrator.ipynb
@@ -19,12 +19,13 @@
    "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": 3,
+   "execution_count": 12,
    "id": "24cd0dbc",
    "metadata": {},
    "outputs": [
@@ -38,7 +39,7 @@
        " 'port': 5432}"
       ]
      },
-     "execution_count": 3,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -49,7 +50,29 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 13,
+   "id": "2e01bf2a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<connection object at 0x7fe83d1b0e08; dsn: 'user=postgres password=xxx dbname=hdb host=archiver-timescale port=5432', closed: 0>"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Check connection\n",
+    "reader.get_connection()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
    "id": "582e2c9e",
    "metadata": {},
    "outputs": [
@@ -57,39 +80,31 @@
      "data": {
       "text/plain": [
        "['tango://databaseds:10000/stat/sdp/1/fpga_temp_r',\n",
-       " 'tango://databaseds:10000/stat/recv/1/recvtr_i2c_error_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/rcu_pwr_good_r',\n",
-       " 'tango://databaseds:10000/stat/recv/1/rcu_mask_rw',\n",
-       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_version_r',\n",
-       " 'tango://databaseds:10000/stat/sdp/1/fpga_firmware_version_r',\n",
-       " 'tango://databaseds:10000/stat/sdp/1/tr_fpga_communication_error_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/tr_fpga_mask_rw',\n",
-       " 'tango://databaseds:10000/stat/sdp/1/fpga_hardware_version_r',\n",
-       " 'tango://databaseds:10000/stat/sdp/1/tr_software_version_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",
@@ -137,70 +152,80 @@
        " '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']"
+       " '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": 11,
+     "execution_count": 14,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
+    "# Get the list of all the archived attributes\n",
     "reader.get_attributes()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 15,
    "id": "9f985ceb",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "['tango://databaseds:10000/stat/recv/1/recvtr_i2c_error_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/rcu_pwr_good_r',\n",
-       " 'tango://databaseds:10000/stat/recv/1/rcu_mask_rw',\n",
-       " 'tango://databaseds:10000/stat/recv/1/rcu_pcb_version_r',\n",
-       " 'tango://databaseds:10000/stat/recv/1/version_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']"
       ]
      },
-     "execution_count": 23,
+     "execution_count": 15,
      "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": 15,
+   "execution_count": 16,
    "id": "5517c508",
    "metadata": {},
    "outputs": [
@@ -210,19 +235,20 @@
        "1"
       ]
      },
-     "execution_count": 15,
+     "execution_count": 16,
      "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": 39,
+   "execution_count": 26,
    "id": "740064f3",
    "metadata": {},
    "outputs": [
@@ -232,43 +258,910 @@
        "{}"
       ]
      },
-     "execution_count": 39,
+     "execution_count": 26,
      "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",
-    "reader.get_last_attributes_values(attributes=a,columns=['value_r'],n=10)"
+    "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": 49,
+   "execution_count": 27,
    "id": "d48fe536",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "[(1, 'att_array_devdouble', 'tango://databaseds:10000/stat/sdp/1/fpga_temp_r')]"
+       "[(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)]"
       ]
      },
-     "execution_count": 49,
+     "execution_count": 27,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "reader._cursor.execute(\"SELECT att_conf_id, table_name, att_name FROM att_conf WHERE att_name LIKE '%tango://databaseds:10000/stat/sdp/1/fpga_temp_r%'\")\n",
+    "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": null,
+   "execution_count": 28,
    "id": "fcab2a21",
    "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(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": 28,
+     "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')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7caeb8a9",
+   "metadata": {},
    "outputs": [],
    "source": []
   }
diff --git a/tangostationcontrol/tangostationcontrol/toolkit/hdbpp_reader/timescaledb/timescaledb.py b/tangostationcontrol/tangostationcontrol/toolkit/hdbpp_reader/timescaledb/timescaledb.py
index e4a8cc3c9..a42b619a0 100755
--- a/tangostationcontrol/tangostationcontrol/toolkit/hdbpp_reader/timescaledb/timescaledb.py
+++ b/tangostationcontrol/tangostationcontrol/toolkit/hdbpp_reader/timescaledb/timescaledb.py
@@ -3,6 +3,7 @@
 import sys, re, traceback
 import os
 import time
+import datetime
 import psycopg2
 from psycopg2 import sql
 
-- 
GitLab