mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Remove max LED number constraint from Matrix layout (#1805)
This commit is contained in:
parent
e8e102c25d
commit
179ee316d0
@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Allow to force starting Hyperion in read-only mode (`--readonlyMode`)
|
- Allow to force starting Hyperion in read-only mode (`--readonlyMode`)
|
||||||
- JSON-API: Support to query for a dedicated set of configuration items for a set of instances
|
- JSON-API: Support to query for a dedicated set of configuration items for a set of instances
|
||||||
- JSON-API: Support to save a dedicated set of configuration items for a set of instances
|
- JSON-API: Support to save a dedicated set of configuration items for a set of instances
|
||||||
|
- JSON-API: Limit update emission frequency: Images (25Hz), raw LED-Colors (40Hz) & LED-Device data (200Hz)
|
||||||
|
- Effects: Limit the maximum update rate to 200Hz
|
||||||
|
|
||||||
**JSON-API**
|
**JSON-API**
|
||||||
- New subscription support for event updates, i.e. `Suspend, Resume, Idle, idleResume, Restart, Quit`.
|
- New subscription support for event updates, i.e. `Suspend, Resume, Idle, idleResume, Restart, Quit`.
|
||||||
@ -44,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Refactored: Python to enable parallel effect processing under Python 3.12
|
- Refactored: Python to enable parallel effect processing under Python 3.12
|
||||||
- Fixed: Python 3.12 crashes (#1747)
|
- Fixed: Python 3.12 crashes (#1747)
|
||||||
- osX Grabber: Use ScreenCaptureKit under macOS 15 and above
|
- osX Grabber: Use ScreenCaptureKit under macOS 15 and above
|
||||||
|
- Removed maximum LED number constraint from Matrix layout schema which was not synced with the UI behaviour (#1804)
|
||||||
|
|
||||||
**JSON-API**
|
**JSON-API**
|
||||||
- Refactored JSON-API to ensure consistent authorization behaviour across sessions and single requests with token authorization.
|
- Refactored JSON-API to ensure consistent authorization behaviour across sessions and single requests with token authorization.
|
||||||
|
@ -20,6 +20,9 @@ brightness = float(hyperion.args.get('brightness', 100))/100.0
|
|||||||
|
|
||||||
sleepTime = float(hyperion.args.get('sleepTime', 0.14))
|
sleepTime = float(hyperion.args.get('sleepTime', 0.14))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
candles = hyperion.args.get('candles', "all")
|
candles = hyperion.args.get('candles', "all")
|
||||||
ledlist = hyperion.args.get('ledlist', "1")
|
ledlist = hyperion.args.get('ledlist', "1")
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@ cropBottom = int(hyperion.args.get('cropBottom', 0))
|
|||||||
grayscale = bool(hyperion.args.get('grayscale', False))
|
grayscale = bool(hyperion.args.get('grayscale', False))
|
||||||
|
|
||||||
sleepTime = 1./framesPerSecond
|
sleepTime = 1./framesPerSecond
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
imageFrameList = []
|
imageFrameList = []
|
||||||
|
|
||||||
if imageData:
|
if imageData:
|
||||||
|
@ -4,6 +4,9 @@ import time
|
|||||||
# Get parameters
|
# Get parameters
|
||||||
sleepTime = float(hyperion.args.get('sleepTime', 0.5))
|
sleepTime = float(hyperion.args.get('sleepTime', 0.5))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
def TestRgb( iteration ):
|
def TestRgb( iteration ):
|
||||||
|
|
||||||
switcher = {
|
switcher = {
|
||||||
|
@ -11,6 +11,9 @@ sleepTime = float(hyperion.args.get('sleepTime', 0.5))
|
|||||||
testleds = hyperion.args.get('testleds', "all")
|
testleds = hyperion.args.get('testleds', "all")
|
||||||
ledlist = hyperion.args.get('ledlist', "1")
|
ledlist = hyperion.args.get('ledlist', "1")
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
testlist = ()
|
testlist = ()
|
||||||
if (testleds == "list") and (type(ledlist) is str):
|
if (testleds == "list") and (type(ledlist) is str):
|
||||||
for s in ledlist.split(','):
|
for s in ledlist.split(','):
|
||||||
|
@ -6,6 +6,9 @@ width = hyperion.imageWidth()
|
|||||||
height = hyperion.imageHeight()
|
height = hyperion.imageHeight()
|
||||||
sleepTime = float(hyperion.args.get('sleepTime', 0.2))
|
sleepTime = float(hyperion.args.get('sleepTime', 0.2))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
def mapto(x, in_min, in_max, out_min, out_max):
|
def mapto(x, in_min, in_max, out_min, out_max):
|
||||||
return float((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
|
return float((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
|
||||||
|
|
||||||
|
@ -4,8 +4,11 @@ import hyperion, time
|
|||||||
sleepTime = float(hyperion.args.get('speed', 1.5)) * 0.005
|
sleepTime = float(hyperion.args.get('speed', 1.5)) * 0.005
|
||||||
whiteLevel = int(hyperion.args.get('whiteLevel', 0))
|
whiteLevel = int(hyperion.args.get('whiteLevel', 0))
|
||||||
lvl = int(hyperion.args.get('colorLevel', 220))
|
lvl = int(hyperion.args.get('colorLevel', 220))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
# check value
|
# check value
|
||||||
whiteLevel = min( whiteLevel, 254 )
|
whiteLevel = min( whiteLevel, 254 )
|
||||||
lvl = min( lvl, 255 )
|
lvl = min( lvl, 255 )
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ height = 10
|
|||||||
|
|
||||||
imageData = bytearray(height * width * (0,0,0))
|
imageData = bytearray(height * width * (0,0,0))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
# Start the write data loop
|
# Start the write data loop
|
||||||
if initialBlink:
|
if initialBlink:
|
||||||
for i in range(6):
|
for i in range(6):
|
||||||
|
@ -8,6 +8,9 @@ saturation = float(hyperion.args.get('saturation', 100))/100.0
|
|||||||
color = list(hyperion.args.get('color', (255,255,255)))
|
color = list(hyperion.args.get('color', (255,255,255)))
|
||||||
randomColor = bool(hyperion.args.get('random-color', False))
|
randomColor = bool(hyperion.args.get('random-color', False))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
# Check parameters
|
# Check parameters
|
||||||
rotationTime = max(0.1, rotationTime)
|
rotationTime = max(0.1, rotationTime)
|
||||||
|
|
||||||
|
@ -22,7 +22,10 @@ def getPoint(rand = True ,x = 0.5, y = 0.5):
|
|||||||
def getSTime(rt, steps = 360):
|
def getSTime(rt, steps = 360):
|
||||||
rt = float(rt)
|
rt = float(rt)
|
||||||
sleepTime = max(0.1, rt) / steps
|
sleepTime = max(0.1, rt) / steps
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
# adapt sleeptime to hardware
|
# adapt sleeptime to hardware
|
||||||
minStepTime= float(hyperion.latchTime)/1000.0
|
minStepTime= float(hyperion.latchTime)/1000.0
|
||||||
if minStepTime == 0: minStepTime = 0.001
|
if minStepTime == 0: minStepTime = 0.001
|
||||||
|
@ -10,6 +10,9 @@ minStepTime = float(hyperion.latchTime)/1000.0
|
|||||||
if minStepTime == 0: minStepTime = 0.001
|
if minStepTime == 0: minStepTime = 0.001
|
||||||
factor = 1 if sleepTime > minStepTime else int(math.ceil(minStepTime/sleepTime))
|
factor = 1 if sleepTime > minStepTime else int(math.ceil(minStepTime/sleepTime))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
runners = [
|
runners = [
|
||||||
{ "i":0, "pos":0, "c":0, "step":9, "lvl":255},
|
{ "i":0, "pos":0, "c":0, "step":9, "lvl":255},
|
||||||
{ "i":1, "pos":0, "c":0, "step":8, "lvl":255},
|
{ "i":1, "pos":0, "c":0, "step":8, "lvl":255},
|
||||||
|
@ -11,7 +11,10 @@ sleepTime = float(hyperion.args.get('speed', 1)) / 1000.0
|
|||||||
color = list(hyperion.args.get('color', (255,255,255)))
|
color = list(hyperion.args.get('color', (255,255,255)))
|
||||||
randomise = bool(hyperion.args.get('random', False))
|
randomise = bool(hyperion.args.get('random', False))
|
||||||
iWidth = hyperion.imageWidth()
|
iWidth = hyperion.imageWidth()
|
||||||
iHeight = hyperion.imageHeight()
|
iHeight = hyperion.imageHeight()
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
class trail:
|
class trail:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -4,7 +4,10 @@ import hyperion, time
|
|||||||
sleepTime = float(hyperion.args.get('sleepTime', 1000))/1000.0
|
sleepTime = float(hyperion.args.get('sleepTime', 1000))/1000.0
|
||||||
length = hyperion.args.get('length', 1)
|
length = hyperion.args.get('length', 1)
|
||||||
color1 = hyperion.args.get('color1', (255,255,255))
|
color1 = hyperion.args.get('color1', (255,255,255))
|
||||||
color2 = hyperion.args.get('color2', (255,0,0))
|
color2 = hyperion.args.get('color2', (255,0,0))
|
||||||
|
|
||||||
|
# Limit update rate
|
||||||
|
sleepTime = max(hyperion.lowestUpdateInterval(), sleepTime)
|
||||||
|
|
||||||
# Initialize the led data
|
# Initialize the led data
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -50,6 +50,8 @@ public:
|
|||||||
///
|
///
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
|
QSharedPointer<JsonCallbacks> getCallBack() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -82,7 +84,7 @@ signals:
|
|||||||
///
|
///
|
||||||
/// Signal emits with the reply message provided with handleMessage()
|
/// Signal emits with the reply message provided with handleMessage()
|
||||||
///
|
///
|
||||||
void callbackMessage(QJsonObject);
|
void callbackReady(QJsonObject);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Signal emits whenever a JSON-message should be forwarded
|
/// Signal emits whenever a JSON-message should be forwarded
|
||||||
|
@ -93,7 +93,7 @@ signals:
|
|||||||
/// @brief Emits whenever a new json mesage callback is ready to send
|
/// @brief Emits whenever a new json mesage callback is ready to send
|
||||||
/// @param The JsonObject message
|
/// @param The JsonObject message
|
||||||
///
|
///
|
||||||
void newCallback(QJsonObject);
|
void callbackReady(QJsonObject);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
///
|
///
|
||||||
@ -182,6 +182,8 @@ private:
|
|||||||
|
|
||||||
/// construct callback msg
|
/// construct callback msg
|
||||||
void doCallback(Subscription::Type cmd, const QVariant& data);
|
void doCallback(Subscription::Type cmd, const QVariant& data);
|
||||||
|
void doCallback(Subscription::Type cmd, const QJsonArray& data);
|
||||||
|
void doCallback(Subscription::Type cmd, const QJsonObject& data);
|
||||||
|
|
||||||
Logger *_log;
|
Logger *_log;
|
||||||
Hyperion* _hyperion;
|
Hyperion* _hyperion;
|
||||||
|
@ -103,4 +103,6 @@ private:
|
|||||||
QImage _image;
|
QImage _image;
|
||||||
QPainter* _painter;
|
QPainter* _painter;
|
||||||
QVector<QImage> _imageStack;
|
QVector<QImage> _imageStack;
|
||||||
|
|
||||||
|
double _lowestUpdateIntervalInSeconds;
|
||||||
};
|
};
|
||||||
|
@ -21,28 +21,29 @@ public:
|
|||||||
|
|
||||||
// Wrapper methods for Python interpreter extra buildin methods
|
// Wrapper methods for Python interpreter extra buildin methods
|
||||||
static PyMethodDef effectMethods[];
|
static PyMethodDef effectMethods[];
|
||||||
static PyObject* wrapSetColor(PyObject* self, PyObject* args);
|
static PyObject* wrapSetColor (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapSetImage(PyObject* self, PyObject* args);
|
static PyObject* wrapSetImage (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapGetImage(PyObject* self, PyObject* args);
|
static PyObject* wrapGetImage (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapAbort(PyObject* self, PyObject* args);
|
static PyObject* wrapAbort (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageShow(PyObject* self, PyObject* args);
|
static PyObject* wrapImageShow (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageLinearGradient(PyObject* self, PyObject* args);
|
static PyObject* wrapImageLinearGradient (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageConicalGradient(PyObject* self, PyObject* args);
|
static PyObject* wrapImageConicalGradient (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageRadialGradient(PyObject* self, PyObject* args);
|
static PyObject* wrapImageRadialGradient (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageSolidFill(PyObject* self, PyObject* args);
|
static PyObject* wrapImageSolidFill (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageDrawLine(PyObject* self, PyObject* args);
|
static PyObject* wrapImageDrawLine (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageDrawPoint(PyObject* self, PyObject* args);
|
static PyObject* wrapImageDrawPoint (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageDrawRect(PyObject* self, PyObject* args);
|
static PyObject* wrapImageDrawRect (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageDrawPolygon(PyObject* self, PyObject* args);
|
static PyObject* wrapImageDrawPolygon (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageDrawPie(PyObject* self, PyObject* args);
|
static PyObject* wrapImageDrawPie (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageSetPixel(PyObject* self, PyObject* args);
|
static PyObject* wrapImageSetPixel (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageGetPixel(PyObject* self, PyObject* args);
|
static PyObject* wrapImageGetPixel (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageSave(PyObject* self, PyObject* args);
|
static PyObject* wrapImageSave (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageMinSize(PyObject* self, PyObject* args);
|
static PyObject* wrapImageMinSize (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageWidth(PyObject* self, PyObject* args);
|
static PyObject* wrapImageWidth (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageHeight(PyObject* self, PyObject* args);
|
static PyObject* wrapImageHeight (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageCRotate(PyObject* self, PyObject* args);
|
static PyObject* wrapImageCRotate (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageCOffset(PyObject* self, PyObject* args);
|
static PyObject* wrapImageCOffset (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageCShear(PyObject* self, PyObject* args);
|
static PyObject* wrapImageCShear (PyObject *self, PyObject *args);
|
||||||
static PyObject* wrapImageResetT(PyObject* self, PyObject* args);
|
static PyObject* wrapImageResetT (PyObject *self, PyObject *args);
|
||||||
|
static PyObject* wrapLowestUpdateInterval (PyObject* self, PyObject* args);
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
// stl includes
|
// stl includes
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
// QT includes
|
// QT includes
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@ -11,6 +12,7 @@
|
|||||||
#include <QJsonValue>
|
#include <QJsonValue>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
// hyperion-utils includes
|
// hyperion-utils includes
|
||||||
#include <utils/Image.h>
|
#include <utils/Image.h>
|
||||||
@ -604,4 +606,14 @@ private:
|
|||||||
/// Boblight instance
|
/// Boblight instance
|
||||||
BoblightServer* _boblightServer;
|
BoblightServer* _boblightServer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QElapsedTimer _imageTimer; // Timer for controlling image emission frequency
|
||||||
|
QElapsedTimer _rawLedDataTimer; // Timer for controlling rawLedColors emission frequency
|
||||||
|
QElapsedTimer _ledDeviceDataTimer; // Timer for controlling LedDevice data emission frequency
|
||||||
|
qint64 _lastImageEmission; // Last timestamp of image signal emission
|
||||||
|
qint64 _lastRawLedDataEmission; // Last timestamp of rawLedColors signal emission
|
||||||
|
qint64 _lastLedDeviceDataEmission; // Last timestamp of ledDeviceData signal emission
|
||||||
|
std::chrono::milliseconds _imageEmissionInterval;
|
||||||
|
std::chrono::milliseconds _rawLedDataEmissionInterval;
|
||||||
|
std::chrono::milliseconds _ledDeviceDataEmissionInterval;
|
||||||
};
|
};
|
||||||
|
@ -85,6 +85,11 @@ JsonAPI::JsonAPI(QString peerAddress, Logger *log, bool localConnection, QObject
|
|||||||
_jsonCB = QSharedPointer<JsonCallbacks>(new JsonCallbacks( _log, _peerAddress, parent));
|
_jsonCB = QSharedPointer<JsonCallbacks>(new JsonCallbacks( _log, _peerAddress, parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSharedPointer<JsonCallbacks> JsonAPI::getCallBack() const
|
||||||
|
{
|
||||||
|
return _jsonCB;
|
||||||
|
}
|
||||||
|
|
||||||
void JsonAPI::initialize()
|
void JsonAPI::initialize()
|
||||||
{
|
{
|
||||||
// init API, REQUIRED!
|
// init API, REQUIRED!
|
||||||
@ -97,9 +102,6 @@ void JsonAPI::initialize()
|
|||||||
// listen for killed instances
|
// listen for killed instances
|
||||||
connect(_instanceManager, &HyperionIManager::instanceStateChanged, this, &JsonAPI::handleInstanceStateChange);
|
connect(_instanceManager, &HyperionIManager::instanceStateChanged, this, &JsonAPI::handleInstanceStateChange);
|
||||||
|
|
||||||
// pipe callbacks from subscriptions to parent
|
|
||||||
connect(_jsonCB.data(), &JsonCallbacks::newCallback, this, &JsonAPI::callbackMessage);
|
|
||||||
|
|
||||||
// notify hyperion about a jsonMessageForward
|
// notify hyperion about a jsonMessageForward
|
||||||
if (_hyperion != nullptr)
|
if (_hyperion != nullptr)
|
||||||
{
|
{
|
||||||
@ -1537,7 +1539,7 @@ void JsonAPI::sendSuccessReply(const JsonApiCommand& cmd)
|
|||||||
|
|
||||||
void JsonAPI::sendSuccessReply(const QString &command, int tan, InstanceCmd::Type isInstanceCmd)
|
void JsonAPI::sendSuccessReply(const QString &command, int tan, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
emit callbackMessage(getBasicCommandReply(true, command, tan , isInstanceCmd));
|
emit callbackReady(getBasicCommandReply(true, command, tan , isInstanceCmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
||||||
@ -1572,7 +1574,7 @@ void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QS
|
|||||||
reply["errorData"] = errorsArray;
|
reply["errorData"] = errorsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit callbackMessage(reply);
|
emit callbackReady(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd)
|
void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd)
|
||||||
@ -1601,7 +1603,7 @@ void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetai
|
|||||||
reply["errorData"] = errorsArray;
|
reply["errorData"] = errorsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit callbackMessage(reply);
|
emit callbackReady(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
||||||
@ -1621,7 +1623,7 @@ void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command,
|
|||||||
|
|
||||||
request["info"] = infoData;
|
request["info"] = infoData;
|
||||||
|
|
||||||
emit callbackMessage(request);
|
emit callbackReady(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendNoAuthorization(const JsonApiCommand& cmd)
|
void JsonAPI::sendNoAuthorization(const JsonApiCommand& cmd)
|
||||||
|
@ -282,22 +282,43 @@ QStringList JsonCallbacks::getSubscribedCommands() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data)
|
void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data)
|
||||||
|
{
|
||||||
|
if (data.userType() == QMetaType::QJsonArray)
|
||||||
|
{
|
||||||
|
doCallback(cmd, data.toJsonArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doCallback(cmd, data.toJsonObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonCallbacks::doCallback(Subscription::Type cmd, const QJsonArray& data)
|
||||||
{
|
{
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
obj["command"] = Subscription::toString(cmd);
|
obj["command"] = Subscription::toString(cmd);
|
||||||
|
|
||||||
if (Subscription::isInstanceSpecific(cmd))
|
if (Subscription::isInstanceSpecific(cmd))
|
||||||
{
|
{
|
||||||
obj["instance"] = _hyperion->getInstanceIndex();
|
obj.insert("instance", _hyperion->getInstanceIndex());
|
||||||
}
|
}
|
||||||
|
obj.insert("data", data);
|
||||||
|
|
||||||
if (data.userType() == QMetaType::QJsonArray) {
|
emit callbackReady(obj);
|
||||||
obj["data"] = data.toJsonArray();
|
}
|
||||||
} else {
|
|
||||||
obj["data"] = data.toJsonObject();
|
void JsonCallbacks::doCallback(Subscription::Type cmd, const QJsonObject& data)
|
||||||
|
{
|
||||||
|
QJsonObject obj;
|
||||||
|
obj["command"] = Subscription::toString(cmd);
|
||||||
|
|
||||||
|
if (Subscription::isInstanceSpecific(cmd))
|
||||||
|
{
|
||||||
|
obj.insert("instance", _hyperion->getInstanceIndex());
|
||||||
}
|
}
|
||||||
|
obj.insert("data", data);
|
||||||
|
|
||||||
emit newCallback(obj);
|
emit callbackReady(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleComponentState(hyperion::Components comp, bool state)
|
void JsonCallbacks::handleComponentState(hyperion::Components comp, bool state)
|
||||||
@ -306,7 +327,7 @@ void JsonCallbacks::handleComponentState(hyperion::Components comp, bool state)
|
|||||||
data["name"] = componentToIdString(comp);
|
data["name"] = componentToIdString(comp);
|
||||||
data["enabled"] = state;
|
data["enabled"] = state;
|
||||||
|
|
||||||
doCallback(Subscription::ComponentsUpdate, QVariant(data));
|
doCallback(Subscription::ComponentsUpdate, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handlePriorityUpdate(int currentPriority, const PriorityMuxer::InputsMap& activeInputs)
|
void JsonCallbacks::handlePriorityUpdate(int currentPriority, const PriorityMuxer::InputsMap& activeInputs)
|
||||||
@ -315,7 +336,7 @@ void JsonCallbacks::handlePriorityUpdate(int currentPriority, const PriorityMuxe
|
|||||||
data["priorities"] = JsonInfo::getPrioritiestInfo(currentPriority, activeInputs);
|
data["priorities"] = JsonInfo::getPrioritiestInfo(currentPriority, activeInputs);
|
||||||
data["priorities_autoselect"] = _hyperion->sourceAutoSelectEnabled();
|
data["priorities_autoselect"] = _hyperion->sourceAutoSelectEnabled();
|
||||||
|
|
||||||
doCallback(Subscription::PrioritiesUpdate, QVariant(data));
|
doCallback(Subscription::PrioritiesUpdate, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleImageToLedsMappingChange(int mappingType)
|
void JsonCallbacks::handleImageToLedsMappingChange(int mappingType)
|
||||||
@ -323,7 +344,7 @@ void JsonCallbacks::handleImageToLedsMappingChange(int mappingType)
|
|||||||
QJsonObject data;
|
QJsonObject data;
|
||||||
data["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(mappingType);
|
data["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(mappingType);
|
||||||
|
|
||||||
doCallback(Subscription::ImageToLedMappingUpdate, QVariant(data));
|
doCallback(Subscription::ImageToLedMappingUpdate, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleAdjustmentChange()
|
void JsonCallbacks::handleAdjustmentChange()
|
||||||
@ -335,7 +356,7 @@ void JsonCallbacks::handleVideoModeChange(VideoMode mode)
|
|||||||
{
|
{
|
||||||
QJsonObject data;
|
QJsonObject data;
|
||||||
data["videomode"] = QString(videoMode2String(mode));
|
data["videomode"] = QString(videoMode2String(mode));
|
||||||
doCallback(Subscription::VideomodeUpdate, QVariant(data));
|
doCallback(Subscription::VideomodeUpdate, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ENABLE_EFFECTENGINE)
|
#if defined(ENABLE_EFFECTENGINE)
|
||||||
@ -343,29 +364,29 @@ void JsonCallbacks::handleEffectListChange()
|
|||||||
{
|
{
|
||||||
QJsonObject effects;
|
QJsonObject effects;
|
||||||
effects["effects"] = JsonInfo::getEffects(_hyperion);
|
effects["effects"] = JsonInfo::getEffects(_hyperion);
|
||||||
doCallback(Subscription::EffectsUpdate, QVariant(effects));
|
doCallback(Subscription::EffectsUpdate, effects);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void JsonCallbacks::handleSettingsChange(settings::type type, const QJsonDocument& data)
|
void JsonCallbacks::handleSettingsChange(settings::type type, const QJsonDocument& data)
|
||||||
{
|
{
|
||||||
QJsonObject dat;
|
QJsonObject obj;
|
||||||
if(data.isObject()) {
|
if(data.isObject()) {
|
||||||
dat[typeToString(type)] = data.object();
|
obj[typeToString(type)] = data.object();
|
||||||
} else {
|
} else {
|
||||||
dat[typeToString(type)] = data.array();
|
obj[typeToString(type)] = data.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
doCallback(Subscription::SettingsUpdate, QVariant(dat));
|
doCallback(Subscription::SettingsUpdate, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleLedsConfigChange(settings::type type, const QJsonDocument& data)
|
void JsonCallbacks::handleLedsConfigChange(settings::type type, const QJsonDocument& data)
|
||||||
{
|
{
|
||||||
if(type == settings::LEDS)
|
if(type == settings::LEDS)
|
||||||
{
|
{
|
||||||
QJsonObject dat;
|
QJsonObject obj;
|
||||||
dat[typeToString(type)] = data.array();
|
obj[typeToString(type)] = data.array();
|
||||||
doCallback(Subscription::LedsUpdate, QVariant(dat));
|
doCallback(Subscription::LedsUpdate, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +406,7 @@ void JsonCallbacks::handleTokenChange(const QVector<AuthManager::AuthDefinition>
|
|||||||
sub["last_use"] = entry.lastUse;
|
sub["last_use"] = entry.lastUse;
|
||||||
arr.push_back(sub);
|
arr.push_back(sub);
|
||||||
}
|
}
|
||||||
doCallback(Subscription::TokenUpdate, QVariant(arr));
|
doCallback(Subscription::TokenUpdate, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleLedColorUpdate(const std::vector<ColorRgb> &ledColors)
|
void JsonCallbacks::handleLedColorUpdate(const std::vector<ColorRgb> &ledColors)
|
||||||
@ -393,13 +414,16 @@ void JsonCallbacks::handleLedColorUpdate(const std::vector<ColorRgb> &ledColors)
|
|||||||
QJsonObject result;
|
QJsonObject result;
|
||||||
QJsonArray leds;
|
QJsonArray leds;
|
||||||
|
|
||||||
for (const auto &color : ledColors)
|
// Avoid copying by appending RGB values directly
|
||||||
|
for (const auto& color : ledColors)
|
||||||
{
|
{
|
||||||
leds << QJsonValue(color.red) << QJsonValue(color.green) << QJsonValue(color.blue);
|
leds.append(QJsonValue(color.red));
|
||||||
|
leds.append(QJsonValue(color.green));
|
||||||
|
leds.append(QJsonValue(color.blue));
|
||||||
}
|
}
|
||||||
result["leds"] = leds;
|
result["leds"] = leds;
|
||||||
|
|
||||||
doCallback(Subscription::LedColorsUpdate, QVariant(result));
|
doCallback(Subscription::LedColorsUpdate, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleImageUpdate(const Image<ColorRgb> &image)
|
void JsonCallbacks::handleImageUpdate(const Image<ColorRgb> &image)
|
||||||
@ -413,7 +437,7 @@ void JsonCallbacks::handleImageUpdate(const Image<ColorRgb> &image)
|
|||||||
QJsonObject result;
|
QJsonObject result;
|
||||||
result["image"] = "data:image/jpg;base64," + QString(byteArray.toBase64());
|
result["image"] = "data:image/jpg;base64," + QString(byteArray.toBase64());
|
||||||
|
|
||||||
doCallback(Subscription::ImageUpdate, QVariant(result));
|
doCallback(Subscription::ImageUpdate, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg)
|
void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg)
|
||||||
@ -445,7 +469,7 @@ void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg)
|
|||||||
}
|
}
|
||||||
result.insert("messages", messageArray);
|
result.insert("messages", messageArray);
|
||||||
|
|
||||||
doCallback(Subscription::LogMsgUpdate, QVariant(result));
|
doCallback(Subscription::LogMsgUpdate, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonCallbacks::handleEventUpdate(const Event &event)
|
void JsonCallbacks::handleEventUpdate(const Event &event)
|
||||||
@ -454,6 +478,6 @@ void JsonCallbacks::handleEventUpdate(const Event &event)
|
|||||||
|
|
||||||
result["event"] = eventToString(event);
|
result["event"] = eventToString(event);
|
||||||
|
|
||||||
doCallback(Subscription::EventUpdate, QVariant(result));
|
doCallback(Subscription::EventUpdate, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,13 @@
|
|||||||
// python utils
|
// python utils
|
||||||
#include <python/PythonProgram.h>
|
#include <python/PythonProgram.h>
|
||||||
|
|
||||||
Effect::Effect(Hyperion* hyperion, int priority, int timeout, const QString& script, const QString& name, const QJsonObject& args, const QString& imageData)
|
|
||||||
|
// Constants
|
||||||
|
namespace {
|
||||||
|
int DEFAULT_MAX_UPDATE_RATE_HZ { 200 };
|
||||||
|
} //End of constants
|
||||||
|
|
||||||
|
Effect::Effect(Hyperion *hyperion, int priority, int timeout, const QString &script, const QString &name, const QJsonObject &args, const QString &imageData)
|
||||||
: QThread()
|
: QThread()
|
||||||
, _hyperion(hyperion)
|
, _hyperion(hyperion)
|
||||||
, _priority(priority)
|
, _priority(priority)
|
||||||
@ -26,7 +32,8 @@ Effect::Effect(Hyperion* hyperion, int priority, int timeout, const QString& scr
|
|||||||
, _endTime(-1)
|
, _endTime(-1)
|
||||||
, _interupt(false)
|
, _interupt(false)
|
||||||
, _imageSize(hyperion->getLedGridSize())
|
, _imageSize(hyperion->getLedGridSize())
|
||||||
, _image(_imageSize, QImage::Format_ARGB32_Premultiplied)
|
, _image(_imageSize,QImage::Format_ARGB32_Premultiplied)
|
||||||
|
, _lowestUpdateIntervalInSeconds(1/static_cast<double>(DEFAULT_MAX_UPDATE_RATE_HZ))
|
||||||
{
|
{
|
||||||
_colors.resize(_hyperion->getLedCount());
|
_colors.resize(_hyperion->getLedCount());
|
||||||
_colors.fill(ColorRgb::BLACK);
|
_colors.fill(ColorRgb::BLACK);
|
||||||
|
@ -184,6 +184,7 @@ PyMethodDef EffectModule::effectMethods[] = {
|
|||||||
{"imageCOffset" , EffectModule::wrapImageCOffset , METH_VARARGS, "Add offset to the coordinate system"},
|
{"imageCOffset" , EffectModule::wrapImageCOffset , METH_VARARGS, "Add offset to the coordinate system"},
|
||||||
{"imageCShear" , EffectModule::wrapImageCShear , METH_VARARGS, "Shear of coordinate system by the given horizontal/vertical axis"},
|
{"imageCShear" , EffectModule::wrapImageCShear , METH_VARARGS, "Shear of coordinate system by the given horizontal/vertical axis"},
|
||||||
{"imageResetT" , EffectModule::wrapImageResetT , METH_NOARGS, "Resets all coords modifications (rotate,offset,shear)"},
|
{"imageResetT" , EffectModule::wrapImageResetT , METH_NOARGS, "Resets all coords modifications (rotate,offset,shear)"},
|
||||||
|
{"lowestUpdateInterval" , EffectModule::wrapLowestUpdateInterval , METH_NOARGS, "Gets the lowest permissible interval time in seconds"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1106,3 +1107,10 @@ PyObject* EffectModule::wrapImageResetT(PyObject* self, PyObject* args)
|
|||||||
getEffect()->_painter->resetTransform();
|
getEffect()->_painter->resetTransform();
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* EffectModule::wrapLowestUpdateInterval(PyObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
qDebug() << "_lowestUpdateIntervalInSeconds: " << getEffect()->_lowestUpdateIntervalInSeconds;
|
||||||
|
|
||||||
|
return Py_BuildValue("d", getEffect()->_lowestUpdateIntervalInSeconds);
|
||||||
|
}
|
||||||
|
@ -49,6 +49,13 @@
|
|||||||
#include <boblightserver/BoblightServer.h>
|
#include <boblightserver/BoblightServer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
namespace {
|
||||||
|
constexpr std::chrono::milliseconds DEFAULT_MAX_IMAGE_EMISSION_INTERVAL{ 40 }; // 25 Hz
|
||||||
|
constexpr std::chrono::milliseconds DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL{ 25 }; // 40 Hz
|
||||||
|
constexpr std::chrono::milliseconds DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL{ 5 }; // 200 Hz
|
||||||
|
} //End of constants
|
||||||
|
|
||||||
Hyperion::Hyperion(quint8 instance)
|
Hyperion::Hyperion(quint8 instance)
|
||||||
: QObject()
|
: QObject()
|
||||||
, _instIndex(instance)
|
, _instIndex(instance)
|
||||||
@ -75,6 +82,12 @@ Hyperion::Hyperion(quint8 instance)
|
|||||||
#if defined(ENABLE_BOBLIGHT_SERVER)
|
#if defined(ENABLE_BOBLIGHT_SERVER)
|
||||||
, _boblightServer(nullptr)
|
, _boblightServer(nullptr)
|
||||||
#endif
|
#endif
|
||||||
|
, _lastImageEmission(0)
|
||||||
|
, _lastRawLedDataEmission(0)
|
||||||
|
, _lastLedDeviceDataEmission(0)
|
||||||
|
, _imageEmissionInterval(DEFAULT_MAX_IMAGE_EMISSION_INTERVAL)
|
||||||
|
, _rawLedDataEmissionInterval(DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL)
|
||||||
|
, _ledDeviceDataEmissionInterval(DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<ComponentList>("ComponentList");
|
qRegisterMetaType<ComponentList>("ComponentList");
|
||||||
|
|
||||||
@ -109,6 +122,8 @@ void Hyperion::start()
|
|||||||
// handle hwLedCount
|
// handle hwLedCount
|
||||||
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Initialize colororder vector
|
// Initialize colororder vector
|
||||||
for (const Led& led : _ledString.leds())
|
for (const Led& led : _ledString.leds())
|
||||||
{
|
{
|
||||||
@ -180,6 +195,15 @@ void Hyperion::start()
|
|||||||
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor, this, &Hyperion::setColor);
|
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor, this, &Hyperion::setColor);
|
||||||
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage, this, &Hyperion::setInputImage);
|
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage, this, &Hyperion::setInputImage);
|
||||||
|
|
||||||
|
// Limit LED data emission, if high rumber of LEDs configured
|
||||||
|
_rawLedDataEmissionInterval = (_ledString.leds().size() > 1000) ? 2 * DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL : DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL;
|
||||||
|
_ledDeviceDataEmissionInterval = (_hwLedCount > 1000) ? 2 * DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL : DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL;
|
||||||
|
|
||||||
|
// Set up timers to throttle specific signals
|
||||||
|
_imageTimer.start(); // Start the elapsed timer for image signal throttling
|
||||||
|
_rawLedDataTimer.start(); // Start the elapsed timer for rawLedColors throttling
|
||||||
|
_ledDeviceDataTimer.start(); // Start the elapsed timer for LED-Device data throttling
|
||||||
|
|
||||||
// if there is no startup / background effect and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a priority change)
|
// if there is no startup / background effect and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a priority change)
|
||||||
update();
|
update();
|
||||||
|
|
||||||
@ -267,6 +291,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
|||||||
std::vector<ColorRgb> color(_ledString.leds().size(), ColorRgb{0,0,0});
|
std::vector<ColorRgb> color(_ledString.leds().size(), ColorRgb{0,0,0});
|
||||||
_ledBuffer = color;
|
_ledBuffer = color;
|
||||||
|
|
||||||
|
|
||||||
_ledStringColorOrder.clear();
|
_ledStringColorOrder.clear();
|
||||||
for (const Led& led : _ledString.leds())
|
for (const Led& led : _ledString.leds())
|
||||||
{
|
{
|
||||||
@ -276,6 +301,10 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
|||||||
// handle hwLedCount update
|
// handle hwLedCount update
|
||||||
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
||||||
|
|
||||||
|
// Limit LED data emission, if high rumber of LEDs configured
|
||||||
|
_rawLedDataEmissionInterval = (_ledString.leds().size() > 1000) ? 2 * DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL : DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL;
|
||||||
|
_ledDeviceDataEmissionInterval = (_hwLedCount > 1000) ? 2 * DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL : DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL;
|
||||||
|
|
||||||
// change in leds are also reflected in adjustment
|
// change in leds are also reflected in adjustment
|
||||||
delete _raw2ledAdjustment;
|
delete _raw2ledAdjustment;
|
||||||
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), getSetting(settings::COLOR).object());
|
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), getSetting(settings::COLOR).object());
|
||||||
@ -672,7 +701,14 @@ void Hyperion::update()
|
|||||||
Image<ColorRgb> image = priorityInfo.image;
|
Image<ColorRgb> image = priorityInfo.image;
|
||||||
if (image.width() > 1 || image.height() > 1)
|
if (image.width() > 1 || image.height() > 1)
|
||||||
{
|
{
|
||||||
emit currentImage(image);
|
_imageEmissionInterval = (image.width() > 1280) ? 2 * DEFAULT_MAX_IMAGE_EMISSION_INTERVAL : DEFAULT_MAX_IMAGE_EMISSION_INTERVAL;
|
||||||
|
// Throttle the emission of currentImage(image) signal
|
||||||
|
qint64 elapsedImageEmissionTime = _imageTimer.elapsed();
|
||||||
|
if (elapsedImageEmissionTime - _lastImageEmission >= _imageEmissionInterval.count())
|
||||||
|
{
|
||||||
|
_lastImageEmission = elapsedImageEmissionTime;
|
||||||
|
emit currentImage(image); // Emit the image signal at the controlled rate
|
||||||
|
}
|
||||||
_ledBuffer = _imageProcessor->process(image);
|
_ledBuffer = _imageProcessor->process(image);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -692,9 +728,15 @@ void Hyperion::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit rawLedColors before transform
|
// Throttle the emission of rawLedColors(_ledBuffer) signal
|
||||||
emit rawLedColors(_ledBuffer);
|
qint64 elapsedRawLedDataEmissionTime = _rawLedDataTimer.elapsed();
|
||||||
|
if (elapsedRawLedDataEmissionTime - _lastRawLedDataEmission >= _rawLedDataEmissionInterval.count())
|
||||||
|
{
|
||||||
|
_lastRawLedDataEmission = elapsedRawLedDataEmissionTime;
|
||||||
|
emit rawLedColors(_ledBuffer); // Emit the rawLedColors signal at the controlled rate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start transformations
|
||||||
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
|
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -740,7 +782,13 @@ void Hyperion::update()
|
|||||||
// Smoothing is disabled
|
// Smoothing is disabled
|
||||||
if (! _deviceSmooth->enabled())
|
if (! _deviceSmooth->enabled())
|
||||||
{
|
{
|
||||||
emit ledDeviceData(_ledBuffer);
|
// Throttle the emission of LED-Device data signal
|
||||||
|
qint64 elapsedLedDeviceDataEmissionTime = _ledDeviceDataTimer.elapsed();
|
||||||
|
if (elapsedLedDeviceDataEmissionTime - _lastLedDeviceDataEmission >= _ledDeviceDataEmissionInterval.count())
|
||||||
|
{
|
||||||
|
_lastLedDeviceDataEmission = elapsedLedDeviceDataEmissionTime;
|
||||||
|
emit ledDeviceData(_ledBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -124,13 +124,11 @@
|
|||||||
"ledshoriz": {
|
"ledshoriz": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"maximum": 50,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"ledsvert": {
|
"ledsvert": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"maximum": 50,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"cabling": {
|
"cabling": {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// project includes
|
// project includes
|
||||||
#include "JsonClientConnection.h"
|
#include "JsonClientConnection.h"
|
||||||
#include <api/JsonAPI.h>
|
#include <api/JsonAPI.h>
|
||||||
|
#include <api/JsonCallbacks.h>
|
||||||
|
|
||||||
// qt inc
|
// qt inc
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
@ -17,8 +18,9 @@ JsonClientConnection::JsonClientConnection(QTcpSocket *socket, bool localConnect
|
|||||||
// create a new instance of JsonAPI
|
// create a new instance of JsonAPI
|
||||||
_jsonAPI = new JsonAPI(socket->peerAddress().toString(), _log, localConnection, this);
|
_jsonAPI = new JsonAPI(socket->peerAddress().toString(), _log, localConnection, this);
|
||||||
// get the callback messages from JsonAPI and send it to the client
|
// get the callback messages from JsonAPI and send it to the client
|
||||||
connect(_jsonAPI, &JsonAPI::callbackMessage, this , &JsonClientConnection::sendMessage);
|
connect(_jsonAPI, &JsonAPI::callbackReady, this , &JsonClientConnection::sendMessage);
|
||||||
connect(_jsonAPI, &JsonAPI::forceClose, this , [&](){ _socket->close(); } );
|
connect(_jsonAPI, &JsonAPI::forceClose, this , [&](){ _socket->close(); } );
|
||||||
|
connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &JsonClientConnection::sendMessage);
|
||||||
|
|
||||||
_jsonAPI->initialize();
|
_jsonAPI->initialize();
|
||||||
}
|
}
|
||||||
@ -47,7 +49,8 @@ void JsonClientConnection::readRequest()
|
|||||||
qint64 JsonClientConnection::sendMessage(QJsonObject message)
|
qint64 JsonClientConnection::sendMessage(QJsonObject message)
|
||||||
{
|
{
|
||||||
QJsonDocument writer(message);
|
QJsonDocument writer(message);
|
||||||
QByteArray data = writer.toJson(QJsonDocument::Compact) + "\n";
|
QByteArray data = writer.toJson(QJsonDocument::Compact);
|
||||||
|
data.append('\n');
|
||||||
|
|
||||||
if (!_socket || (_socket->state() != QAbstractSocket::ConnectedState)) return 0;
|
if (!_socket || (_socket->state() != QAbstractSocket::ConnectedState)) return 0;
|
||||||
return _socket->write(data.data(), data.size());
|
return _socket->write(data.data(), data.size());
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "QtHttpClientWrapper.h"
|
#include "QtHttpClientWrapper.h"
|
||||||
|
|
||||||
#include <api/JsonAPI.h>
|
#include <api/JsonAPI.h>
|
||||||
|
#include <api/JsonCallbacks.h>
|
||||||
|
|
||||||
WebJsonRpc::WebJsonRpc(QtHttpRequest* request, QtHttpServer* server, bool localConnection, QtHttpClientWrapper* parent)
|
WebJsonRpc::WebJsonRpc(QtHttpRequest* request, QtHttpServer* server, bool localConnection, QtHttpClientWrapper* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@ -14,8 +15,10 @@ WebJsonRpc::WebJsonRpc(QtHttpRequest* request, QtHttpServer* server, bool localC
|
|||||||
{
|
{
|
||||||
const QString client = request->getClientInfo().clientAddress.toString();
|
const QString client = request->getClientInfo().clientAddress.toString();
|
||||||
_jsonAPI = new JsonAPI(client, _log, localConnection, this, true);
|
_jsonAPI = new JsonAPI(client, _log, localConnection, this, true);
|
||||||
connect(_jsonAPI, &JsonAPI::callbackMessage, this, &WebJsonRpc::handleCallback);
|
connect(_jsonAPI, &JsonAPI::callbackReady, this, &WebJsonRpc::sendCallbackMessage);
|
||||||
connect(_jsonAPI, &JsonAPI::forceClose, [&]() { _wrapper->closeConnection(); _stopHandle = true; });
|
connect(_jsonAPI, &JsonAPI::forceClose, [&]() { _wrapper->closeConnection(); _stopHandle = true; });
|
||||||
|
connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebJsonRpc::sendCallbackMessage);
|
||||||
|
|
||||||
_jsonAPI->initialize();
|
_jsonAPI->initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +34,7 @@ void WebJsonRpc::handleMessage(QtHttpRequest* request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebJsonRpc::handleCallback(QJsonObject obj)
|
void WebJsonRpc::sendCallbackMessage(QJsonObject obj)
|
||||||
{
|
{
|
||||||
// guard against wrong callbacks; TODO: Remove when JSONAPI is more solid
|
// guard against wrong callbacks; TODO: Remove when JSONAPI is more solid
|
||||||
if(!_unlocked) return;
|
if(!_unlocked) return;
|
||||||
|
@ -26,5 +26,5 @@ private:
|
|||||||
bool _unlocked = false;
|
bool _unlocked = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleCallback(QJsonObject obj);
|
void sendCallbackMessage(QJsonObject obj);
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <hyperion/Hyperion.h>
|
#include <hyperion/Hyperion.h>
|
||||||
#include <api/JsonAPI.h>
|
#include <api/JsonAPI.h>
|
||||||
|
#include <api/JsonCallbacks.h>
|
||||||
|
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
@ -24,9 +25,11 @@ WebSocketClient::WebSocketClient(QtHttpRequest* request, QTcpSocket* sock, bool
|
|||||||
|
|
||||||
// Json processor
|
// Json processor
|
||||||
_jsonAPI.reset(new JsonAPI(client, _log, localConnection, this));
|
_jsonAPI.reset(new JsonAPI(client, _log, localConnection, this));
|
||||||
connect(_jsonAPI.get(), &JsonAPI::callbackMessage, this, &WebSocketClient::sendMessage);
|
connect(_jsonAPI.get(), &JsonAPI::callbackReady, this, &WebSocketClient::sendMessage);
|
||||||
connect(_jsonAPI.get(), &JsonAPI::forceClose, this,[this]() { this->sendClose(CLOSECODE::NORMAL); });
|
connect(_jsonAPI.get(), &JsonAPI::forceClose, this,[this]() { this->sendClose(CLOSECODE::NORMAL); });
|
||||||
|
|
||||||
|
connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebSocketClient::sendMessage);
|
||||||
|
|
||||||
connect(this, &WebSocketClient::handleMessage, _jsonAPI.get(), &JsonAPI::handleMessage);
|
connect(this, &WebSocketClient::handleMessage, _jsonAPI.get(), &JsonAPI::handleMessage);
|
||||||
|
|
||||||
Debug(_log, "New connection from %s", QSTRING_CSTR(client));
|
Debug(_log, "New connection from %s", QSTRING_CSTR(client));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user