From cae52c1fa868c2a2be51af5ef38c4adc1d94e2ce Mon Sep 17 00:00:00 2001 From: Kai Chappell Date: Sat, 1 Nov 2025 19:51:41 +0000 Subject: [PATCH] Improve dashboard UX: connect instruments before tests, clarify simulation controls, show error messages --- src/py_dvt_ate/app/dashboard/app.py | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/py_dvt_ate/app/dashboard/app.py b/src/py_dvt_ate/app/dashboard/app.py index 372717c..811d879 100644 --- a/src/py_dvt_ate/app/dashboard/app.py +++ b/src/py_dvt_ate/app/dashboard/app.py @@ -203,21 +203,23 @@ def display_controls() -> None: """Display simulation control panel in sidebar.""" st.sidebar.header("Simulation Controls") + st.sidebar.info("🔧 Physics engine is always running in the background. Use the button below to start/stop chart updates.") + # Start/Stop button if st.session_state.running: if st.sidebar.button( - "Stop Simulation", type="primary", use_container_width=True + "⏸️ Pause Charts", type="primary", width="stretch" ): st.session_state.running = False else: if st.sidebar.button( - "Start Simulation", type="primary", use_container_width=True + "▶️ Start Charts", type="primary", width="stretch" ): st.session_state.running = True st.session_state.last_update = time.time() # Reset button - if st.sidebar.button("Reset", use_container_width=True): + if st.sidebar.button("Reset", width="stretch"): # Stop server and restart server: SimulationServer = st.session_state.server loop = asyncio.new_event_loop() @@ -580,7 +582,7 @@ def test_execution_page() -> None: if st.button( "Run Test", type="primary", - use_container_width=True, + width="stretch", disabled=st.session_state.test_running, ): st.session_state.test_running = True @@ -602,6 +604,16 @@ def test_execution_page() -> None: runner: TestRunner = st.session_state.test_runner instruments: InstrumentSet = st.session_state.instruments + # Connect instruments before running test + try: + instruments.chamber.transport.connect() # type: ignore[attr-defined] + instruments.psu.transport.connect() # type: ignore[attr-defined] + instruments.dmm.transport.connect() # type: ignore[attr-defined] + except Exception as e: + st.error(f"Failed to connect to instruments: {e}") + st.session_state.test_running = False + st.stop() + # Run the test run_id = runner.run_test( test=selected_test, @@ -629,9 +641,9 @@ def test_execution_page() -> None: col1, col2, col3 = st.columns(3) with col1: status_color = {"PASSED": "🟢", "FAILED": "🔴", "ERROR": "🟡"}.get( - run.status.value, "⚪" + run.status.value.upper(), "⚪" ) - st.metric("Status", f"{status_color} {run.status.value}") + st.metric("Status", f"{status_color} {run.status.value.upper()}") with col2: if run.completed_at and run.started_at: duration = (run.completed_at - run.started_at).total_seconds() @@ -642,6 +654,12 @@ def test_execution_page() -> None: results = repository.get_results(st.session_state.test_run_id) st.metric("Results", len(results)) + # Show error/warning message for non-PASSED tests + if run.status.value.upper() == "ERROR": + st.error("⚠️ Test encountered an error during execution. Check the detailed results below or the terminal output for error messages.") + elif run.status.value.upper() == "FAILED": + st.warning("⚠️ Test completed but one or more results failed to meet specifications.") + # Show detailed results if results: st.markdown("#### Detailed Results") @@ -757,7 +775,7 @@ def results_viewer_page() -> None: # Use data editor for row selection edited_df = st.data_editor( df, - use_container_width=True, + width="stretch", hide_index=True, column_config={ "Select": st.column_config.CheckboxColumn( @@ -850,7 +868,7 @@ def results_viewer_page() -> None: ).properties( height=300 ) - st.altair_chart(chart, use_container_width=True) + st.altair_chart(chart, width="stretch") except Exception as e: st.caption(f"No time-series measurement data available ({e})")