From 4896e640744978adc4c05296853652ae61b9bb61 Mon Sep 17 00:00:00 2001 From: Sohel Date: Wed, 20 Nov 2024 15:49:55 +0100 Subject: [PATCH] The web app now streams gcode over web sockets --- plotter-app/app.py | 8 ++-- plotter-app/streamer.py | 74 +++++++++++++++++++++++++++++++++-- plotter-app/test_socket.py | 8 ++++ plotter-app/websocket_test.py | 24 ++++++++++++ 4 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 plotter-app/test_socket.py create mode 100644 plotter-app/websocket_test.py diff --git a/plotter-app/app.py b/plotter-app/app.py index 830ef4f..1b7be06 100644 --- a/plotter-app/app.py +++ b/plotter-app/app.py @@ -1,7 +1,7 @@ from flask import Flask, render_template, request import sys import os -from streamer import stream_gcode +from streamer import stream_gcode_websocket from text_to_gcode import convert_text import svgToGcode @@ -42,7 +42,7 @@ def getSVG(): gcode = svgToGcode.convertToGcode(file.read() ,output) - stream_gcode(gcode.splitlines()) + stream_gcode_websocket(gcode.splitlines()) print(gcode) print("done!") else: @@ -62,7 +62,7 @@ def getGcode(): gcode = file.readlines() print(str(gcode)) - stream_gcode(gcode) + stream_gcode_websocket(gcode) else: print('empty file or unaccepted file') @@ -102,6 +102,8 @@ def getText(): gcode_filename = "retourligne.gcode" with open(gcode_filename, "w") as gcode_file: gcode_file.write(gcode_output) + + stream_gcode_websocket(gcode_output) #envoi du gcode généré au plotter print(f"G-code saved to {gcode_filename}") else: diff --git a/plotter-app/streamer.py b/plotter-app/streamer.py index 7282704..0f8c3c5 100644 --- a/plotter-app/streamer.py +++ b/plotter-app/streamer.py @@ -1,6 +1,9 @@ import serial import time - +import threading +import websocket +import time +import queue #### Load gcode testfile @@ -10,9 +13,9 @@ import time -#### Streamer +#### Serial treamer -def stream_gcode(gcode): +def stream_gcode_serial(gcode): # Open grbl serial port s = serial.Serial('/dev/ttyACM0',115200) @@ -40,5 +43,68 @@ def stream_gcode(gcode): print('job done') -#stream_gcode(gcode) + + +#### Web Socket Streamer + +# Global variables +ws = None +response_queue = queue.Queue() # Thread-safe queue for server responses + +def receiver(): + """Receives messages from the WebSocket server.""" + while True: + try: + # Receive a message from the WebSocket + for l in ws.recv().splitlines(): + if isinstance(l, str): + response = l + else: + response = str(l, 'utf-8') + # print("Received:", response) + response_queue.put(response) # Add response to the queue + except Exception as e: + print("Error in receiver:", e) + break + +def stream_gcode_websocket(gcode): + """Streams G-code commands to the WebSocket server.""" + global ws + ws = websocket.WebSocket() + ws.connect("ws://192.168.0.1:81") # Replace with your server's address + + # Start the receiver thread + t = threading.Thread(target=receiver, daemon=True) + t.start() + + # Wake up GRBL + ws.send("\r\n\r\n") + time.sleep(2) # Wait for GRBL to initialize + with response_queue.mutex: + response_queue.queue.clear() + + for line in gcode: + l = str(line.strip()) # Strip all EOL characters for consistency + print('Sending:', l) + ws.send(l + '\n') # Send G-code block to the server + + # Wait for server response + try: + grbl_out = response_queue.get(timeout=5) # Wait up to 5 seconds for a response + print('Response:', grbl_out.strip()) + if(grbl_out.strip() != "ok"): + break + except queue.Empty: + print("Timeout waiting for server response.") + + print('Job done') + ws.close() + +# gcode = [ +# "G0 X10 Y10", +# "G1 X20 Y20", +# "G1 X30 Y10" +# ] + +# stream_gcode_websocket(gcode) \ No newline at end of file diff --git a/plotter-app/test_socket.py b/plotter-app/test_socket.py new file mode 100644 index 0000000..d938066 --- /dev/null +++ b/plotter-app/test_socket.py @@ -0,0 +1,8 @@ +import socket +import sys +# Create a TCP/IP socket +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# Connect the socket to the port where the server is listening +server_address = ('192.168.0.1', 81) +print(sys.stderr, 'connecting to %s port %s' % server_address) +sock.connect(server_address) \ No newline at end of file diff --git a/plotter-app/websocket_test.py b/plotter-app/websocket_test.py new file mode 100644 index 0000000..eef98f8 --- /dev/null +++ b/plotter-app/websocket_test.py @@ -0,0 +1,24 @@ +import threading, websocket, time +ws = websocket.WebSocket() +ws.connect("ws://192.168.0.1:81") + +# Reception needs to be done in a separate thread; you cannot +# assume that a given command will always result in exactly one +# response at a predictable time +# def receiver(): +# while True: +# for l in ws.recv().splitlines(): +# if isinstance(l, str): +# print(l) +# else: +# print(str(l, 'utf-8')) + +# t = threading.Thread(target=receiver) +# t.start() + +# ws.send("?") # realtime characters need no line terminator +# ws.send("$/axes/x\n") # line-oriented commands need \n at the end +ws.send("\r\n\r\n") +print(ws.recv()) +ws.send("G0 X10\n") +print(ws.recv())