소스 검색

Revert backend changes to debug serial terminal issue

Temporarily reverting stop/reset reliability changes to test if they
caused the serial terminal to stop receiving responses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 2 주 전
부모
커밋
6816e54457
3개의 변경된 파일6개의 추가작업 그리고 81개의 파일을 삭제
  1. 5 54
      main.py
  2. 1 20
      modules/connection/connection_manager.py
  3. 0 7
      modules/core/pattern_manager.py

+ 5 - 54
main.py

@@ -1620,53 +1620,13 @@ async def stop_execution():
     if not (state.conn.is_connected() if state.conn else False):
         logger.warning("Attempted to stop without a connection")
         raise HTTPException(status_code=400, detail="Connection not established")
-    success = await pattern_manager.stop_actions()
-    if not success:
-        raise HTTPException(status_code=500, detail="Stop timed out - use force_stop")
+    await pattern_manager.stop_actions()
     return {"success": True}
 
-@app.post("/force_stop")
-async def force_stop():
-    """Force stop all pattern execution and clear all state. Use when normal stop doesn't work."""
-    logger.info("Force stop requested - clearing all pattern state")
-
-    # Set stop flag first
-    state.stop_requested = True
-    state.pause_requested = False
-
-    # Clear all pattern-related state
-    state.current_playing_file = None
-    state.execution_progress = None
-    state.is_running = False
-    state.is_clearing = False
-    state.is_homing = False
-    state.current_playlist = None
-    state.current_playlist_index = None
-    state.playlist_mode = None
-    state.pause_time_remaining = 0
-
-    # Wake up any waiting tasks
-    try:
-        pattern_manager.get_pause_event().set()
-    except:
-        pass
-
-    # Stop motion controller and clear its queue
-    if pattern_manager.motion_controller.running:
-        pattern_manager.motion_controller.command_queue.put(
-            pattern_manager.MotionCommand('stop')
-        )
-
-    # Force release pattern lock by recreating it
-    pattern_manager.pattern_lock = None  # Will be recreated on next use
-
-    logger.info("Force stop completed - all pattern state cleared")
-    return {"success": True, "message": "Force stop completed"}
-
 @app.post("/soft_reset")
 async def soft_reset():
     """Send Ctrl+X soft reset to the controller (DLC32/ESP32). Requires re-homing after."""
-    if not (state.conn and state.conn.is_connected()):
+    if not (state.conn.is_connected() if state.conn else False):
         logger.warning("Attempted to soft reset without a connection")
         raise HTTPException(status_code=400, detail="Connection not established")
 
@@ -1674,18 +1634,9 @@ async def soft_reset():
         # Stop any running patterns first
         await pattern_manager.stop_actions()
 
-        # Access the underlying serial object directly for more reliable reset
-        # This bypasses the connection abstraction which may have buffering issues
-        from modules.connection.connection_manager import SerialConnection
-        if isinstance(state.conn, SerialConnection) and state.conn.ser:
-            state.conn.ser.reset_input_buffer()  # Clear any pending data
-            state.conn.ser.write(b'\x18')  # Ctrl+X as bytes
-            state.conn.ser.flush()
-            logger.info(f"Soft reset command (Ctrl+X) sent directly via serial to {state.port}")
-        else:
-            # Fallback for WebSocket or other connection types
-            state.conn.send('\x18')
-            logger.info("Soft reset command (Ctrl+X) sent via connection abstraction")
+        # Send Ctrl+X (0x18) - GRBL/FluidNC soft reset command
+        state.conn.send('\x18')
+        logger.info("Soft reset command (Ctrl+X) sent to controller")
 
         # Mark as needing homing since position is now unknown
         state.is_homed = False

+ 1 - 20
modules/connection/connection_manager.py

@@ -1141,31 +1141,12 @@ def check_idle():
             return True
         time.sleep(1)
 
-async def check_idle_async(timeout: float = 30.0):
+async def check_idle_async():
     """
     Continuously check if the device is idle (async version).
-
-    Args:
-        timeout: Maximum seconds to wait for idle state (default 30s)
-
-    Returns:
-        True if device became idle, False if timeout or stop requested
     """
     logger.info("Checking idle (async)")
-    start_time = asyncio.get_event_loop().time()
-
     while True:
-        # Check if stop was requested - exit early
-        if state.stop_requested:
-            logger.info("Stop requested during idle check, exiting early")
-            return False
-
-        # Check timeout
-        elapsed = asyncio.get_event_loop().time() - start_time
-        if elapsed > timeout:
-            logger.warning(f"Timeout ({timeout}s) waiting for device idle state")
-            return False
-
         response = await asyncio.to_thread(get_status_response)
         if response and "Idle" in response:
             logger.info("Device is idle")

+ 0 - 7
modules/core/pattern_manager.py

@@ -1210,11 +1210,7 @@ async def stop_actions(clear_playlist = True, wait_for_lock = True):
         clear_playlist: Whether to clear playlist state
         wait_for_lock: Whether to wait for pattern_lock to be released. Set to False when
                       called from within pattern execution to avoid deadlock.
-
-    Returns:
-        True if stopped cleanly, False if timed out waiting for pattern lock
     """
-    timed_out = False
     try:
         with state.pause_condition:
             state.pause_requested = False
@@ -1258,7 +1254,6 @@ async def stop_actions(clear_playlist = True, wait_for_lock = True):
                         logger.info("Pattern lock acquired - pattern has fully stopped")
             except asyncio.TimeoutError:
                 logger.warning("Timeout waiting for pattern to stop - forcing cleanup")
-                timed_out = True
                 # Force cleanup of state even if pattern didn't release lock gracefully
                 state.current_playing_file = None
                 state.execution_progress = None
@@ -1270,7 +1265,6 @@ async def stop_actions(clear_playlist = True, wait_for_lock = True):
 
         # Call async function directly since we're in async context
         await connection_manager.update_machine_position()
-        return not timed_out
     except Exception as e:
         logger.error(f"Error during stop_actions: {e}")
         # Force cleanup state on error
@@ -1282,7 +1276,6 @@ async def stop_actions(clear_playlist = True, wait_for_lock = True):
             await connection_manager.update_machine_position()
         except Exception as update_err:
             logger.error(f"Error updating machine position on error: {update_err}")
-        return False
 
 async def move_polar(theta, rho, speed=None):
     """