|
|
@@ -1,20 +1,19 @@
|
|
|
import asyncio
|
|
|
-import logging
|
|
|
-import os
|
|
|
-import socket
|
|
|
+import serial_asyncio
|
|
|
from typing import List
|
|
|
+from utils.logging import LoggerSingleton
|
|
|
|
|
|
MOVE_RATE = 50
|
|
|
APPROACHE_RATE = 10
|
|
|
CELL_CIRCLE_RADIUS = 0.35
|
|
|
|
|
|
-logger = logging.getLogger(__name__)
|
|
|
+logger = LoggerSingleton.get_logger()
|
|
|
|
|
|
class GRBLHandler:
|
|
|
- def __init__(self, host: str, port: int):
|
|
|
- self.host = host
|
|
|
+ def __init__(self, port: str, baudrate: int):
|
|
|
self.port = port
|
|
|
self.debug = port == "debug"
|
|
|
+ self.baudrate = baudrate
|
|
|
|
|
|
self.controller_active = asyncio.Event()
|
|
|
|
|
|
@@ -30,8 +29,9 @@ class GRBLHandler:
|
|
|
|
|
|
logger.info("Connecting to GRBL...")
|
|
|
try:
|
|
|
- self.reader, self.writer = await asyncio.open_connection(
|
|
|
- self.host, self.port
|
|
|
+ self.reader, self.writer = await serial_asyncio.open_serial_connection(
|
|
|
+ url = self.port,
|
|
|
+ baudrate = self.baudrate
|
|
|
)
|
|
|
await self._process_response()
|
|
|
logger.info("GRBL connected.")
|
|
|
@@ -49,6 +49,7 @@ class GRBLHandler:
|
|
|
self.controller_active.set()
|
|
|
try:
|
|
|
for cmd in commands:
|
|
|
+ logger.debug(f"Sending G-Code command: {cmd}")
|
|
|
self.writer.write(f"{cmd}\n".encode())
|
|
|
await self.writer.drain()
|
|
|
await self._process_response()
|
|
|
@@ -58,13 +59,13 @@ class GRBLHandler:
|
|
|
async def _process_response(self):
|
|
|
"""Process GRBL responses"""
|
|
|
if self.reader:
|
|
|
- response = await self.reader.readline()
|
|
|
- decoded = response.strip().decode("utf-8")
|
|
|
- logger.debug(f"G-Code response: {decoded}")
|
|
|
-
|
|
|
- # Parse position from status reports (<Idle|MPos:0.000,0.000,0.000|...>)
|
|
|
- if decoded.startswith('<') and 'MPos:' in decoded:
|
|
|
- try:
|
|
|
+ try:
|
|
|
+ response = await asyncio.wait_for(self.reader.readline(), timeout=2.0) # 2 second timeout
|
|
|
+ decoded = response.strip().decode("utf-8")
|
|
|
+ logger.debug(f"G-Code response: {decoded}")
|
|
|
+
|
|
|
+ # Parse position from status reports (<Idle|MPos:0.000,0.000,0.000|...>)
|
|
|
+ if decoded.startswith('<') and 'MPos:' in decoded:
|
|
|
pos_str = decoded.split('MPos:')[1].split('|')[0]
|
|
|
x, y, z = map(float, pos_str.split(','))
|
|
|
self.current_position = (x,y,z)
|
|
|
@@ -72,10 +73,14 @@ class GRBLHandler:
|
|
|
# Notify all registered callbacks
|
|
|
for callback in self.position_callbacks:
|
|
|
callback(self.current_position)
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"Failed to parse position: {e}")
|
|
|
-
|
|
|
- return decoded
|
|
|
+
|
|
|
+ return decoded
|
|
|
+ except asyncio.TimeoutError:
|
|
|
+ logger.warning("Timeout waiting for GRBL response")
|
|
|
+ return None
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Failed to parse position: {e}")
|
|
|
+ return None
|
|
|
|
|
|
def register_position_callback(self, callback):
|
|
|
"""Register callback for position updates
|