bec-ipython-client 3.35.6__py3-none-any.whl → 3.84.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bec-ipython-client might be problematic. Click here for more details.

.gitignore CHANGED
@@ -9,6 +9,9 @@
9
9
  **/*.egg*
10
10
  **/*.env
11
11
 
12
+ # bec_widgets saved profiles
13
+ widgets_settings/profiles/*
14
+
12
15
  # recovery_config files
13
16
  recovery_config_*
14
17
 
PKG-INFO CHANGED
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_ipython_client
3
- Version: 3.35.6
3
+ Version: 3.84.0
4
4
  Summary: BEC IPython client
5
- Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec/issues
6
- Project-URL: Homepage, https://gitlab.psi.ch/bec/bec
5
+ Project-URL: Bug Tracker, https://github.com/bec-project/bec/issues
6
+ Project-URL: Homepage, https://github.com/bec-project/bec
7
7
  Classifier: Development Status :: 3 - Alpha
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Topic :: Scientific/Engineering
10
- Requires-Python: >=3.10
10
+ Requires-Python: >=3.11
11
11
  Requires-Dist: bec-lib~=3.0
12
12
  Requires-Dist: ipython~=8.22
13
13
  Requires-Dist: numpy<3.0,>=1.24
@@ -32,9 +32,12 @@ except (BECAuthenticationError, KeyboardInterrupt) as exc:
32
32
  except Exception:
33
33
  sys.excepthook(*sys.exc_info())
34
34
  else:
35
- if bec.started and not _main_dict["args"].nogui and BECGuiClient is not None:
35
+ if bec.started and BECGuiClient is not None:
36
36
  gui = bec.gui = BECGuiClient()
37
- gui.start()
37
+ if _main_dict["args"].gui_id:
38
+ gui.connect_to_gui_server(_main_dict["args"].gui_id)
39
+ if not _main_dict["args"].nogui:
40
+ gui.show()
38
41
 
39
42
  _available_plugins = plugin_helper.get_ipython_client_startup_plugins(state="post")
40
43
  if _available_plugins:
@@ -14,11 +14,16 @@ class LiveUpdatesDeviceProgress(LiveUpdatesTable):
14
14
 
15
15
  REPORT_TYPE = "device_progress"
16
16
 
17
- def _run_update(self, device_names: str):
17
+ def core(self):
18
+ """core function to run the live updates for the table"""
19
+ self._wait_for_report_instructions()
20
+ self._run_update(self.report_instruction[self.REPORT_TYPE])
21
+
22
+ def _run_update(self, device_names: list[str]):
18
23
  """Run the update loop for the progress bar.
19
24
 
20
25
  Args:
21
- device_names (str): The name of the device to monitor.
26
+ device_names (list[str]): The name of the device to monitor.
22
27
  """
23
28
  with ScanProgressBar(
24
29
  scan_number=self.scan_item.scan_number, clear_on_exit=False
@@ -29,7 +34,7 @@ class LiveUpdatesDeviceProgress(LiveUpdatesTable):
29
34
  self._print_client_msgs_asap()
30
35
  self._print_client_msgs_all()
31
36
 
32
- def _update_progressbar(self, progressbar: ScanProgressBar, device_names: str) -> bool:
37
+ def _update_progressbar(self, progressbar: ScanProgressBar, device_names: list[str]) -> bool:
33
38
  """Update the progressbar based on the device status message
34
39
 
35
40
  Args:
@@ -41,17 +46,17 @@ class LiveUpdatesDeviceProgress(LiveUpdatesTable):
41
46
  self.check_alarms()
42
47
  status = self.bec.connector.get(MessageEndpoints.device_progress(device_names[0]))
43
48
  if not status:
44
- logger.debug("waiting for new data point")
49
+ logger.trace("waiting for new data point")
45
50
  time.sleep(0.1)
46
51
  return False
47
52
  if status.metadata.get("scan_id") != self.scan_item.scan_id:
48
- logger.debug("waiting for new data point")
53
+ logger.trace("waiting for new data point")
49
54
  time.sleep(0.1)
50
55
  return False
51
56
 
52
57
  point_id = status.content.get("value")
53
58
  if point_id is None:
54
- logger.debug("waiting for new data point")
59
+ logger.trace("waiting for new data point")
55
60
  time.sleep(0.1)
56
61
  return False
57
62
 
@@ -49,7 +49,7 @@ class IPythonLiveUpdates:
49
49
  """
50
50
  scan_type = self._active_request.content["scan_type"]
51
51
  if scan_type in ["open_scan_def", "close_scan_def"]:
52
- self._process_instruction({"scan_progress": 0})
52
+ self._process_instruction({"scan_progress": {"points": 0, "show_table": True}})
53
53
  return
54
54
  if scan_type == "close_scan_group":
55
55
  return
@@ -151,11 +151,14 @@ class IPythonLiveUpdates:
151
151
  scan_request = ScanRequestMixin(self.client, request.metadata["RID"])
152
152
  scan_request.wait()
153
153
 
154
+ # After .wait, we can be sure that the queue item is available, so we can
155
+ assert scan_request.scan_queue_request is not None
156
+
154
157
  # get the corresponding queue item
155
- while not scan_request.request_storage.storage[-1].queue:
158
+ while not scan_request.scan_queue_request.queue:
156
159
  time.sleep(0.01)
157
160
 
158
- self._current_queue = queue = scan_request.request_storage.storage[-1].queue
161
+ self._current_queue = queue = scan_request.scan_queue_request.queue
159
162
  self._request_block_id = req_id = self._active_request.metadata.get("RID")
160
163
 
161
164
  while queue.status not in ["COMPLETED", "ABORTED", "HALTED"]:
@@ -223,6 +226,8 @@ class IPythonLiveUpdates:
223
226
  flush=True,
224
227
  )
225
228
  available_blocks = self._available_req_blocks(queue, request)
229
+ if not available_blocks:
230
+ return False
226
231
  req_block = available_blocks[self._request_block_index[req_id]]
227
232
  if req_block["content"]["scan_type"] in [
228
233
  "open_scan_def",
@@ -2,7 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  import time
4
4
  from collections.abc import Callable
5
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Any, SupportsFloat
6
+
7
+ import numpy as np
6
8
 
7
9
  from bec_ipython_client.prettytable import PrettyTable
8
10
  from bec_ipython_client.progressbar import ScanProgressBar
@@ -66,6 +68,7 @@ class LiveUpdatesTable(LiveUpdatesBase):
66
68
  if print_table_data is not None
67
69
  else self.REPORT_TYPE == "scan_progress"
68
70
  )
71
+ self._devices_with_bad_precision = set()
69
72
 
70
73
  def wait_for_scan_to_start(self):
71
74
  """wait until the scan starts"""
@@ -75,7 +78,7 @@ class LiveUpdatesTable(LiveUpdatesBase):
75
78
  if self.scan_item.status == "closed":
76
79
  break
77
80
  if queue_pos is None:
78
- logger.debug(f"Could not find queue entry for scan_id {self.scan_item.scan_id}")
81
+ logger.trace(f"Could not find queue entry for scan_id {self.scan_item.scan_id}")
79
82
  continue
80
83
  if queue_pos == 0:
81
84
  break
@@ -168,6 +171,13 @@ class LiveUpdatesTable(LiveUpdatesBase):
168
171
 
169
172
  def core(self):
170
173
  """core function to run the live updates for the table"""
174
+ self._wait_for_report_instructions()
175
+ show_table = self.report_instruction[self.REPORT_TYPE].get("show_table", True)
176
+ self._print_table_data = show_table
177
+ self._run_update(self.report_instruction[self.REPORT_TYPE]["points"])
178
+
179
+ def _wait_for_report_instructions(self):
180
+ """wait until the report instructions are available"""
171
181
  req_ID = self.scan_queue_request.requestID
172
182
  while True:
173
183
  request_block = [
@@ -179,8 +189,6 @@ class LiveUpdatesTable(LiveUpdatesBase):
179
189
  break
180
190
  self.check_alarms()
181
191
 
182
- self._run_update(self.report_instruction[self.REPORT_TYPE])
183
-
184
192
  def _run_update(self, target_num_points: int):
185
193
  """run the update loop with the progress bar
186
194
 
@@ -208,7 +216,7 @@ class LiveUpdatesTable(LiveUpdatesBase):
208
216
  self.bec.callbacks.poll()
209
217
  self.scan_item.poll_callbacks()
210
218
  else:
211
- logger.debug("waiting for new data point")
219
+ logger.trace("waiting for new data point")
212
220
  time.sleep(0.1)
213
221
 
214
222
  if not self.scan_item.num_points:
@@ -219,6 +227,24 @@ class LiveUpdatesTable(LiveUpdatesBase):
219
227
  if self.point_id > self.scan_item.num_points:
220
228
  raise RuntimeError("Received more points than expected.")
221
229
 
230
+ if len(self.scan_item.live_data) == 0 and self.scan_item.status == "closed":
231
+ msg = self.scan_item.status_message
232
+ if not msg:
233
+ continue
234
+ if msg.readout_priority.get("monitored", []):
235
+ continue
236
+
237
+ logger.warning(
238
+ f"\n Scan {self.scan_item.scan_number} finished. No monitored devices enabled, please check your config."
239
+ )
240
+ break
241
+
242
+ def _warn_bad_precisions(self):
243
+ if self._devices_with_bad_precision != set():
244
+ for dev, prec in self._devices_with_bad_precision:
245
+ logger.warning(f"Device {dev} reported malformed precision of {prec}!")
246
+ self._devices_with_bad_precision = set()
247
+
222
248
  @property
223
249
  def _print_table_data(self) -> bool:
224
250
  """Checks if the table should be printed or not.
@@ -261,40 +287,41 @@ class LiveUpdatesTable(LiveUpdatesBase):
261
287
 
262
288
  if self.point_id % 100 == 0:
263
289
  print(self.table.get_header_lines())
264
- ind = 0
290
+
291
+ signals_precisions = []
265
292
  for dev in self.devices:
266
293
  if dev in self.bec.device_manager.devices:
267
294
  obj = self.bec.device_manager.devices[dev]
268
295
  for hint in obj._hints:
269
296
  signal = self.point_data.content["data"].get(obj.root.name, {}).get(hint)
270
- if signal is None or signal.get("value") is None:
271
- print_value = "N/A"
297
+ if signal is None:
298
+ signals_precisions.append((None, None))
272
299
  else:
273
- try:
274
- precision = getattr(obj, "precision")
275
- except AttributeError:
276
- precision = 2
277
- value = signal.get("value")
278
- if isinstance(value, (int, float)):
279
- print_value = f"{value:.{precision}f}"
280
- else:
281
- print_value = str(value)
282
- self.dev_values[ind] = print_value
283
- ind += 1
300
+ prec = getattr(obj, "precision", 2)
301
+ if not isinstance(prec, int):
302
+ self._devices_with_bad_precision.add((dev, prec))
303
+ prec = 2
304
+ signals_precisions.append((signal, prec))
284
305
  else:
285
- signal = self.point_data.content["data"].get(dev, {})
286
- value = signal.get("value")
287
- if value is not None:
288
- if isinstance(value, (int, float)):
289
- print_value = f"{value:.2f}"
290
- else:
291
- print_value = str(value)
292
- else:
293
- print_value = "N/A"
294
- self.dev_values[ind] = print_value
295
- ind += 1
306
+ signals_precisions.append((self.point_data.content["data"].get(dev, {}), 2))
307
+
308
+ for i, (signal, precision) in enumerate(signals_precisions):
309
+ self.dev_values[i] = self._format_value(signal, precision)
310
+
296
311
  print(self.table.get_row(str(self.point_id), *self.dev_values))
297
312
 
313
+ def _format_value(self, signal: dict | None, precision: int = 2):
314
+ if signal is None:
315
+ return "N/A"
316
+ val = signal.get("value")
317
+ if isinstance(val, SupportsFloat) and not isinstance(val, np.ndarray):
318
+ if precision < 0:
319
+ # This is to cover the special case when EPICS returns a negative precision.
320
+ # More info: https://epics.anl.gov/tech-talk/2004/msg00434.php
321
+ return f"{float(val):.{-precision}g}"
322
+ return f"{float(val):.{precision}f}"
323
+ return str(val)
324
+
298
325
  def close_table(self):
299
326
  """close the table and print the footer"""
300
327
  if not self.table:
@@ -305,6 +332,7 @@ class LiveUpdatesTable(LiveUpdatesBase):
305
332
  f"Scan {self.scan_item.scan_number} finished. Scan ID {self.scan_item.scan_id}. Elapsed time: {elapsed_time:.2f} s"
306
333
  )
307
334
  )
335
+ self._warn_bad_precisions()
308
336
 
309
337
  def process_request(self):
310
338
  """process the request and start the core loop for live updates"""
@@ -1,31 +1,110 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import threading
3
4
  from collections.abc import Callable
4
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, cast
5
6
 
6
7
  import numpy as np
7
8
 
8
9
  from bec_ipython_client.progressbar import DeviceProgressBar
10
+ from bec_lib import messages
9
11
  from bec_lib.endpoints import MessageEndpoints
12
+ from bec_lib.redis_connector import MessageObject
10
13
 
11
14
  from .utils import LiveUpdatesBase, check_alarms
12
15
 
13
16
  if TYPE_CHECKING:
14
- from bec_lib import messages
15
17
  from bec_lib.client import BECClient
16
18
  from bec_lib.devicemanager import DeviceManagerBase
17
19
 
18
20
 
19
- class ReadbackDataMixin:
20
- def __init__(self, device_manager: DeviceManagerBase, devices: list) -> None:
21
- """Mixin to get the current device values and request-done messages.
21
+ class ReadbackDataHandler:
22
+ """Helper class to get the current device values and request-done messages."""
23
+
24
+ def __init__(
25
+ self, device_manager: DeviceManagerBase, devices: list[str], request_id: str
26
+ ) -> None:
27
+ """Helper class to get the current device values and request-done messages.
22
28
 
23
29
  Args:
24
30
  device_manager (DeviceManagerBase): device manager
25
31
  devices (list): list of devices to monitor
32
+ request_id (str): request ID
26
33
  """
27
34
  self.device_manager = device_manager
28
35
  self.devices = devices
36
+ self.connector = device_manager.connector
37
+ self.request_id = request_id
38
+ self._devices_received = {dev: False for dev in devices}
39
+ self.data: dict[str, messages.DeviceMessage] = {}
40
+ self._devices_done_state: dict[str, tuple[bool, bool]] = {
41
+ dev: (False, False) for dev in devices
42
+ }
43
+ self.requests_done = threading.Event()
44
+ self._register_callbacks()
45
+
46
+ def _register_callbacks(self):
47
+ """register callbacks for device readback messages."""
48
+ for dev in self.devices:
49
+ self.connector.register(
50
+ MessageEndpoints.device_readback(dev), cb=self.on_readback, parent=self, device=dev
51
+ )
52
+ self.connector.register(
53
+ MessageEndpoints.device_req_status(self.request_id),
54
+ cb=self.on_req_status,
55
+ from_start=True,
56
+ parent=self,
57
+ )
58
+
59
+ def _unregister_callbacks(self):
60
+ """unregister callbacks for device readback messages."""
61
+ for dev in self.devices:
62
+ self.connector.unregister(MessageEndpoints.device_readback(dev), cb=self.on_readback)
63
+ self.connector.unregister(
64
+ MessageEndpoints.device_req_status(self.request_id), cb=self.on_req_status
65
+ )
66
+
67
+ @staticmethod
68
+ def on_req_status(
69
+ msg_obj: dict[str, messages.DeviceReqStatusMessage], parent: ReadbackDataHandler
70
+ ):
71
+ """Callback for device request status messages to track which devices are done.
72
+
73
+ Args:
74
+ msg_obj (dict[str, messages.DeviceReqStatusMessage]): message object or device request status message
75
+ parent (ReadbackDataHandler): parent instance
76
+ """
77
+ # pylint: disable=protected-access
78
+ msg = msg_obj["data"]
79
+ if msg.request_id != parent.request_id:
80
+ return
81
+ device = msg.device
82
+ parent._devices_done_state[device] = (True, msg.success)
83
+
84
+ if (
85
+ all(done for done, _ in parent._devices_done_state.values())
86
+ and not parent.requests_done.is_set()
87
+ ):
88
+ parent._on_request_done()
89
+
90
+ @staticmethod
91
+ def on_readback(msg_obj: MessageObject, parent: ReadbackDataHandler, device: str):
92
+ """Callback for updating device readback data.
93
+
94
+ Args:
95
+ msg_obj (MessageObject): message object
96
+ parent (ReadbackDataHandler): parent instance
97
+ device (str): device name
98
+ """
99
+ # pylint: disable=protected-access
100
+ msg: messages.DeviceMessage = cast(messages.DeviceMessage, msg_obj.value)
101
+ parent._devices_received[device] = True
102
+ parent.data[device] = msg
103
+
104
+ def _on_request_done(self):
105
+ """Callback for when all requests are done."""
106
+ self.requests_done.set()
107
+ self._unregister_callbacks()
29
108
 
30
109
  def get_device_values(self) -> list:
31
110
  """get the current device values
@@ -35,57 +114,55 @@ class ReadbackDataMixin:
35
114
  """
36
115
  values = []
37
116
  for dev in self.devices:
38
- val = self.device_manager.devices[dev].read(cached=True)
39
- if not val:
40
- values.append(np.nan)
41
- continue
117
+ val = self.data.get(dev)
118
+ if val is None:
119
+ signal_data = self.device_manager.devices[dev].read(cached=True)
120
+ else:
121
+ signal_data = val.signals
42
122
  # pylint: disable=protected-access
43
123
  hints = self.device_manager.devices[dev]._hints
44
124
  # if we have hints, use them to get the value, otherwise just use the first value
45
125
  if hints:
46
- values.append(val.get(hints[0]).get("value"))
126
+ values.append(signal_data.get(hints[0]).get("value"))
47
127
  else:
48
- values.append(val.get(list(val.keys())[0]).get("value"))
128
+ values.append(signal_data.get(list(signal_data.keys())[0]).get("value"))
49
129
  return values
50
130
 
51
- def get_request_done_msgs(self):
52
- """get all request-done messages"""
53
- pipe = self.device_manager.connector.pipeline()
54
- for dev in self.devices:
55
- self.device_manager.connector.get(MessageEndpoints.device_req_status(dev), pipe)
56
- return self.device_manager.connector.execute_pipeline(pipe)
131
+ def done(self) -> bool:
132
+ """check if all devices are done
57
133
 
58
- def wait_for_RID(self, request: messages.ScanQueueMessage) -> None:
59
- """wait for the readback's metadata to match the request ID
134
+ Returns:
135
+ bool: True if all devices are done, False otherwise
136
+ """
137
+ return self.requests_done.is_set()
60
138
 
61
- Args:
62
- request (messages.ScanQueueMessage): request message
139
+ def device_states(self) -> dict[str, tuple[bool, bool]]:
63
140
  """
64
- while True:
65
- msgs = [
66
- self.device_manager.connector.get(MessageEndpoints.device_readback(dev))
67
- for dev in self.devices
68
- ]
69
- if all(msg.metadata.get("RID") == request.metadata["RID"] for msg in msgs if msg):
70
- break
71
- check_alarms(self.device_manager.parent)
141
+ Return the current device done states.
142
+
143
+ Returns:
144
+ dict: dictionary with device names as keys and tuples of (done, success) as values
145
+ """
146
+ return self._devices_done_state
72
147
 
73
148
 
74
149
  class LiveUpdatesReadbackProgressbar(LiveUpdatesBase):
75
150
  """Live feedback on motor movements using a progressbar.
76
151
 
77
152
  Args:
78
- dm (DeviceManagerBase): device_manager
79
- request (ScanQueueMessage): request that should be monitored
153
+ bec (BECClient): BECClient instance
154
+ report_instruction (list, optional): report instruction for the scan. Defaults to None.
155
+ request (messages.ScanQueueMessage, optional): scan queue request message. Defaults to None.
156
+ callbacks (list[Callable], optional): list of callbacks to register. Defaults to None.
80
157
 
81
158
  """
82
159
 
83
160
  def __init__(
84
161
  self,
85
162
  bec: BECClient,
86
- report_instruction: list = None,
87
- request: messages.ScanQueueMessage = None,
88
- callbacks: list[Callable] = None,
163
+ report_instruction: list | None = None,
164
+ request: messages.ScanQueueMessage | None = None,
165
+ callbacks: list[Callable] | None = None,
89
166
  ) -> None:
90
167
  super().__init__(
91
168
  bec, report_instruction=report_instruction, request=request, callbacks=callbacks
@@ -97,18 +174,20 @@ class LiveUpdatesReadbackProgressbar(LiveUpdatesBase):
97
174
 
98
175
  def core(self):
99
176
  """core function to monitor the device values and update the progressbar accordingly."""
100
- data_source = ReadbackDataMixin(self.bec.device_manager, self.devices)
177
+ request_id = self.request.metadata["RID"]
178
+ if self.report_instruction:
179
+ self.devices = self.report_instruction["readback"]["devices"]
180
+ request_id = self.report_instruction["readback"]["RID"]
181
+ data_source = ReadbackDataHandler(self.bec.device_manager, self.devices, request_id)
101
182
  start_values = data_source.get_device_values()
102
183
  self.wait_for_request_acceptance()
103
- data_source.wait_for_RID(self.request)
184
+
104
185
  if self.report_instruction:
105
- self.devices = self.report_instruction["readback"]["devices"]
106
186
  target_values = self.report_instruction["readback"]["end"]
107
187
 
108
188
  start_instr = self.report_instruction["readback"].get("start")
109
189
  if start_instr:
110
190
  start_values = self.report_instruction["readback"]["start"]
111
- data_source = ReadbackDataMixin(self.bec.device_manager, self.devices)
112
191
  else:
113
192
  target_values = [
114
193
  x for xs in self.request.content["parameter"]["args"].values() for x in xs
@@ -119,33 +198,16 @@ class LiveUpdatesReadbackProgressbar(LiveUpdatesBase):
119
198
  with DeviceProgressBar(
120
199
  self.devices, start_values=start_values, target_values=target_values
121
200
  ) as progress:
122
- req_done = False
123
- while not progress.finished or not req_done:
201
+
202
+ while not progress.finished or not data_source.done():
124
203
  check_alarms(self.bec)
125
204
 
126
205
  values = data_source.get_device_values()
127
206
  progress.update(values=values)
128
207
  self._print_client_msgs_asap()
129
208
 
130
- msgs = data_source.get_request_done_msgs()
131
- request_ids = [
132
- msg.metadata["RID"] if (msg and msg.metadata.get("RID")) else None
133
- for msg in msgs
134
- ]
135
-
136
- if self.report_instruction:
137
- compare_rids = set([self.report_instruction["readback"]["RID"]])
138
- else:
139
- compare_rids = set([self.request.metadata["RID"]])
140
- if set(request_ids) != set(compare_rids):
141
- progress.sleep()
142
- continue
143
-
144
- req_done = True
145
- for dev, msg in zip(self.devices, msgs):
146
- if not msg:
147
- continue
148
- if msg.content.get("success", False):
209
+ for dev, (done, success) in data_source.device_states().items():
210
+ if done and success:
149
211
  progress.set_finished(dev)
150
212
  # pylint: disable=protected-access
151
213
  progress._progress.refresh()
@@ -138,22 +138,22 @@ class ScanRequestMixin:
138
138
  Returns:
139
139
  RequestItem: scan queue request
140
140
  """
141
- logger.debug("Waiting for request ID")
141
+ logger.trace("Waiting for request ID")
142
142
  start = time.time()
143
143
  while self.request_storage.find_request_by_ID(self.RID) is None:
144
144
  time.sleep(0.1)
145
145
  check_alarms(self.bec)
146
- logger.debug(f"Waiting for request ID finished after {time.time()-start} s.")
146
+ logger.trace(f"Waiting for request ID finished after {time.time()-start} s.")
147
147
  return self.request_storage.find_request_by_ID(self.RID)
148
148
 
149
149
  def _wait_for_scan_request_decision(self):
150
150
  """wait for a scan queuest decision"""
151
- logger.debug("Waiting for decision")
151
+ logger.trace("Waiting for decision")
152
152
  start = time.time()
153
153
  while self.scan_queue_request.decision_pending:
154
154
  time.sleep(0.1)
155
155
  check_alarms(self.bec)
156
- logger.debug(f"Waiting for decision finished after {time.time()-start} s.")
156
+ logger.trace(f"Waiting for decision finished after {time.time()-start} s.")
157
157
 
158
158
  def wait(self):
159
159
  """wait for the request acceptance"""