211 lines
6.6 KiB
C++
211 lines
6.6 KiB
C++
#include "WebSocketController.h"
|
|
#include "GamesPanel.h"
|
|
#include "LogPanel.h"
|
|
#include "PowerPanel.h"
|
|
#include "SettingsTree.h"
|
|
#include "VersionsPanel.h"
|
|
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QTextEdit>
|
|
#include <QAbstractSocket>
|
|
|
|
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);
|
|
}
|