import numpy as np from matplotlib.figure import Figure import socket import msgpack from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QHBoxLayout, QMessageBox from PySide6.QtWidgets import QDialog, QFormLayout, QLineEdit, QLabel, QComboBox, QSpinBox, QToolButton, QFileDialog from PySide6.QtCore import QTimer from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from PySide6.QtWidgets import QSizePolicy import json class MplCanvas(FigureCanvas): def __init__(self, parent=None, width=5, height=4, dpi=100): self.fig = Figure(figsize=(width, height), dpi=dpi, facecolor='grey') super().__init__(self.fig) self.setParent(parent) self.axes = self.fig.add_subplot(111) # Построим простой график self.axes.plot([0, 1, 2, 3], [10, 1, 20, 3]) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) class SDRClient(QMainWindow): def __init__(self): super().__init__() # Параметры подключения к серверу self.server_ip = '127.0.0.1' self.server_port = 5003 self.sock = None # Параметры для отрисовки self.channel_data = { 'time': np.array([]), 'channel_g': np.array([]), 'channel_rf': np.array([]), 'channel_adc_ttl': np.array([]), 'channel_rf_ttl': np.array([]) } # Настройка окна self.setWindowTitle("SDR Client") self.setGeometry(100, 100, 1280, 720) self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.layout = QHBoxLayout() self.plot_layout = QVBoxLayout() self.menu_layout = QVBoxLayout() self.layout.addLayout(self.menu_layout) self.layout.addLayout(self.plot_layout) self.central_widget.setLayout(self.layout) self.command_layout = QHBoxLayout() self.plot_layout.addLayout(self.command_layout) self.add_event_button = QPushButton("Add Event") self.command_layout.addWidget(self.add_event_button) self.add_rfwave_button = QPushButton("Add RF Wave") self.command_layout.addWidget(self.add_rfwave_button) self.run_event_list_button = QPushButton("Run Event List") self.command_layout.addWidget(self.run_event_list_button) self.clear_event_list_button = QPushButton("Clear Event List") self.command_layout.addWidget(self.clear_event_list_button) self.plot_canvas = MplCanvas(self, width=5, height=4, dpi=100) #self.plot_canvas.setSizePolicy(self.plot_widget.sizePolicy()) self.plot_layout.addWidget(self.plot_canvas, stretch=1) toolbar = NavigationToolbar(self.plot_canvas, self) self.plot_layout.addWidget(toolbar, stretch=1) self.connect_button = QPushButton("Connect to SDR") self.connect_button.setMinimumSize(200, 50) self.disconnect_button = QPushButton("Disconnect") self.disconnect_button.setMinimumSize(200, 50) self.settings_button = QPushButton("Settings") self.settings_button.setMinimumSize(200, 50) self.recv_sim_data_button = QPushButton("Receive Sim Data") self.recv_sim_data_button.setMinimumSize(200, 50) self.menu_layout.addWidget(self.connect_button) self.menu_layout.addWidget(self.disconnect_button) self.menu_layout.addWidget(self.settings_button) self.menu_layout.addWidget(self.recv_sim_data_button) self.connect_button.clicked.connect(self.connect_to_server) self.disconnect_button.clicked.connect(self.disconnect_from_server) self.add_event_button.clicked.connect(self.add_event_dialog) def connect_to_server(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.server_ip, self.server_port)) print(f"Connected to SDR server at {self.server_ip}:{self.server_port}") except Exception as e: print(f"Failed to connect to server: {e}") QMessageBox.critical(self, "Connection Error", f"Failed to connect to server: {e}") self.sock = None def disconnect_from_server(self): if self.sock: self.sock.close() self.sock = None QMessageBox.information(self, "Disconnected", "Successfully disconnected from SDR server") print("Disconnected from SDR server") def add_event_dialog(self): #if not self.sock: # QMessageBox.warning(self, "Not Connected", "Please connect to the SDR server first") # return False add_event_dialog = QDialog(self) add_event_dialog.setWindowTitle("Add Event") layout = QFormLayout() labels = ["Start Time (ticks)", "Duration (ticks)", "Waveform Type", "time_front_rf_ttl (ticks)", "time_back_rf_ttl (ticks)", "time_front_adc_ttl (ticks)", "time_back_adc_ttl (ticks)", "time_start_rf (ticks)", "time_end_rf (ticks)", "rf_freq (Hz)"] self.event_inputs = {} for label in labels: if label == "Waveform Type": combo = QComboBox() combo.addItems(["sine", "square", "triangle"]) layout.addRow(QLabel(label), combo) self.event_inputs[label] = combo else: line_edit = QLineEdit() layout.addRow(QLabel(label), line_edit) self.event_inputs[label] = line_edit submit_button = QPushButton("Submit") layout.addWidget(submit_button) load_event_list_button = QPushButton("Load Event List") layout.addWidget(load_event_list_button) submit_button.clicked.connect(self.submit_event) load_event_list_button.clicked.connect(self.load_event_list) add_event_dialog.setLayout(layout) add_event_dialog.exec() def submit_event(self): try: event_data = { "time": int(self.event_inputs["Start Time (ticks)"].text()), "duration": int(self.event_inputs["Duration (ticks)"].text()), "wave": self.event_inputs["Waveform Type"].currentText(), "time_front_rf_trigger": int(self.event_inputs["time_front_rf_ttl (ticks)"].text()), "time_back_rf_trigger": int(self.event_inputs["time_back_rf_ttl (ticks)"].text()), "time_front_adc_trigger": int(self.event_inputs["time_front_adc_ttl (ticks)"].text()), "time_back_adc_trigger": int(self.event_inputs["time_back_adc_ttl (ticks)"].text()), "rf_start": int(self.event_inputs["time_start_rf (ticks)"].text()), "rf_end": int(self.event_inputs["time_end_rf (ticks)"].text()), "carrier_freq": float(self.event_inputs["rf_freq (Hz)"].text()) } msg = msgpack.packb({"command": 0x10, "data": event_data}) self.sock.sendall(msg) print("Event added successfully") QMessageBox.information(self, "Success", "Event added successfully") self.add_event_dialog.close() except Exception as e: print(f"Failed to add event: {e}") QMessageBox.critical(self, "Error", f"Failed to add event: {e}") def load_event_list(self): file_dialog = QFileDialog(self) file_dialog.setNameFilter("JSON Files (*.json)") if file_dialog.exec(): selected_file = file_dialog.selectedFiles()[0] try: with open(selected_file, 'r') as f: event_list = json.load(f) for event_data in event_list: msg = { "magic": 0xAA, "cmd": 0x10, "time": event_data["time"], "duration": event_data["duration"], "wave": event_data["wave"], "time_front_rf_trigger": event_data["time_front_rf_trigger"], "time_back_rf_trigger": event_data["time_back_rf_trigger"], "time_front_adc_trigger": event_data["time_front_adc_trigger"], "time_back_adc_trigger": event_data["time_back_adc_trigger"], "rf_start": event_data["rf_start"], "rf_end": event_data["rf_end"], "carrier_freq": event_data["carrier_freq"] } packed_msg = msgpack.packb(msg, use_bin_type=True) self.sock.sendall(packed_msg) resp = self.sock.recv(1024) if not resp: raise Exception("No response from server") unpacked_resp = msgpack.unpackb(resp, raw=False) if unpacked_resp["cmd"] != 0xFE and unpacked_resp["code"] != 0x00000010: raise Exception(f"Server error: {unpacked_resp['message']}") print("Event list loaded successfully") QMessageBox.information(self, "Success", "Event list loaded successfully") self.add_event_dialog.close() except Exception as e: print(f"Failed to load event list: {e}") QMessageBox.critical(self, "Error", f"Failed to load event list: {e}") app = QApplication([]) client = SDRClient() client.show() #plt.ion() # Enable interactive mode for plotting #plt.show() app.exec()