175 lines
6.2 KiB
Python
175 lines
6.2 KiB
Python
import sys
|
|
import glob
|
|
import serial
|
|
import re
|
|
import requests
|
|
import random
|
|
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
|
QLabel, QSizePolicy, QPushButton, QGridLayout)
|
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal
|
|
import time
|
|
|
|
class UpdateWorker(QThread):
|
|
update_signal = pyqtSignal(int, int)
|
|
|
|
def __init__(self, block, serial_number, bench_id):
|
|
super().__init__()
|
|
self.block = block
|
|
self.serial_number = serial_number
|
|
self.bench_id = bench_id
|
|
self.counter = 0
|
|
|
|
def run(self):
|
|
while True:
|
|
random_value = random.randint(0, 100)
|
|
self.counter += 1
|
|
self.update_signal.emit(random_value, self.counter)
|
|
self.sleep(1) # Sleep for 1 second
|
|
|
|
class BlockStackApp(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.initUI()
|
|
self.check_usb_devices()
|
|
|
|
def initUI(self):
|
|
# Set up the layout
|
|
self.layout = QVBoxLayout()
|
|
self.layout.setSpacing(5) # Set space between widgets to 5 pixels
|
|
self.layout.setContentsMargins(5, 5, 5, 5) # Set margins around the layout to 5 pixels
|
|
|
|
# Align the layout to the left
|
|
self.layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
|
|
|
# Set the layout to the QWidget
|
|
self.setLayout(self.layout)
|
|
|
|
self.setWindowTitle('462filament Bench GUI')
|
|
|
|
# Apply dark theme
|
|
self.setStyleSheet("""
|
|
QWidget {
|
|
background-color: #2E2E2E;
|
|
color: #FFFFFF;
|
|
}
|
|
QLabel {
|
|
background-color: #4A4A4A;
|
|
border: 1px solid #5A5A5A;
|
|
padding: 10px;
|
|
margin: 5px;
|
|
}
|
|
QPushButton {
|
|
background-color: #5A5A5A;
|
|
border: 1px solid #6A6A6A;
|
|
padding: 5px;
|
|
margin: 2px;
|
|
}
|
|
""")
|
|
|
|
# Show the window maximized
|
|
self.showMaximized()
|
|
|
|
def check_usb_devices(self):
|
|
# Check each /dev/ttyUSB? device
|
|
for port in glob.glob('/dev/ttyUSB*'):
|
|
print(f"Check port {port}")
|
|
try:
|
|
with serial.Serial(port, 1000000, timeout=1) as ser:
|
|
ser.write(b'i') # Send the character 'i'
|
|
time.sleep(1) # Wait for 1 second to receive data
|
|
response = ser.read_all().decode('utf-8').strip()
|
|
serial_number = self.extract_serial_number(response)
|
|
if serial_number:
|
|
print(f"Got id on port {port}")
|
|
bench_id = self.get_bench_id(serial_number)
|
|
if bench_id:
|
|
print(f"Adding port {port}")
|
|
block = self.add_block(serial_number, bench_id)
|
|
# Start a QThread for each block
|
|
self.worker = UpdateWorker(block, serial_number, bench_id)
|
|
self.worker.update_signal.connect(self.update_block)
|
|
self.worker.start()
|
|
except serial.SerialException as e:
|
|
print(f"Could not open port {port}: {e}")
|
|
|
|
def extract_serial_number(self, response):
|
|
# Extract the hexadecimal serial number using a regular expression
|
|
match = re.match(r"id:([0-9A-Fa-f]+)", response)
|
|
if match:
|
|
return match.group(1)
|
|
return None
|
|
|
|
def get_bench_id(self, serial_number):
|
|
# Make a request to the API to get the bench ID
|
|
url = f"http://462filament/api.php?data=benchid&serial={serial_number}"
|
|
try:
|
|
response = requests.get(url)
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
return data.get("id")
|
|
except requests.RequestException as e:
|
|
print(f"Error making request to API: {e}")
|
|
return None
|
|
|
|
def add_block(self, serial_number, bench_id):
|
|
# Create a new block with three zones
|
|
block_widget = QWidget()
|
|
block_layout = QHBoxLayout()
|
|
|
|
# Left zone
|
|
left_layout = QVBoxLayout()
|
|
id_label = QLabel(f"id: {serial_number}")
|
|
bench_label = QLabel(f"Bench ID: {bench_id}")
|
|
diameter_label = QLabel("Diameter: 0")
|
|
position_label = QLabel("Position: 0")
|
|
left_layout.addWidget(id_label)
|
|
left_layout.addWidget(bench_label)
|
|
left_layout.addWidget(diameter_label)
|
|
left_layout.addWidget(position_label)
|
|
|
|
# Center zone (placeholder for graph)
|
|
center_layout = QVBoxLayout()
|
|
graph_placeholder = QLabel("Graph Placeholder")
|
|
graph_placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
center_layout.addWidget(graph_placeholder)
|
|
|
|
# Right zone with buttons in a grid layout
|
|
right_layout = QGridLayout()
|
|
buttons = [
|
|
("Home", ""), ("Sleep", "a"), ("Down Right", "t"),
|
|
("Up Right", "y"), ("Down Left", "g"), ("Up Left", "h"),
|
|
("Start", "S"), ("Stop", "R"), ("Reset", "r"),
|
|
("Go Right", "1"), ("Go Left", "2")
|
|
]
|
|
for index, (text, command) in enumerate(buttons):
|
|
button = QPushButton(f"{text} ({command})")
|
|
row = index // 3 # Determine the row
|
|
col = index % 3 # Determine the column
|
|
right_layout.addWidget(button, row, col)
|
|
|
|
# Add zones to the block layout
|
|
block_layout.addLayout(left_layout)
|
|
block_layout.addLayout(center_layout)
|
|
block_layout.addLayout(right_layout)
|
|
|
|
block_widget.setLayout(block_layout)
|
|
self.layout.addWidget(block_widget)
|
|
|
|
# Store labels for updating
|
|
block_widget.diameter_label = diameter_label
|
|
block_widget.position_label = position_label
|
|
|
|
return block_widget
|
|
|
|
def update_block(self, random_value, counter):
|
|
# Update the block with random value and incrementing counter
|
|
worker = self.sender()
|
|
worker.block.diameter_label.setText(f"Diameter: {random_value}")
|
|
worker.block.position_label.setText(f"Position: {counter}")
|
|
|
|
if __name__ == '__main__':
|
|
app = QApplication(sys.argv)
|
|
ex = BlockStackApp()
|
|
sys.exit(app.exec_())
|