#include "hyperionclient.h" #include #include #include int HyperionClient::_idCounter = 0; // public HyperionClient::HyperionClient(QString host, ushort port, QString priority) { _sock_p = new QTcpSocket(this); // _sock_p->setReadBufferSize(1); // Commented out _host_m = host; _port_m = port; _priority_m = priority; connect(_sock_p, &QTcpSocket::connected, this, &HyperionClient::_connected); connect(_sock_p, &QTcpSocket::disconnected, this, &HyperionClient::_disconnected); connect(_sock_p, &QTcpSocket::readyRead, this, &HyperionClient::_readyRead); connect(_sock_p, &QTcpSocket::errorOccurred, this, &HyperionClient::_socketError); // Connect error signal _connectHost(); qDebug() << "HyperionClient: Connection attempt initiated."; } HyperionClient::~HyperionClient() { qDebug() << "HyperionClient destructor called."; clearLeds(); if (_sock_p->state() == QAbstractSocket::ConnectedState) { while(_sock_p->waitForBytesWritten()) {} _sock_p->disconnectFromHost(); } delete _sock_p; } void HyperionClient::clearLeds() { _cmd_m.clear(); _cmd_m.append("{\"command\": \"clearall\",\"priority\":").append(_priority_m.toUtf8()).append("}\n"); _sendCommand(); } void HyperionClient::setLedColor(quint8 R, quint8 G, quint8 B) { _cmd_m.clear(); _cmd_m.append("{\"color\":["); _cmd_m.append(QString::number(R).toUtf8()); _cmd_m.append(","); _cmd_m.append(QString::number(G).toUtf8()); _cmd_m.append(","); _cmd_m.append(QString::number(B).toUtf8()); _cmd_m.append("],\"command\":\"color\",\"priority\":").append(_priority_m.toUtf8()).append("}\n"); _sendCommand(); } void HyperionClient::ledAdjustments(QString red, QString green, QString blue, QString temp, QString thres, QString trans) { _redAdjust_m = red; _greenAdjust_m = green; _blueAdjust_m = blue; _temperature_m = temp; _threshold_m = thres; _transform_m = trans; _ledAdjustments(); } // private void HyperionClient::_connectHost() { _sock_p->connectToHost(_host_m, _port_m); } void HyperionClient::_sendCommand() { if (_sock_p->state() == QAbstractSocket::ConnectedState) { qDebug() << "_sendCommand() called. Command size: " << _cmd_m.size() << ", Data: " << _cmd_m.left(1000) << "..."; _sock_p->write(_cmd_m); while (_sock_p->bytesToWrite()) { _sock_p->waitForBytesWritten(); } } else { qWarning() << "Socket not connected. Cannot send command."; } } void HyperionClient::_ledAdjustments() { _colorAdjustmentType_m = 0; if (_redAdjust_m != "") { _colorAdjustmentType_m |= REDADJUST; } if (_greenAdjust_m != "") { _colorAdjustmentType_m |= GREENADJUST; } if (_blueAdjust_m != "") { _colorAdjustmentType_m |= BLUEADJUST; } _colorAdjustment(); _thresholdAdjustment(); _transformdAdjustment(); } void HyperionClient::_colorAdjustment() { if (!_colorAdjustmentType_m) { return; } _cmd_m.clear(); _cmd_m.append("{\"adjustment\":{"); if (_colorAdjustmentType_m & REDADJUST) { _cmd_m.append("\"redAdjust\":"); _cmd_m.append(_redAdjust_m.toUtf8()); _cmd_m.append(","); } if (_colorAdjustmentType_m & GREENADJUST) { _cmd_m.append("\"greenAdjust\":"); _cmd_m.append(_greenAdjust_m.toUtf8()); _cmd_m.append(","); } if (_colorAdjustmentType_m & BLUEADJUST) { _cmd_m.append("\"blueAdjust\":"); _cmd_m.append(_blueAdjust_m.toUtf8()); _cmd_m.append(","); } _cmd_m.chop(1); // remove trailing , _cmd_m.append("},\"command\":\"adjustment\",\"priority\":").append(_priority_m.toUtf8()).append("\n"); } void HyperionClient::_thresholdAdjustment() { if (_threshold_m == "") { return; } _cmd_m.clear(); _cmd_m.append("{\"command\":\"transform\",\"priority\":").append(_priority_m.toUtf8()).append(",\"transform\":{\"threshold\":"); _cmd_m.append(_threshold_m.toUtf8()); _cmd_m.append("}}\n"); _sendCommand(); } void HyperionClient::_transformdAdjustment() { if (_transform_m == "") { return; } QStringList values = _transform_m.split(','); _cmd_m.clear(); _cmd_m.append("{\"command\":\"transform\",\"priority\":").append(_priority_m.toUtf8()).append(",\"transform\":{\"luminanceGain\":"); _cmd_m.append(values.at(0).toUtf8()); _cmd_m.append(",\"luminanceMinimum\":"); _cmd_m.append(values.at(1).toUtf8()); _cmd_m.append(",\"saturationGain\":"); _cmd_m.append(values.at(2).toUtf8()); _cmd_m.append("}}\n"); _sendCommand(); } void HyperionClient::_temperatureAdjustment() { if (_temperature_m == "") { return; } _cmd_m.clear(); _cmd_m.append("{\"command\":\"temperature\",\"priority\":"); _cmd_m.append(_temperature_m.toUtf8()); _cmd_m.append("}}\n"); _sendCommand(); } // public slots void HyperionClient::sendImage(const uchar *data, int size) { QJsonObject fullCommand; fullCommand["command"] = "image"; fullCommand["id"] = ++_idCounter; QJsonDocument paramsDoc = QJsonDocument::fromJson(imgCmdBuf); QJsonObject paramsObject = paramsDoc.object(); paramsObject["imagedata"] = QString(QByteArray::fromRawData(reinterpret_cast(data), size).toBase64()); fullCommand["params"] = paramsObject; _cmd_m = QJsonDocument(fullCommand).toJson(QJsonDocument::Compact); _cmd_m.append("\n"); // Add newline terminator qDebug() << "Sending image command: " << _cmd_m.left(500) << "..."; // Log first 500 chars _sendCommand(); } void HyperionClient::setImgSize(int width, int height) { QJsonObject params; params["priority"] = _priority_m.toInt(); params["imageheight"] = height; params["imagewidth"] = width; QJsonDocument doc(params); imgCmdBuf = doc.toJson(QJsonDocument::Compact).chopped(1); // Remove trailing '}' imgCmdBuf.append(",\"imagedata\":\""); } // private slots void HyperionClient::_connected() { qDebug() << "Successfully connected to Hyperion server at" << _host_m << ":" << _port_m; _ledAdjustments(); // Send initial adjustments after connection emit clientConnected(); // Emit signal } void HyperionClient::_disconnected() { qDebug() << "Disconnected from Hyperion server. Attempting to reconnect in 5 seconds..."; QTimer::singleShot(5000, this, &HyperionClient::_connectHost); // Reconnect after a delay } void HyperionClient::_readyRead() { QByteArray data = _sock_p->readAll(); qDebug() << "Received from Hyperion:" << data; } void HyperionClient::_socketError(QAbstractSocket::SocketError socketError) { Q_UNUSED(socketError); qWarning() << "Socket Error:" << _sock_p->errorString(); }