|
|
@@ -67,24 +67,48 @@ class GRBLHandler:
|
|
|
finally:
|
|
|
self.controller_active.clear()
|
|
|
|
|
|
- async def wait_until_idle(self, timeout_s):
|
|
|
- """Wait until GRBL reports idle status"""
|
|
|
+ async def get_status(self):
|
|
|
+ """Get current GRBL status
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ str: Status response from GRBL, or None if in debug mode
|
|
|
+ """
|
|
|
+ if self.debug:
|
|
|
+ return None
|
|
|
+
|
|
|
+ if self.writer:
|
|
|
+ self.writer.write(b"?\n")
|
|
|
+ await self.writer.drain()
|
|
|
+ # '?' command returns status report and 'ok'
|
|
|
+ response = await self._process_response()
|
|
|
+ response = response + await self._process_response()
|
|
|
+ return response
|
|
|
+ return None
|
|
|
+
|
|
|
+ async def wait_until_idle(self, timeout_s, position: list[float] = None):
|
|
|
+ """Wait until GRBL reports idle status
|
|
|
+
|
|
|
+ Args:
|
|
|
+ timeout_s: Timeout in seconds
|
|
|
+ position: Optional list of 3 floats that will be updated with current position
|
|
|
+ """
|
|
|
if self.debug:
|
|
|
await asyncio.sleep(1)
|
|
|
return
|
|
|
|
|
|
start = datetime.datetime.now()
|
|
|
while True:
|
|
|
- if self.writer:
|
|
|
- self.writer.write(b"?\n")
|
|
|
- await self.writer.drain()
|
|
|
- # '?' command returns status report and 'ok'
|
|
|
- response = await self._process_response()
|
|
|
- response = response + await self._process_response()
|
|
|
-
|
|
|
- if response and "Idle" in response:
|
|
|
- logger.debug("Movement complete.\nContinuing...")
|
|
|
- break
|
|
|
+ response = await self.get_status()
|
|
|
+ if response and 'MPos:' in response:
|
|
|
+ # Parse position from status reports (<Idle|MPos:0.000,0.000,0.000|...>)
|
|
|
+ pos_str = response.split('MPos:')[1].split('|')[0]
|
|
|
+ if position is not None:
|
|
|
+ x, y, z = map(float, pos_str.split(','))
|
|
|
+ position = (x,y,z)
|
|
|
+
|
|
|
+ if response and "Idle" in response:
|
|
|
+ logger.debug("Movement complete.\nContinuing...")
|
|
|
+ break
|
|
|
|
|
|
now = datetime.datetime.now()
|
|
|
if (now - start).total_seconds() > timeout_s:
|
|
|
@@ -93,11 +117,11 @@ class GRBLHandler:
|
|
|
|
|
|
await asyncio.sleep(0.2) # Async delay to prevent flooding
|
|
|
|
|
|
- async def send_and_wait_gcode(self, commands: List[str], timeout_s=60):
|
|
|
+ async def send_and_wait_gcode(self, commands: List[str], timeout_s=60, position: list[float] = None):
|
|
|
"""Send GCODE commands and wait until machine is idle"""
|
|
|
await self.send_gcode(commands)
|
|
|
await asyncio.sleep(0.2) # Delay to allow GRBL to process commands
|
|
|
- await self.wait_until_idle(timeout_s)
|
|
|
+ await self.wait_until_idle(timeout_s, position)
|
|
|
|
|
|
async def _process_response(self):
|
|
|
"""Process GRBL responses"""
|