diff --git a/mu2edaq-dataformat-viewer.py b/mu2edaq-dataformat-viewer.py index 32040b6..dc9804d 100755 --- a/mu2edaq-dataformat-viewer.py +++ b/mu2edaq-dataformat-viewer.py @@ -235,9 +235,11 @@ def _apply_config_defaults(self) -> None: if idx >= 0: self.format_combo.setCurrentIndex(idx) - # Viewer port and protocol + # Viewer port and protocol. + # CRS_PORT_LISTEN is exported by the control room crs-app launcher. viewer_cfg = self._cfg.get("viewer", {}) - port = viewer_cfg.get("port", 7755) + port = int(os.environ.get("CRS_PORT_LISTEN", + viewer_cfg.get("port", 7755))) self._port_edit.setText(str(port)) proto = viewer_cfg.get("protocol", "TCP") idx = self._proto_combo.findText(proto.upper()) @@ -994,10 +996,27 @@ def _start_server(self): self._listen_btn.setText("Stop listening") self._proto_combo.setEnabled(False) self._set_status(f"Listening on {proto} port {port}\u2026") + self._start_responder(port, proto) except OSError as exc: QMessageBox.critical(self, "Error", f"Could not start server:\n{exc}") + def _start_responder(self, port, proto): + """Announce the listener via mu2edaq-discovery (optional dependency). + Started only while actually listening, stopped with the server.""" + try: + from mu2edaq_discovery import Responder + except ImportError: + return + self._responder = Responder( + name="Data Format Viewer", app="dataformat-viewer", + port=port, scheme=proto.lower()) + self._responder.start() + def _stop_server(self): + responder = getattr(self, "_responder", None) + if responder is not None: + responder.stop() + self._responder = None if self._server_socket: try: self._server_socket.close() diff --git a/requirements.txt b/requirements.txt index 295c285..682fe5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ PyYAML>=6.0 PyQt6>=6.4 +mu2edaq-discovery @ git+https://github.com/Mu2e/mu2edaq-discovery.git diff --git a/start-mu2edaq-dataformat-viewer.sh b/start-mu2edaq-dataformat-viewer.sh new file mode 100755 index 0000000..9e924a6 --- /dev/null +++ b/start-mu2edaq-dataformat-viewer.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Start the Mu2e Data Format Viewer (PyQt6 GUI). +# DISPLAY is honored from the environment so the window appears in the +# invoking VNC session. CRS_PORT_LISTEN (exported by the control room +# crs-app launcher) overrides the configured listen port. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PID_FILE="${CRS_HOME:-$HOME/controlroom}/log/dataformat-viewer.pid" +mkdir -p "$(dirname "$PID_FILE")" 2>/dev/null || PID_FILE="/tmp/dataformat-viewer.pid" + +PYTHON="$SCRIPT_DIR/venv/bin/python" +[[ -x "$PYTHON" ]] || PYTHON="python3" + +nohup "$PYTHON" "$SCRIPT_DIR/mu2edaq-dataformat-viewer.py" "$@" \ + >> "${PID_FILE%.pid}.log" 2>&1 & +echo $! > "$PID_FILE" +echo "Data Format Viewer started (PID $(cat "$PID_FILE"))." diff --git a/stop-mu2edaq-dataformat-viewer.sh b/stop-mu2edaq-dataformat-viewer.sh new file mode 100755 index 0000000..d00f115 --- /dev/null +++ b/stop-mu2edaq-dataformat-viewer.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Stop the Mu2e Data Format Viewer. +set -uo pipefail + +PID_FILE="${CRS_HOME:-$HOME/controlroom}/log/dataformat-viewer.pid" +[[ -f "$PID_FILE" ]] || PID_FILE="/tmp/dataformat-viewer.pid" + +if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then + kill "$(cat "$PID_FILE")" + rm -f "$PID_FILE" + echo "Data Format Viewer stopped." +else + PIDS=$(pgrep -f "mu2edaq-dataformat-viewer.py" || true) + if [[ -n "$PIDS" ]]; then + kill $PIDS 2>/dev/null || true + echo "Data Format Viewer stopped (found by name)." + else + echo "Data Format Viewer is not running." + fi + rm -f "$PID_FILE" 2>/dev/null || true +fi +exit 0