#include "WebSocketController.h" #include "GamesPanel.h" #include "LogPanel.h" #include "PowerPanel.h" #include "SettingsTree.h" #include "VersionsPanel.h" #include #include #include #include WebSocketController::WebSocketController(QLineEdit *urlEdit, QLabel *statusLabel, QObject *parent) : QObject(parent), m_urlEdit(urlEdit), m_statusLabel(statusLabel) {} QWebSocket *WebSocketController::socket() { return &m_socket; } void WebSocketController::addLogView(QTextEdit *log) { m_logs.append(log); } void WebSocketController::setSettingsTree(SettingsTree *tree) { m_settingsTree = tree; connect(tree, &SettingsTree::valueEdited, this, &WebSocketController::onValueEdited); } void WebSocketController::setGamesPanel(GamesPanel *panel) { m_gamesPanel = panel; } void WebSocketController::setVersionsPanel(VersionsPanel *p) { m_versionsPanel = p; } void WebSocketController::setPowerPanel(PowerPanel *panel) { m_powerPanel = panel; } void WebSocketController::setLogPanel(LogPanel *panel) { m_logPanel = panel; } bool WebSocketController::isConnected() const { return m_socket.state() == QAbstractSocket::ConnectedState; } void WebSocketController::startConnection() { const QUrl url(m_urlEdit->text().trimmed()); if (!url.isValid()) { broadcast("Invalid URL"); return; } broadcast(QString("Connecting to %1").arg(url.toString())); m_statusLabel->setText("Connecting..."); m_socket.open(url); } void WebSocketController::closeConnection() { broadcast("Closing connection"); m_settingsKeys.clear(); m_rnpCount = -1; if (m_versionsPanel) m_versionsPanel->reset(); if (m_powerPanel) m_powerPanel->reset(); m_socket.close(); } void WebSocketController::sendCommand(const QString &cmd) { if (!isConnected()) { broadcast("[not connected]"); return; } m_socket.sendTextMessage(cmd); broadcast(QString("TX: %1").arg(cmd)); } void WebSocketController::onConnected() { broadcast("Connected"); m_statusLabel->setText("Connected"); m_rnpCount = -1; sendCommand(QStringLiteral("GBL List")); sendCommand(QStringLiteral("GAM list")); sendCommand(QStringLiteral("GAM listall")); // <-- fetch full catalogue sendCommand(QStringLiteral("NAM")); sendCommand(QStringLiteral("VER")); sendCommand(QStringLiteral("UID")); sendCommand(QStringLiteral("RNP")); sendCommand(QStringLiteral("#P0-P STA")); sendCommand(QStringLiteral("#P0-P RTV")); sendCommand(QStringLiteral("#P0-P VTG")); sendCommand(QStringLiteral("LOG")); } void WebSocketController::onDisconnected() { broadcast("Disconnected"); m_statusLabel->setText("Disconnected"); m_settingsKeys.clear(); m_rnpCount = -1; } void WebSocketController::onTextMessageReceived(const QString &msg) { broadcast(QString("RX: %1").arg(msg)); handleProtocol(msg); } void WebSocketController::onErrorOccurred(QAbstractSocket::SocketError) { broadcast(QString("Error: %1").arg(m_socket.errorString())); m_statusLabel->setText("Error"); } void WebSocketController::onValueEdited(const QString &key, const QString &newValue) { sendCommand(QString("GBL %1=%2").arg(key, newValue)); sendCommand(QString("GBL %1").arg(key)); } void WebSocketController::handleProtocol(const QString &msg) { const QStringList tokens = msg.split(' ', Qt::SkipEmptyParts); if (tokens.isEmpty()) return; const QString cmd = tokens[0]; // ---- Power: #P0-P STA/RTV/VTG ---- if (cmd == "#P0-P" && tokens.size() >= 2 && m_powerPanel) { const QString sub = tokens[1]; if (sub == "STA" && tokens.size() >= 3) m_powerPanel->setStatus(tokens[2]); else if (sub == "RTV" && tokens.size() >= 3) m_powerPanel->setRatedVoltage(tokens[2]); else if (sub == "VTG" && tokens.size() >= 3) m_powerPanel->setVoltages(tokens.mid(2)); return; } // ---- LOG channel list ---- if (cmd == "LOG" && tokens.size() > 1 && m_logPanel) { bool isList = true; for (int i = 1; i < tokens.size(); ++i) if (tokens[i].contains('=')) { isList = false; break; } if (isList) m_logPanel->applyLogResponse(msg); return; } // ---- NAM ---- if (cmd == "NAM" && tokens.size() >= 2) { if (m_versionsPanel) m_versionsPanel->setDeviceName(tokens[1]); return; } // ---- VER ---- if (cmd == "VER" && tokens.size() >= 3) { if (m_versionsPanel) m_versionsPanel->setVersion(tokens[1], tokens.mid(2).join(' ')); return; } // ---- UID ---- if (cmd == "UID" && tokens.size() >= 3) { if (m_versionsPanel) m_versionsPanel->setUid(tokens[1], tokens.mid(2).join(' ')); return; } // ---- RNP ---- if (cmd == "RNP" && tokens.size() >= 2) { bool ok = false; const int count = tokens[1].toInt(&ok); if (ok && count > 0) { m_rnpCount = count; if (m_versionsPanel) m_versionsPanel->setRnpCount(count); for (int i = 0; i < count; ++i) { sendCommand(QString("VER %1").arg(i)); sendCommand(QString("UID %1").arg(i)); } } return; } // ---- GAM listall — full catalogue ---- if (cmd == "GAM" && tokens.size() >= 2 && tokens[1] == "listall") { if (m_gamesPanel) m_gamesPanel->loadAllFromResponse(msg); return; } // ---- GAM list — installed games ---- if (cmd == "GAM" && tokens.size() >= 2 && tokens[1] == "list") { if (m_gamesPanel) m_gamesPanel->loadFromResponse(msg); return; } // ---- GBL List key1 key2 ... ---- if (cmd == "GBL" && tokens.size() > 2 && tokens[1] == "List") { m_settingsKeys = tokens.mid(2); if (m_settingsTree) { m_settingsTree->loadKeys(m_settingsKeys); for (const QString &key : m_settingsKeys) sendCommand(QString("GBL %1").arg(key)); } return; } // ---- GBL key=value ---- if (cmd == "GBL" && tokens.size() >= 2 && m_settingsTree) { const QString payload = tokens[1]; const int eqIdx = payload.indexOf('='); if (eqIdx > 0) { const QString key = payload.left(eqIdx); QString value = payload.mid(eqIdx + 1); if (tokens.size() > 2) value += ' ' + tokens.mid(2).join(' '); m_settingsTree->setValue(key, value); } } } void WebSocketController::broadcast(const QString &line) { for (auto *log : m_logs) log->append(line); }