From 8018e769c04bac94dca1d46ba9c097785851a41d Mon Sep 17 00:00:00 2001 From: appleb_m Date: Mon, 4 May 2026 17:01:56 +0200 Subject: [PATCH] DAQ: visualisation of tell state added to GUI, now updates BUSY label with current Tell action, when possible. THisd only overlays sample camera at the moment.Can also be seen on status abr, beamlien state panel adn beamlien recovery panel --- .../gui/panels/beamline_recovery_panel.py | 11 ++++- src/aare/gui/panels/beamline_state_panel.py | 46 +++++++++++++++++++ src/aare/gui/widgets/camera_image.py | 17 ++++++- src/aare/gui/widgets/status_bar.py | 18 ++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/aare/gui/panels/beamline_recovery_panel.py b/src/aare/gui/panels/beamline_recovery_panel.py index 4891e9e0..3ce97a5d 100644 --- a/src/aare/gui/panels/beamline_recovery_panel.py +++ b/src/aare/gui/panels/beamline_recovery_panel.py @@ -193,11 +193,20 @@ class RecoveryPanel(QWidget): sample_mounted = self._sample_appears_mounted() tell_connected = bool(getattr(self._last_status, "tell_connected", False)) + tell_state_text = "—" + if getattr(self._last_status, "tell_state", None) is not None: + tell_state = self._last_status.tell_state + tell_state_text = tell_state.activity.value + tell_message = (tell_state.message or "").strip() + if tell_message: + tell_state_text = f"{tell_state_text} ({tell_message})" + return ( f"State: {state_name}\n" f"Busy: {busy}\n" f"Sample mounted: {sample_mounted}\n" - f"TELL connected: {tell_connected}" + f"TELL connected: {tell_connected}\n" + f"TELL state: {tell_state_text}" ) def _refresh_buttons(self) -> None: diff --git a/src/aare/gui/panels/beamline_state_panel.py b/src/aare/gui/panels/beamline_state_panel.py index 4f036609..32c426ec 100644 --- a/src/aare/gui/panels/beamline_state_panel.py +++ b/src/aare/gui/panels/beamline_state_panel.py @@ -164,6 +164,19 @@ class BeamlineStatePanel(QFrame): self.current_label.move(14, 58) self.current_label.adjustSize() + self.tell_label = QLabel("Tell: —", self) + self.tell_label.setStyleSheet(""" + QLabel { + color: rgb(55, 67, 87); + font-size: 13px; + font-weight: 600; + padding-left: 4px; + background: transparent; + } + """) + self.tell_label.move(14, 86) + self.tell_label.adjustSize() + self.view_toggle = QPushButton(self) self.view_toggle.setCheckable(False) self.view_toggle.setStyleSheet(""" @@ -529,6 +542,39 @@ class BeamlineStatePanel(QFrame): def update_daq_status(self, status: DAQStatusModel) -> None: self.set_current_state(status.state) + tell_text = "Tell: —" + tell_color = "rgb(55, 67, 87)" + if status.tell_state is not None: + tell_state = status.tell_state + tell_text = f"Tell: {tell_state.activity.display_name()}" + + tell_phase = tell_state.phase.display_name() if tell_state.phase is not None else "" + tell_message = (tell_state.message or "").strip() + + if tell_phase: + tell_text = f"{tell_text} ({tell_phase})" + elif tell_message: + tell_text = f"{tell_text} ({tell_message})" + + if tell_state.activity.value == "error": + tell_color = "red" + elif tell_state.activity.value in {"mounting", "unmounting", "drying", "cooling"}: + tell_color = "orange" + else: + tell_color = "green" + + self.tell_label.setText(tell_text) + self.tell_label.setStyleSheet(f""" + QLabel {{ + color: {tell_color}; + font-size: 13px; + font-weight: 600; + padding-left: 4px; + background: transparent; + }} + """) + self.tell_label.adjustSize() + def set_current_state(self, state: BeamlineStateEnum | None) -> None: self._current_state = state diff --git a/src/aare/gui/widgets/camera_image.py b/src/aare/gui/widgets/camera_image.py index 501be959..b7f570b8 100644 --- a/src/aare/gui/widgets/camera_image.py +++ b/src/aare/gui/widgets/camera_image.py @@ -76,6 +76,7 @@ class SampleCameraImageLabel(QGraphicsView): self.__camera_available = True self.__last_grid_update_ts = 0.0 self.__grid_update_min_interval_s = 1.0 / 25.0 + self.__tell_state = None self.__geom = geom self.__bookmarks: SmargonBookmarkList = SmargonBookmarkList() @@ -208,6 +209,19 @@ class SampleCameraImageLabel(QGraphicsView): self.__smoothed_target_point = None self.update() + def __busy_overlay_text(self) -> str: + tell_state = self.__tell_state + if tell_state is None: + return "BEAMLINE BUSY" + + activity_value = str(getattr(tell_state.activity, "value", "") or "").lower() + if activity_value not in {"mounting", "unmounting", "drying", "cooling"}: + return "BEAMLINE BUSY" + + activity_name = tell_state.activity.display_name() + + return f"TELL {activity_name}".upper() + def __draw_busy_overlay(self, painter: QPainter): if not self.__is_daq_busy: return @@ -223,7 +237,7 @@ class SampleCameraImageLabel(QGraphicsView): painter.setPen(QPen(QColor(255, 255, 255, 200), 2, Qt.PenStyle.SolidLine)) painter.setBrush(QColor(255, 0, 0, 150)) - text = "BEAMLINE BUSY" + text = self.__busy_overlay_text() font_metrics = QFontMetrics(font) text_rect = font_metrics.boundingRect(text) @@ -586,6 +600,7 @@ class SampleCameraImageLabel(QGraphicsView): self.__geom = s.geom self.__sam_cam = s.bl.sample_camera self.__bounding_box = s.box + self.__tell_state = s.tell_state new_session_state = s.session.session if hasattr(s, 'session') else None if new_session_state != self.__session_state: diff --git a/src/aare/gui/widgets/status_bar.py b/src/aare/gui/widgets/status_bar.py index a78ffbf6..7c34a50a 100644 --- a/src/aare/gui/widgets/status_bar.py +++ b/src/aare/gui/widgets/status_bar.py @@ -72,6 +72,8 @@ class StatusBar(QStatusBar): self.state_label = ClickableLabel(parent=self) self.state_label.clicked.connect(self.show_state_menu) + self.tell_state_label = QLabel("Tell: —", self) + self.busy_label = ClickableLabel(parent=self) self.session_label = ClickableLabel(parent=self) @@ -93,6 +95,7 @@ class StatusBar(QStatusBar): self.addPermanentWidget(self.exp_shutter_label) self.addPermanentWidget(self.pgroup_label) self.addPermanentWidget(self.state_label) + self.addPermanentWidget(self.tell_state_label) self.addPermanentWidget(self.busy_label) self.addPermanentWidget(self.session_label) @@ -173,6 +176,21 @@ class StatusBar(QStatusBar): self.state_label.setText(f"""State: {status.state.display_name()} """) + tell_text = "—" + tell_color = "rgb(55, 67, 87)" + if status.tell_state is not None: + tell_text = status.tell_state.activity.display_name() + + if status.tell_state.activity.value == "error": + tell_color = "red" + elif status.tell_state.activity.value in {"mounting", "unmounting", "drying", "cooling"}: + tell_color = "orange" + else: + tell_color = "green" + + self.tell_state_label.setText(f"Tell: {tell_text} ") + self.tell_state_label.setStyleSheet(f"color: {tell_color};") + if status.busy: busy_flag = """ Busy 🔒 """ else: