diff --git a/docker/jupyter-lab/Dockerfile b/docker/jupyter-lab/Dockerfile index 2261ea6307d2e17a17ff8f9fd23e31f921e2a50c..f68c08bbfbd5237f99f1c7b75482c2e1f4559723 100644 --- a/docker/jupyter-lab/Dockerfile +++ b/docker/jupyter-lab/Dockerfile @@ -36,6 +36,8 @@ RUN fix-permissions /home/${NB_USER}/.jupyter/lab USER ${NB_UID} +COPY default-notebooks/* /home/${NB_USER}/ + WORKDIR "${HOME}" # Configure using git from Jupyter Lab. Since the web service is open, we can't know who is diff --git a/docker/jupyter-lab/default-notebooks/Station State Transitions.ipynb b/docker/jupyter-lab/default-notebooks/Station State Transitions.ipynb new file mode 100755 index 0000000000000000000000000000000000000000..9c49c4a7159f1d918c6534e6446a8a94f7c6d725 --- /dev/null +++ b/docker/jupyter-lab/default-notebooks/Station State Transitions.ipynb @@ -0,0 +1,576 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a806252-c92a-4d4f-b74d-b79b0b782cf8", + "metadata": {}, + "source": [ + "# Station State Transitions\n", + "\n", + "The station can be in the following states:\n", + "\n", + "* `OFF`: Everything is powered off. This is also the state the software assumes when powering up (after roll out or LCU reboot),\n", + "* `HIBERNATE`: Connections to translators are on line. System is monitored.\n", + "* `STANDBY`: Critical systems are powered and initialised.\n", + "* `ON`: Everything is powered and initialised. Station is ready for observations.\n", + "\n", + "Valid transitions are: `OFF` -> `HIBERNATE` <-> `STANDBY` <-> `ON`. If the LCU is booted and nothing is known, the following transitions fully reset a station: `OFF` -> `HIBERNATE` -> `STANDBY` -> `HIBERNATE` -> `STANDBY` -> `ON` as that will force powering key hardware off before turning everything on. This ensures that the final `HIBERNATE` -> `STANDBY` -> `ON` starts with a consistent state.\n", + "\n", + "The `stationmanager` device is used to query about the station state and to perform transitions. It exposes the following:\n", + "\n", + "* `stationmanager.station_hibernate()`: Transition to `HIBERNATE`,\n", + "* `stationmanager.station_standby()`: Transition to `STANDBY`,\n", + "* `stationmanager.station_off()`: Transition to `OFF`,\n", + "* `stationmanager.station_state_R.name`: Current/last station state,\n", + "* `stationmanager.station_state_transitioning_R`: Station is currently transitioning between states,\n", + "* `stationmanager.requested_station_state_R`: Requested station state (different from current when transitioning),\n", + "* `stationmanager.last_requested_transition_exceptions_R`: Exceptions thrown by last transition. This is filled when the transition has finished/stopped." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "7e3f8189-862f-40b8-b8ed-80605200880c", + "metadata": {}, + "outputs": [], + "source": [ + "# Enable write access for the whole notebook\n", + "write_access.enable()" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "dc277fdc-0e1f-4e51-92a3-383d1f781be6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Helper functions to track state transitions\n", + "\n", + "import time\n", + "\n", + "def timeit():\n", + " \"\"\"Decorator that prints how long the decorated function took.\"\"\"\n", + " \n", + " def wrapper(func):\n", + " def inner(*args, **kwargs):\n", + " start = time.monotonic()\n", + " \n", + " try:\n", + " return func(*args, **kwargs)\n", + " finally:\n", + " end = time.monotonic()\n", + " print(f\"Time elapsed in {func.__name__}: {end-start:.2f} seconds\")\n", + " \n", + " return inner \n", + " return wrapper\n", + " \n", + "def report_transition_until_done():\n", + " if stationmanager.station_state_transitioning_R:\n", + " print(f\"Transitioning {stationmanager.station_state_r.name} -> {stationmanager.requested_station_state_r.name}\", end=\"\", flush=True)\n", + "\n", + " while stationmanager.station_state_transitioning_R:\n", + " print(\".\", end=\"\",flush=True)\n", + " time.sleep(1)\n", + " \n", + " print()\n", + " \n", + " error_str = ''.join(['\\n * %s' % ex for ex in stationmanager.last_requested_transition_exceptions_R])\n", + " \n", + " if error_str: \n", + " print(f\"In state {stationmanager.station_state_r.name}. Last transition errors: {error_str}\")\n", + " else:\n", + " print(f\"In state {stationmanager.station_state_r.name}. No errors occurred.\")\n", + "\n", + "@timeit()\n", + "def transition(func):\n", + " try:\n", + " # call transition function\n", + " func()\n", + " except DevFailed as ex:\n", + " if ex.args[-1].reason != \"API_DeviceTimedOut\":\n", + " raise\n", + "\n", + " # report until done\n", + " report_transition_until_done()" + ] + }, + { + "cell_type": "markdown", + "id": "cab12787-53e2-4118-bbbf-de5806b3cd92", + "metadata": {}, + "source": [ + "We need to go OFF->HIBERNATE->STANDBY->HIBERNATE->STANDBY->ON:\n", + "\n", + "* Most of the time, the station is actually in \"ON\" but SC rebooted.\n", + "* STANDBY->HIBERNATE is needed to explicitly turn the hardware off, which in turn is required to turn it on consistently." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e157803f-ab26-4a3e-b402-8f5cd251e769", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "In state HIBERNATE. Last transition errors: \n", + " * UNB2(stat/unb2/h0): DevFailed: Failed to execute command_inout on device stat/unb2/h0, command power_hardware_off\n", + "Time elapsed in transition: 0.01 seconds\n" + ] + } + ], + "source": [ + "# Transition to HIBERNATE\n", + "transition(stationmanager.station_hibernate)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "ef3c86a6-da73-40e1-bdf1-04c0dc2080ad", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transitioning ON -> STANDBY.........................\n", + "In state STANDBY. No errors occurred.\n", + "Time elapsed in transition: 85.21 seconds\n" + ] + } + ], + "source": [ + "# Transition to STANDBY\n", + "transition(stationmanager.station_standby)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "31448896-16cc-44b2-84aa-f8a4faee75e2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "In state HIBERNATE. No errors occurred.\n", + "Time elapsed in transition: 16.19 seconds\n" + ] + } + ], + "source": [ + "# Transition to HIBERNATE\n", + "transition(stationmanager.station_hibernate)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "672cba78-159b-4d74-8917-ae8ad2ad04a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transitioning ON -> STANDBY......................................................\n", + "In state STANDBY. No errors occurred.\n", + "Time elapsed in transition: 114.23 seconds\n" + ] + } + ], + "source": [ + "# Transition to STANDBY\n", + "transition(stationmanager.station_standby)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "7fd714c3-c0c2-4452-a298-8068538c2ad2", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transitioning STANDBY -> ON..................................................................................................\n", + "In state ON. Last transition errors: \n", + " * EC(stat/ec/1): DevFailed: Failed to execute command_inout on device stat/ec/1, command initialise\n", + "Time elapsed in transition: 158.39 seconds\n" + ] + } + ], + "source": [ + "# Transition to ON\n", + "transition(stationmanager.station_on)" + ] + }, + { + "cell_type": "markdown", + "id": "745c3ec8-17fa-46e6-95aa-b62d2b7a629c", + "metadata": {}, + "source": [ + "# Station Verification\n", + "\n", + "The cells below verify various aspects of a working station." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "3c3b9418-4230-4433-9e8a-d40168d0ecc9", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<station_state_R.ON: 3>" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Read the current station state, should be ON\n", + "\n", + "stationmanager.station_state_r" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "6c736f5c-f7d7-416d-b39e-8a5c6d394ce8", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "('EC(stat/ec/1): DevFailed: Failed to execute command_inout on device stat/ec/1, command initialise',)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check for errors. Acceptable are:\n", + "# EC(stat/ec/1): DevFailed: Failed to execute command_inout on device stat/ec/1, command initialise\n", + "\n", + "stationmanager.last_requested_transition_exceptions_R" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "418f187d-3cdf-4363-8c43-46cce110e8d0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BST(stat/bst/lba): 1933\n", + "BST(stat/bst/hba0): 1929\n", + "BST(stat/bst/hba1): 1925\n", + "SST(stat/sst/lba): 371136\n", + "SST(stat/sst/hba0): 92592\n", + "SST(stat/sst/hba1): 92352\n", + "XST(stat/xst/lba): 277776\n", + "XST(stat/xst/hba0): 23100\n", + "XST(stat/xst/hba1): 23040\n" + ] + } + ], + "source": [ + "# Check if statistics arrive. All these counters should be non-zero\n", + "\n", + "for b in [bst_l, bst_h0, bst_h1, bst_h, sst_l, sst_h0, sst_h1, sst_h, xst_l, xst_h0, xst_h1, xst_h]:\n", + " if b is not None:\n", + " print(f\"{b}: {b.nof_packets_received_r}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "79554a1e-9770-4d26-804e-9a53d2554631", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DigitalBeam(stat/digitalbeam/hba0): True\n", + "DigitalBeam(stat/digitalbeam/hba1): True\n", + "DigitalBeam(stat/digitalbeam/lba): True\n", + "TileBeam(stat/tilebeam/hba0): True\n", + "TileBeam(stat/tilebeam/hba1): True\n" + ] + } + ], + "source": [ + "# Check if tracking works. All these should report True\n", + "\n", + "for d in [digitalbeam_h0, digitalbeam_h1, digitalbeam_h, digitalbeam_l, tilebeam_h0, tilebeam_h1, tilebeam_h]:\n", + " if d is not None:\n", + " print(f\"{d}: {d.tracking_enabled_r}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "69078849-7ecf-4f4f-83d4-0c052e3052dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "http://prometheus.service.consul:9090/api/v1/query_range?query=scrape_samples_scraped&start=2024-07-12T08:13:56Z&end=2024-07-12T08:18:56Z&step=60 => <Response [200]>\n", + "{'chrony-exporter': '99',\n", + " 'consul.service.consul:8500': '930',\n", + " 'device-afh': '6314',\n", + " 'device-afl': '2791',\n", + " 'device-aps': '177',\n", + " 'device-apsct': '264',\n", + " 'device-apspu': '294',\n", + " 'device-beamlet': '2160',\n", + " 'device-bst': '567',\n", + " 'device-calibration': '89',\n", + " 'device-ccd': '102',\n", + " 'device-configuration': '71',\n", + " 'device-digitalbeam': '5031',\n", + " 'device-ec': '36',\n", + " 'device-metadata': '82',\n", + " 'device-observationcontrol': '3262',\n", + " 'device-pcon': '68',\n", + " 'device-psoc': '68',\n", + " 'device-recvh': '5215',\n", + " 'device-recvl': '3784',\n", + " 'device-sdp': '3696',\n", + " 'device-sdpfirmware': '1287',\n", + " 'device-sst': '615',\n", + " 'device-stationmanager': '85',\n", + " 'device-temperaturemanager': '72',\n", + " 'device-tilebeam': '380',\n", + " 'device-unb2': '1335',\n", + " 'device-xst': '1260',\n", + " 'grafana': '2746',\n", + " 'jupyter': '955',\n", + " 'lcu-ipmi': '121',\n", + " 'loki': '1576',\n", + " 'node-exporter': '4775',\n", + " 'nomad': '2008',\n", + " 'pcon0-snmp': '95',\n", + " 'pcon1-snmp': '95',\n", + " 'prometheus': '936',\n", + " 'rpc-metrics': '20',\n", + " 's3-metrics': '785',\n", + " 'snmp-exporter': '544',\n", + " 'sync-iers': '48',\n", + " 'white-rabbit-snmp': '2948'}\n" + ] + } + ], + "source": [ + "# Verify that Prometheus is working, and everything is scraped. Result should all be >0\n", + "\n", + "from http import HTTPStatus\n", + "import urllib\n", + "import requests\n", + "import json\n", + "import datetime\n", + "\n", + "# construct query\n", + "end = datetime.datetime.now()\n", + "start = end - datetime.timedelta(minutes=5)\n", + "\n", + "query=urllib.parse.quote(\"scrape_samples_scraped\")\n", + "url=f\"http://prometheus.service.consul:9090/api/v1/query_range?query={query}&start={start.strftime('%Y-%m-%dT%H:%M:%SZ')}&end={end.strftime('%Y-%m-%dT%H:%M:%SZ')}&step=60\"\n", + "http_result=requests.get(url)\n", + "\n", + "# report what we fetched\n", + "print(url,\"=>\",http_result)\n", + "\n", + "# parse results\n", + "result = json.loads(http_result.text)\n", + "scrape_samples_scraped = {row['metric']['instance']: row['values'][0][1] for row in result['data']['result']}\n", + "\n", + "from pprint import pprint\n", + "pprint(scrape_samples_scraped)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e9dbafe8-8ccd-412a-a260-daab86f7746c", + "metadata": {}, + "outputs": [], + "source": [ + "# Start an observation on LBA (which is available on all stations)\n", + "\n", + "start = datetime.datetime.now()\n", + "stop = start + datetime.timedelta(minutes=5)\n", + "\n", + "field_spec = {\n", + " \"observation_id\": 1234567,\n", + " \"start_time\": start.isoformat(),\n", + " \"stop_time\": stop.isoformat(),\n", + " \"antenna_set\": \"ALL\",\n", + " \"station\": stationmanager.station_name_r,\n", + " \"antenna_field\": \"LBA\",\n", + " \"filter\": \"LBA_30_90\",\n", + " \"SAPs\": [{\n", + " \"subbands\": [10, 20, 30],\n", + " \"pointing\": { \"angle1\": 1.5, \"angle2\": 0, \"direction_type\": \"J2000\" }\n", + " },{\n", + " \"subbands\": [10, 20, 30],\n", + " \"pointing\": { \"angle1\": 0, \"angle2\": 1.0, \"direction_type\": \"J2000\" }\n", + " }]\n", + "}\n", + "\n", + "observation_spec = {\n", + " \"station\": stationmanager.station_name_r,\n", + " \"antenna_fields\": [field_spec]\n", + "}\n", + "\n", + "import json\n", + "\n", + "with write_access:\n", + " observationcontrol.add_observation(json.dumps(observation_spec))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a569240-bae7-4eda-9b20-a60daa85a719", + "metadata": {}, + "outputs": [], + "source": [ + "# Verify that the observation is running. This should now return True\n", + "1234567 in observationcontrol.running_observations_r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4946f754-0023-4007-9a65-2a1771a66324", + "metadata": {}, + "outputs": [], + "source": [ + "# Verify whether the station was actually configured for the observation\n", + "\n", + "# Should all be ('J2000', '1.5rad', '0rad')\n", + "print(digitalbeam_l.pointing_direction_r[0:3])\n", + "\n", + "# Should all be ('J2000', '0rad', '1.0rad')\n", + "print(digitalbeam_l.pointing_direction_r[3:6])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a69e1500-5b51-4c0a-8fca-b63289f3e2eb", + "metadata": {}, + "outputs": [], + "source": [ + "# Stop observation\n", + "with write_access:\n", + " observationcontrol.stop_all_observations_now()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13ccea03-9d70-414f-aaac-a5223788d95c", + "metadata": {}, + "outputs": [], + "source": [ + "# Are they all stopped? This should return []\n", + "observationcontrol.running_observations_r" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "ec67aa9d-af41-45f3-a44f-dd4f1a4e24b5", + "metadata": {}, + "outputs": [ + { + "ename": "DevFailed", + "evalue": "DevFailed[\nDevError[\n desc = It is currently not allowed to read attribute UNB2TR_monitor_rate_RW\n origin = void Tango::Device_3Impl::read_attributes_no_except(const Tango::DevVarStringArray&, Tango::AttributeIdlData&, bool, std::vector<long int>&) at (/src/cppTango/src/server/device_3.cpp:522)\n reason = API_AttrNotAllowed\nseverity = ERR]\n\nDevError[\n desc = Failed to read_attribute on device stat/unb2/l0, attribute unb2tr_monitor_rate_rw\n origin = virtual Tango::DeviceAttribute Tango::DeviceProxy::read_attribute(const string&) at (/src/cppTango/src/client/devapi_base.cpp:5581)\n reason = API_AttributeFailed\nseverity = ERR]\n]", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDevFailed\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[32], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43munb2_l0\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43munb2tr_monitor_rate_rw\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/device_proxy.py:462\u001b[0m, in \u001b[0;36m__DeviceProxy__getattr\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m 460\u001b[0m attr_info \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__get_attr_cache()\u001b[38;5;241m.\u001b[39mget(name_l)\n\u001b[1;32m 461\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m attr_info:\n\u001b[0;32m--> 462\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m__get_attribute_value\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattr_info\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 464\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name_l \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__get_pipe_cache():\n\u001b[1;32m 465\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_pipe(name)\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/device_proxy.py:402\u001b[0m, in \u001b[0;36m__get_attribute_value\u001b[0;34m(self, attr_info, name)\u001b[0m\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m __async_get_attribute_value(\u001b[38;5;28mself\u001b[39m, attr_info, name)\n\u001b[1;32m 401\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 402\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m__sync_get_attribute_value\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattr_info\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/device_proxy.py:394\u001b[0m, in \u001b[0;36m__sync_get_attribute_value\u001b[0;34m(self, attr_info, name)\u001b[0m\n\u001b[1;32m 393\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__sync_get_attribute_value\u001b[39m(\u001b[38;5;28mself\u001b[39m, attr_info, name):\n\u001b[0;32m--> 394\u001b[0m attr_value \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_attribute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mvalue\n\u001b[1;32m 395\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m __update_enum_values(attr_info, attr_value)\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/green.py:234\u001b[0m, in \u001b[0;36mgreen.<locals>.decorator.<locals>.greener\u001b[0;34m(obj, *args, **kwargs)\u001b[0m\n\u001b[1;32m 232\u001b[0m green_mode \u001b[38;5;241m=\u001b[39m access(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgreen_mode\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m 233\u001b[0m executor \u001b[38;5;241m=\u001b[39m get_object_executor(obj, green_mode)\n\u001b[0;32m--> 234\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mexecutor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwait\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/green.py:124\u001b[0m, in \u001b[0;36mAbstractExecutor.run\u001b[0;34m(self, fn, args, kwargs, wait, timeout)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[38;5;66;03m# Synchronous (no delegation)\u001b[39;00m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39masynchronous \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39min_executor_context():\n\u001b[0;32m--> 124\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 125\u001b[0m \u001b[38;5;66;03m# Asynchronous delegation\u001b[39;00m\n\u001b[1;32m 126\u001b[0m accessor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdelegate(fn, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/device_proxy.py:594\u001b[0m, in \u001b[0;36m__DeviceProxy__read_attribute\u001b[0;34m(self, value, extract_as)\u001b[0m\n\u001b[1;32m 593\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__DeviceProxy__read_attribute\u001b[39m(\u001b[38;5;28mself\u001b[39m, value, extract_as\u001b[38;5;241m=\u001b[39mExtractAs\u001b[38;5;241m.\u001b[39mNumpy):\n\u001b[0;32m--> 594\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m__check_read_attribute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_read_attribute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextract_as\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/conda/lib/python3.11/site-packages/tango/device_proxy.py:162\u001b[0m, in \u001b[0;36m__check_read_attribute\u001b[0;34m(dev_attr)\u001b[0m\n\u001b[1;32m 160\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__check_read_attribute\u001b[39m(dev_attr):\n\u001b[1;32m 161\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dev_attr\u001b[38;5;241m.\u001b[39mhas_failed:\n\u001b[0;32m--> 162\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m DevFailed(\u001b[38;5;241m*\u001b[39mdev_attr\u001b[38;5;241m.\u001b[39mget_err_stack())\n\u001b[1;32m 163\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m dev_attr\n", + "\u001b[0;31mDevFailed\u001b[0m: DevFailed[\nDevError[\n desc = It is currently not allowed to read attribute UNB2TR_monitor_rate_RW\n origin = void Tango::Device_3Impl::read_attributes_no_except(const Tango::DevVarStringArray&, Tango::AttributeIdlData&, bool, std::vector<long int>&) at (/src/cppTango/src/server/device_3.cpp:522)\n reason = API_AttrNotAllowed\nseverity = ERR]\n\nDevError[\n desc = Failed to read_attribute on device stat/unb2/l0, attribute unb2tr_monitor_rate_rw\n origin = virtual Tango::DeviceAttribute Tango::DeviceProxy::read_attribute(const string&) at (/src/cppTango/src/client/devapi_base.cpp:5581)\n reason = API_AttributeFailed\nseverity = ERR]\n]" + ] + } + ], + "source": [ + "unb2_l0.unb2tr_monitor_rate_rw" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8649c3f9-2a46-45ae-827b-2c7998a9a090", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}