Files
esa-remote-lite/WebSocketController.cpp

207 lines
6.4 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 <QUrl>
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 *panel) { m_versionsPanel = panel; }
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("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 ----
// Response: LOG name1 name2* name3 ... (* = enabled)
if (cmd == "LOG" && tokens.size() > 1 && m_logPanel) {
// Only handle the full list response (no '=' in any token)
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 list
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);
}