diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 69c80640..8994c4b5 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -575,7 +575,7 @@ "edt_dev_spec_intervall_title": "Interval", "edt_dev_spec_invert_title": "Invert signal", "edt_dev_spec_latchtime_title": "Latch time", - "edt_dev_spec_latchtime_title_info": "Latch time is the time-frame a device requires until the next update can be processed. During that time-frame any updates done via ignored.", + "edt_dev_spec_latchtime_title_info": "Latch time is the time-frame a device requires until the next update can be processed. During that time-frame any updates done are ignored.", "edt_dev_spec_ledIndex_title": "LED index", "edt_dev_spec_ledType_title": "LED Type", "edt_dev_spec_lightid_itemtitle": "ID", diff --git a/include/forwarder/MessageForwarder.h b/include/forwarder/MessageForwarder.h index 585d8148..d17add09 100644 --- a/include/forwarder/MessageForwarder.h +++ b/include/forwarder/MessageForwarder.h @@ -78,11 +78,14 @@ private slots: /// void forwardJsonMessage(const QJsonObject &message); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) /// /// @brief Forward image to all flatbuffer target hosts /// @param image The flatbuffer image to send /// + /// void forwardFlatbufferMessage(const QString& name, const Image &image); +#endif /// /// @brief Forward message to a single json target host diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index 2b901862..3a2f1146 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -428,6 +428,11 @@ signals: /// Signal which is emitted, when a new V4l proto image should be forwarded void forwardV4lProtoMessage(const QString&, const Image&); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + /// Signal which is emitted, when a new Flat-/Proto- Buffer image should be forwarded + void forwardBufferMessage(const QString&, const Image&); +#endif + /// /// @brief Is emitted from clients who request a videoMode change /// diff --git a/include/utils/GlobalSignals.h b/include/utils/GlobalSignals.h index 213ab955..8819d8ce 100644 --- a/include/utils/GlobalSignals.h +++ b/include/utils/GlobalSignals.h @@ -47,6 +47,15 @@ signals: /// void setV4lImage(const QString& name, const Image& image); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + /// + /// @brief PIPE Flat-/Proto- buffer images to Hyperion class + /// @param name The name of the buffer capture that is currently active + /// @param image The prepared image + /// + void setBufferImage(const QString& name, const Image& image); +#endif + /// /// @brief PIPE the register command for a new global input over HyperionDaemon to Hyperion class /// @param[in] priority The priority of the channel diff --git a/libsrc/flatbufserver/FlatBufferClient.cpp b/libsrc/flatbufserver/FlatBufferClient.cpp index 1e6acba4..8df752ca 100644 --- a/libsrc/flatbufserver/FlatBufferClient.cpp +++ b/libsrc/flatbufserver/FlatBufferClient.cpp @@ -182,6 +182,7 @@ void FlatBufferClient::handleImageCommand(const hyperionnet::Image *image) } emit setGlobalInputImage(_priority, imageRGB, duration); + emit setBufferImage("FlatBuffer", imageRGB); } // send reply diff --git a/libsrc/flatbufserver/FlatBufferClient.h b/libsrc/flatbufserver/FlatBufferClient.h index 4250559e..5776df54 100644 --- a/libsrc/flatbufserver/FlatBufferClient.h +++ b/libsrc/flatbufserver/FlatBufferClient.h @@ -54,6 +54,11 @@ signals: /// void setGlobalInputColor(int priority, const std::vector &ledColor, int timeout_ms, const QString& origin = "FlatBuffer" ,bool clearEffects = true); + /// + /// @brief Emit the final processed image + /// + void setBufferImage(const QString& name, const Image& image); + /// /// @brief Emits whenever the client disconnected /// diff --git a/libsrc/flatbufserver/FlatBufferServer.cpp b/libsrc/flatbufserver/FlatBufferServer.cpp index 75caa3b7..8c48a58b 100644 --- a/libsrc/flatbufserver/FlatBufferServer.cpp +++ b/libsrc/flatbufserver/FlatBufferServer.cpp @@ -81,6 +81,7 @@ void FlatBufferServer::newConnection() connect(client, &FlatBufferClient::clearGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearGlobalInput); connect(client, &FlatBufferClient::setGlobalInputImage, GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage); connect(client, &FlatBufferClient::setGlobalInputColor, GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor); + connect(client, &FlatBufferClient::setBufferImage, GlobalSignals::getInstance(), &GlobalSignals::setBufferImage); connect(GlobalSignals::getInstance(), &GlobalSignals::globalRegRequired, client, &FlatBufferClient::registationRequired); _openConnections.append(client); } diff --git a/libsrc/forwarder/MessageForwarder.cpp b/libsrc/forwarder/MessageForwarder.cpp index f2bc0859..0070f2e4 100644 --- a/libsrc/forwarder/MessageForwarder.cpp +++ b/libsrc/forwarder/MessageForwarder.cpp @@ -107,13 +107,27 @@ void MessageForwarder::enableTargets(bool enable, const QJsonObject& config) if (flatbufTargetNum > 0) { hyperion::Components activeCompId = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority()).componentId; - if (activeCompId == hyperion::COMP_GRABBER) - { + + switch (activeCompId) { + case hyperion::COMP_GRABBER: connect(_hyperion, &Hyperion::forwardSystemProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); - } - else if (activeCompId == hyperion::COMP_V4L) - { + break; + case hyperion::COMP_V4L: connect(_hyperion, &Hyperion::forwardV4lProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); + break; +#if defined(ENABLE_FLATBUF_SERVER) + case hyperion::COMP_FLATBUFSERVER: +#endif +#if defined(ENABLE_PROTOBUF_SERVER) + case hyperion::COMP_PROTOSERVER: +#endif +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + + connect(_hyperion, &Hyperion::forwardBufferMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); + break; +#endif + default: + break; } } @@ -135,33 +149,41 @@ void MessageForwarder::handlePriorityChanges(int priority) if (priority != 0 && _forwarder_enabled) { hyperion::Components activeCompId = _hyperion->getPriorityInfo(priority).componentId; - if (activeCompId == hyperion::COMP_GRABBER || activeCompId == hyperion::COMP_V4L) - { - switch (activeCompId) - { - case hyperion::COMP_GRABBER: - { - disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); - connect(_hyperion, &Hyperion::forwardSystemProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); - } + + switch (activeCompId) { + case hyperion::COMP_GRABBER: + disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + disconnect(_hyperion, &Hyperion::forwardBufferMessage, nullptr, nullptr); +#endif + connect(_hyperion, &Hyperion::forwardSystemProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); break; - case hyperion::COMP_V4L: - { - disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); - connect(_hyperion, &Hyperion::forwardV4lProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); - } + case hyperion::COMP_V4L: + disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + disconnect(_hyperion, &Hyperion::forwardBufferMessage, nullptr, nullptr); +#endif + connect(_hyperion, &Hyperion::forwardV4lProtoMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); break; - default: - { - disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); - disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); - } - } - } - else - { +#if defined(ENABLE_FLATBUF_SERVER) + case hyperion::COMP_FLATBUFSERVER: +#endif +#if defined(ENABLE_PROTOBUF_SERVER) + case hyperion::COMP_PROTOSERVER: +#endif +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); + connect(_hyperion, &Hyperion::forwardBufferMessage, this, &MessageForwarder::forwardFlatbufferMessage, Qt::UniqueConnection); + break; +#endif + default: + disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); + disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + disconnect(_hyperion, &Hyperion::forwardBufferMessage, nullptr, nullptr); +#endif + break; } } } @@ -351,6 +373,9 @@ void MessageForwarder::stopFlatbufferTargets() { disconnect(_hyperion, &Hyperion::forwardSystemProtoMessage, nullptr, nullptr); disconnect(_hyperion, &Hyperion::forwardV4lProtoMessage, nullptr, nullptr); +#if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + disconnect(_hyperion, &Hyperion::forwardBufferMessage, nullptr, nullptr); +#endif if (_messageForwarderFlatBufHelper != nullptr) { diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index a289f361..35b3c236 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -150,6 +150,9 @@ void Hyperion::start() { _messageForwarder = new MessageForwarder(this); _messageForwarder->handleSettingsUpdate(settings::NETFORWARD, getSetting(settings::NETFORWARD)); + #if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER) + connect(GlobalSignals::getInstance(), &GlobalSignals::setBufferImage, this, &Hyperion::forwardBufferMessage); + #endif } #endif diff --git a/libsrc/leddevice/LedDevice.cpp b/libsrc/leddevice/LedDevice.cpp index c9d5addd..7d5fd05d 100644 --- a/libsrc/leddevice/LedDevice.cpp +++ b/libsrc/leddevice/LedDevice.cpp @@ -1,703 +1,703 @@ -#include - -//QT include -#include -#include -#include -#include -#include -#include -#include - -#include "hyperion/Hyperion.h" -#include - -//std includes -#include -#include -#include - -// Constants -namespace { - - // Configuration settings - const char CONFIG_CURRENT_LED_COUNT[] = "currentLedCount"; - const char CONFIG_COLOR_ORDER[] = "colorOrder"; - const char CONFIG_AUTOSTART[] = "autoStart"; - const char CONFIG_LATCH_TIME[] = "latchTime"; - const char CONFIG_REWRITE_TIME[] = "rewriteTime"; - - int DEFAULT_LED_COUNT{ 1 }; - const char DEFAULT_COLOR_ORDER[]{ "RGB" }; - const bool DEFAULT_IS_AUTOSTART{ true }; - - const char CONFIG_ENABLE_ATTEMPTS[] = "enableAttempts"; - const char CONFIG_ENABLE_ATTEMPTS_INTERVALL[] = "enableAttemptsInterval"; - - const int DEFAULT_MAX_ENABLE_ATTEMPTS{ 5 }; - constexpr std::chrono::seconds DEFAULT_ENABLE_ATTEMPTS_INTERVAL{ 5 }; - -} //End of constants - -LedDevice::LedDevice(const QJsonObject& deviceConfig, QObject* parent) - : QObject(parent) - , _devConfig(deviceConfig) - , _log(Logger::getInstance("LEDDEVICE")) - , _ledBuffer(0) - , _refreshTimer(nullptr) - , _enableAttemptsTimer(nullptr) - , _refreshTimerInterval_ms(0) - , _enableAttemptTimerInterval(DEFAULT_ENABLE_ATTEMPTS_INTERVAL) - , _enableAttempts(0) - , _maxEnableAttempts(DEFAULT_MAX_ENABLE_ATTEMPTS) - , _latchTime_ms(0) - , _ledCount(0) - , _isRestoreOrigState(false) - , _isEnabled(false) - , _isDeviceInitialised(false) - , _isDeviceReady(false) - , _isOn(false) - , _isDeviceInError(false) - , _lastWriteTime(QDateTime::currentDateTime()) - , _isRefreshEnabled(false) - , _isAutoStart(true) -{ - _activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower(); -} - -LedDevice::~LedDevice() -{ - this->stopEnableAttemptsTimer(); - this->stopRefreshTimer(); -} - -void LedDevice::start() -{ - Info(_log, "Start LedDevice '%s'.", QSTRING_CSTR(_activeDeviceType)); - - close(); - _isDeviceInitialised = false; - - if (init(_devConfig)) - { - // Everything is OK -> enable device - _isDeviceInitialised = true; - - if (_isAutoStart) - { - if (!_isEnabled) - { - Debug(_log, "Not enabled -> enable device"); - enable(); - } - } - } -} - -void LedDevice::stop() -{ - Debug(_log, "Stop device"); - this->disable(); - this->stopRefreshTimer(); - Info(_log, " Stopped LedDevice '%s'", QSTRING_CSTR(_activeDeviceType)); -} - -int LedDevice::open() -{ - _isDeviceReady = true; - int retval = 0; - - return retval; -} - -int LedDevice::close() -{ - _isDeviceReady = false; - int retval = 0; - - return retval; -} - -void LedDevice::setInError(const QString& errorMsg) -{ - _isOn = false; - _isDeviceInError = true; - _isDeviceReady = false; - _isEnabled = false; - this->stopRefreshTimer(); - - Error(_log, "Device disabled, device '%s' signals error: '%s'", QSTRING_CSTR(_activeDeviceType), QSTRING_CSTR(errorMsg)); - emit enableStateChanged(_isEnabled); -} - -void LedDevice::enable() -{ - Debug(_log, "Enable device %s'", QSTRING_CSTR(_activeDeviceType)); - - if (!_isEnabled) - { - if (_enableAttemptsTimer != nullptr && _enableAttemptsTimer->isActive()) - { - _enableAttemptsTimer->stop(); - } - - _isDeviceInError = false; - - if (!_isDeviceInitialised) - { - _isDeviceInitialised = init(_devConfig); - } - - if (!_isDeviceReady) - { - open(); - } - - bool isEnableFailed(true); - - if (_isDeviceReady) - { - if (switchOn()) - { - stopEnableAttemptsTimer(); - _isEnabled = true; - isEnableFailed = false; - emit enableStateChanged(_isEnabled); - Info(_log, "LedDevice '%s' enabled", QSTRING_CSTR(_activeDeviceType)); - } - } - - if (isEnableFailed) - { - emit enableStateChanged(false); - - if (_maxEnableAttempts > 0) - { - Debug(_log, "Device's enablement failed - Start retry timer. Retried already done [%d], isEnabled: [%d]", _enableAttempts, _isEnabled); - startEnableAttemptsTimer(); - } - else - { - Debug(_log, "Device's enablement failed"); - } - } - } -} - -void LedDevice::disable() -{ - Debug(_log, "Disable device %s'", QSTRING_CSTR(_activeDeviceType)); - if (_isEnabled) - { - _isEnabled = false; - this->stopEnableAttemptsTimer(); - this->stopRefreshTimer(); - - switchOff(); - close(); - - emit enableStateChanged(_isEnabled); - } -} - -void LedDevice::setActiveDeviceType(const QString& deviceType) -{ - _activeDeviceType = deviceType; -} - -bool LedDevice::init(const QJsonObject& deviceConfig) -{ - Debug(_log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData()); - - setLedCount(deviceConfig[CONFIG_CURRENT_LED_COUNT].toInt(DEFAULT_LED_COUNT)); // property injected to reflect real led count - setColorOrder(deviceConfig[CONFIG_COLOR_ORDER].toString(DEFAULT_COLOR_ORDER)); - setLatchTime(deviceConfig[CONFIG_LATCH_TIME].toInt(_latchTime_ms)); - setRewriteTime(deviceConfig[CONFIG_REWRITE_TIME].toInt(_refreshTimerInterval_ms)); - setAutoStart(deviceConfig[CONFIG_AUTOSTART].toBool(DEFAULT_IS_AUTOSTART)); - setEnableAttempts(deviceConfig[CONFIG_ENABLE_ATTEMPTS].toInt(DEFAULT_MAX_ENABLE_ATTEMPTS), - std::chrono::seconds(deviceConfig[CONFIG_ENABLE_ATTEMPTS_INTERVALL].toInt(DEFAULT_ENABLE_ATTEMPTS_INTERVAL.count())) - ); - - return true; -} - -void LedDevice::startRefreshTimer() -{ - if (_refreshTimerInterval_ms > 0) - { - if (_isDeviceReady && _isOn) - { - // setup refreshTimer - if (_refreshTimer == nullptr) - { - _refreshTimer = new QTimer(this); - _refreshTimer->setTimerType(Qt::PreciseTimer); - connect(_refreshTimer, &QTimer::timeout, this, &LedDevice::rewriteLEDs); - } - _refreshTimer->setInterval(_refreshTimerInterval_ms); - - //Debug(_log, "Start refresh timer with interval = %ims", _refreshTimer->interval()); - _refreshTimer->start(); - } - else - { - Debug(_log, "Device is not ready to start a refresh timer"); - } - } -} - -void LedDevice::stopRefreshTimer() -{ - if (_refreshTimer != nullptr) - { - //Debug(_log, "Stopping refresh timer"); - _refreshTimer->stop(); - delete _refreshTimer; - _refreshTimer = nullptr; - - } -} - -void LedDevice::startEnableAttemptsTimer() -{ - ++_enableAttempts; - - if (_enableAttempts <= _maxEnableAttempts) - { - if (_enableAttemptTimerInterval.count() > 0) - { - // setup enable retry timer - if (_enableAttemptsTimer == nullptr) - { - _enableAttemptsTimer = new QTimer(this); - _enableAttemptsTimer->setTimerType(Qt::PreciseTimer); - connect(_enableAttemptsTimer, &QTimer::timeout, this, &LedDevice::enable); - } - _enableAttemptsTimer->setInterval(static_cast(_enableAttemptTimerInterval.count() * 1000)); //NOLINT - - Info(_log, "Start %d. attempt of %d to enable the device in %d seconds", _enableAttempts, _maxEnableAttempts, _enableAttemptTimerInterval.count()); - _enableAttemptsTimer->start(); - } - } - else - { - Error(_log, "Device disabled. Maximum number of %d attempts enabling the device reached. Tried for %d seconds.", _maxEnableAttempts, _enableAttempts * _enableAttemptTimerInterval.count()); - _enableAttempts = 0; - } -} - -void LedDevice::stopEnableAttemptsTimer() -{ - if (_enableAttemptsTimer != nullptr) - { - Debug(_log, "Stopping enable retry timer"); - _enableAttemptsTimer->stop(); - delete _enableAttemptsTimer; - _enableAttemptsTimer = nullptr; - _enableAttempts = 0; - } -} - -int LedDevice::updateLeds(std::vector ledValues) -{ - int retval = 0; - if (!_isEnabled || !_isOn || !_isDeviceReady || _isDeviceInError) - { - //std::cout << "LedDevice::updateLeds(), LedDevice NOT ready! "; - retval = -1; - } - else - { - qint64 elapsedTimeMs = _lastWriteTime.msecsTo(QDateTime::currentDateTime()); - if (_latchTime_ms == 0 || elapsedTimeMs >= _latchTime_ms) - { - //std::cout << "LedDevice::updateLeds(), Elapsed time since last write (" << elapsedTimeMs << ") ms > _latchTime_ms (" << _latchTime_ms << ") ms" << std::endl; - retval = write(ledValues); - _lastWriteTime = QDateTime::currentDateTime(); - - // if device requires refreshing, save Led-Values and restart the timer - if (_isRefreshEnabled && _isEnabled) - { - _lastLedValues = ledValues; - this->startRefreshTimer(); - } - } - else - { - //std::cout << "LedDevice::updateLeds(), Skip write. elapsedTime (" << elapsedTimeMs << ") ms < _latchTime_ms (" << _latchTime_ms << ") ms" << std::endl; - if (_isRefreshEnabled) - { - //Stop timer to allow for next non-refresh update - this->stopRefreshTimer(); - } - } - } - return retval; -} - -int LedDevice::rewriteLEDs() -{ - int retval = -1; - - if (_isEnabled && _isOn && _isDeviceReady && !_isDeviceInError) - { - // qint64 elapsedTimeMs = _lastWriteTime.msecsTo(QDateTime::currentDateTime()); - // std::cout << "LedDevice::rewriteLEDs(): Rewrite LEDs now, elapsedTime [" << elapsedTimeMs << "] ms" << std::endl; - // //:TESTING: Inject "white" output records to differentiate from normal writes - // _lastLedValues.clear(); - // _lastLedValues.resize(static_cast(_ledCount), ColorRgb::WHITE); - // printLedValues(_lastLedValues); - // //:TESTING: - - if (!_lastLedValues.empty()) - { - retval = write(_lastLedValues); - _lastWriteTime = QDateTime::currentDateTime(); - } - } - else - { - // If Device is not ready stop timer - this->stopRefreshTimer(); - } - return retval; -} - -int LedDevice::writeBlack(int numberOfWrites) -{ - Debug(_log, "Set LED strip to black to switch of LEDs"); - return writeColor(ColorRgb::BLACK, numberOfWrites); -} - -int LedDevice::writeColor(const ColorRgb& color, int numberOfWrites) -{ - int rc = -1; - - for (int i = 0; i < numberOfWrites; i++) - { - if (_latchTime_ms > 0) - { - // Wait latch time before writing black - QEventLoop loop; - QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit); - loop.exec(); - } - _lastLedValues = std::vector(static_cast(_ledCount), color); - rc = write(_lastLedValues); - } - return rc; -} - -bool LedDevice::switchOn() -{ - bool rc{ false }; - - if (_isOn) - { - Debug(_log, "Device %s is already on. Skipping.", QSTRING_CSTR(_activeDeviceType)); - rc = true; - } - else - { - if (_isDeviceReady) - { - Info(_log, "Switching device %s ON", QSTRING_CSTR(_activeDeviceType)); - if (storeState()) - { - if (powerOn()) - { - Info(_log, "Device %s is ON", QSTRING_CSTR(_activeDeviceType)); - _isOn = true; - emit enableStateChanged(_isEnabled); - rc = true; - } - else - { - Warning(_log, "Failed switching device %s ON", QSTRING_CSTR(_activeDeviceType)); - } - } - } - } - return rc; -} - -bool LedDevice::switchOff() -{ - bool rc{ false }; - - if (!_isOn) - { - rc = true; - } - else - { - if (_isDeviceInitialised) - { - Info(_log, "Switching device %s OFF", QSTRING_CSTR(_activeDeviceType)); - - // Disable device to ensure no standard LED updates are written/processed - _isOn = false; - - rc = true; - - if (_isDeviceReady) - { - if (_isRestoreOrigState) - { - //Restore devices state - restoreState(); - } - else - { - if (powerOff()) - { - Info(_log, "Device %s is OFF", QSTRING_CSTR(_activeDeviceType)); - } - else - { - Warning(_log, "Failed switching device %s OFF", QSTRING_CSTR(_activeDeviceType)); - } - } - } - } - } - return rc; -} - -bool LedDevice::powerOff() -{ - bool rc{ false }; - - Debug(_log, "Power Off: %s", QSTRING_CSTR(_activeDeviceType)); - - // Simulate power-off by writing a final "Black" to have a defined outcome - if (writeBlack() >= 0) - { - rc = true; - } - return rc; -} - -bool LedDevice::powerOn() -{ - bool rc{ true }; - - Debug(_log, "Power On: %s", QSTRING_CSTR(_activeDeviceType)); - - return rc; -} - -bool LedDevice::storeState() -{ - bool rc{ true }; - - if (_isRestoreOrigState) - { - // Save device's original state - // _originalStateValues = get device's state; - // store original power on/off state, if available - } - return rc; -} - -bool LedDevice::restoreState() -{ - bool rc{ true }; - - if (_isRestoreOrigState) - { - // Restore device's original state - // update device using _originalStateValues - // update original power on/off state, if supported - } - return rc; -} - -QJsonObject LedDevice::discover(const QJsonObject& /*params*/) -{ - QJsonObject devicesDiscovered; - - devicesDiscovered.insert("ledDeviceType", _activeDeviceType); - - QJsonArray deviceList; - devicesDiscovered.insert("devices", deviceList); - - Debug(_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData()); - return devicesDiscovered; -} - -QString LedDevice::discoverFirst() -{ - QString deviceDiscovered; - - Debug(_log, "deviceDiscovered: [%s]", QSTRING_CSTR(deviceDiscovered)); - return deviceDiscovered; -} - - -QJsonObject LedDevice::getProperties(const QJsonObject& params) -{ - Debug(_log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData()); - - QJsonObject properties; - - QJsonObject deviceProperties; - properties.insert("properties", deviceProperties); - - Debug(_log, "properties: [%s]", QString(QJsonDocument(properties).toJson(QJsonDocument::Compact)).toUtf8().constData()); - - return properties; -} - -void LedDevice::setLogger(Logger* log) -{ - _log = log; -} - -void LedDevice::setLedCount(int ledCount) -{ - assert(ledCount >= 0); - _ledCount = static_cast(ledCount); - _ledRGBCount = _ledCount * sizeof(ColorRgb); - _ledRGBWCount = _ledCount * sizeof(ColorRgbw); - Debug(_log, "LedCount set to %d", _ledCount); -} - -void LedDevice::setColorOrder(const QString& colorOrder) -{ - _colorOrder = colorOrder; - Debug(_log, "ColorOrder set to %s", QSTRING_CSTR(_colorOrder.toUpper())); -} - -void LedDevice::setLatchTime(int latchTime_ms) -{ - assert(latchTime_ms >= 0); - _latchTime_ms = latchTime_ms; - Debug(_log, "LatchTime set to %dms", _latchTime_ms); -} - -void LedDevice::setAutoStart(bool isAutoStart) -{ - _isAutoStart = isAutoStart; - Debug(_log, "AutoStart %s", (_isAutoStart ? "enabled" : "disabled")); -} - -void LedDevice::setRewriteTime(int rewriteTime_ms) -{ - _refreshTimerInterval_ms = qMax(rewriteTime_ms, 0); - - if (_refreshTimerInterval_ms > 0) - { - _isRefreshEnabled = true; - - if (_refreshTimerInterval_ms <= _latchTime_ms) - { - int new_refresh_timer_interval = _latchTime_ms + 10; //NOLINT - Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval); - _refreshTimerInterval_ms = new_refresh_timer_interval; - } - - Debug(_log, "Refresh interval = %dms", _refreshTimerInterval_ms); - startRefreshTimer(); - } - else - { - _isRefreshEnabled = false; - stopRefreshTimer(); - } -} - -void LedDevice::setEnableAttempts(int maxEnableRetries, std::chrono::seconds enableRetryTimerInterval) -{ - stopEnableAttemptsTimer(); - maxEnableRetries = qMax(maxEnableRetries, 0); - - _enableAttempts = 0; - _maxEnableAttempts = maxEnableRetries; - _enableAttemptTimerInterval = enableRetryTimerInterval; - - Debug(_log, "Max enable retries: %d, enable retry interval = %llds", _maxEnableAttempts, _enableAttemptTimerInterval.count()); -} - -void LedDevice::printLedValues(const std::vector& ledValues) -{ - std::cout << "LedValues [" << ledValues.size() << "] ["; - for (const ColorRgb& color : ledValues) - { - std::cout << color; - } - std::cout << "]" << std::endl; -} - -QString LedDevice::uint8_t_to_hex_string(const uint8_t* data, const int size, int number) -{ - if (number <= 0 || number > size) - { - number = size; - } - - QByteArray bytes(reinterpret_cast(data), number); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return bytes.toHex(':'); -#else - return bytes.toHex(); -#endif -} - -QString LedDevice::toHex(const QByteArray& data, int number) -{ - if (number <= 0 || number > data.size()) - { - number = data.size(); - } - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return data.left(number).toHex(':'); -#else - return data.left(number).toHex(); -#endif -} -bool LedDevice::isInitialised() const -{ - return _isDeviceInitialised; -} - -bool LedDevice::isReady() const -{ - return _isDeviceReady; -} - -bool LedDevice::isInError() const -{ - return _isDeviceInError; -} - -int LedDevice::getLatchTime() const -{ - return _latchTime_ms; -} - -int LedDevice::getRewriteTime() const -{ - return _refreshTimerInterval_ms; -} - -int LedDevice::getLedCount() const -{ - return static_cast(_ledCount); -} - -QString LedDevice::getActiveDeviceType() const -{ - return _activeDeviceType; -} - -QString LedDevice::getColorOrder() const -{ - return _colorOrder; -} - -bool LedDevice::componentState() const { - return _isEnabled; -} - +#include + +//QT include +#include +#include +#include +#include +#include +#include +#include + +#include "hyperion/Hyperion.h" +#include + +//std includes +#include +#include +#include + +// Constants +namespace { + + // Configuration settings + const char CONFIG_CURRENT_LED_COUNT[] = "currentLedCount"; + const char CONFIG_COLOR_ORDER[] = "colorOrder"; + const char CONFIG_AUTOSTART[] = "autoStart"; + const char CONFIG_LATCH_TIME[] = "latchTime"; + const char CONFIG_REWRITE_TIME[] = "rewriteTime"; + + int DEFAULT_LED_COUNT{ 1 }; + const char DEFAULT_COLOR_ORDER[]{ "RGB" }; + const bool DEFAULT_IS_AUTOSTART{ true }; + + const char CONFIG_ENABLE_ATTEMPTS[] = "enableAttempts"; + const char CONFIG_ENABLE_ATTEMPTS_INTERVALL[] = "enableAttemptsInterval"; + + const int DEFAULT_MAX_ENABLE_ATTEMPTS{ 5 }; + constexpr std::chrono::seconds DEFAULT_ENABLE_ATTEMPTS_INTERVAL{ 5 }; + +} //End of constants + +LedDevice::LedDevice(const QJsonObject& deviceConfig, QObject* parent) + : QObject(parent) + , _devConfig(deviceConfig) + , _log(Logger::getInstance("LEDDEVICE")) + , _ledBuffer(0) + , _refreshTimer(nullptr) + , _refreshTimerInterval_ms(0) + , _latchTime_ms(0) + , _ledCount(0) + , _isRestoreOrigState(false) + , _isEnabled(false) + , _isDeviceInitialised(false) + , _isDeviceReady(false) + , _isOn(false) + , _isDeviceInError(false) + , _lastWriteTime(QDateTime::currentDateTime()) + , _enableAttemptsTimer(nullptr) + , _enableAttemptTimerInterval(DEFAULT_ENABLE_ATTEMPTS_INTERVAL) + , _enableAttempts(0) + , _maxEnableAttempts(DEFAULT_MAX_ENABLE_ATTEMPTS) + , _isRefreshEnabled(false) + , _isAutoStart(true) +{ + _activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower(); +} + +LedDevice::~LedDevice() +{ + this->stopEnableAttemptsTimer(); + this->stopRefreshTimer(); +} + +void LedDevice::start() +{ + Info(_log, "Start LedDevice '%s'.", QSTRING_CSTR(_activeDeviceType)); + + close(); + _isDeviceInitialised = false; + + if (init(_devConfig)) + { + // Everything is OK -> enable device + _isDeviceInitialised = true; + + if (_isAutoStart) + { + if (!_isEnabled) + { + Debug(_log, "Not enabled -> enable device"); + enable(); + } + } + } +} + +void LedDevice::stop() +{ + Debug(_log, "Stop device"); + this->disable(); + this->stopRefreshTimer(); + Info(_log, " Stopped LedDevice '%s'", QSTRING_CSTR(_activeDeviceType)); +} + +int LedDevice::open() +{ + _isDeviceReady = true; + int retval = 0; + + return retval; +} + +int LedDevice::close() +{ + _isDeviceReady = false; + int retval = 0; + + return retval; +} + +void LedDevice::setInError(const QString& errorMsg) +{ + _isOn = false; + _isDeviceInError = true; + _isDeviceReady = false; + _isEnabled = false; + this->stopRefreshTimer(); + + Error(_log, "Device disabled, device '%s' signals error: '%s'", QSTRING_CSTR(_activeDeviceType), QSTRING_CSTR(errorMsg)); + emit enableStateChanged(_isEnabled); +} + +void LedDevice::enable() +{ + Debug(_log, "Enable device %s'", QSTRING_CSTR(_activeDeviceType)); + + if (!_isEnabled) + { + if (_enableAttemptsTimer != nullptr && _enableAttemptsTimer->isActive()) + { + _enableAttemptsTimer->stop(); + } + + _isDeviceInError = false; + + if (!_isDeviceInitialised) + { + _isDeviceInitialised = init(_devConfig); + } + + if (!_isDeviceReady) + { + open(); + } + + bool isEnableFailed(true); + + if (_isDeviceReady) + { + if (switchOn()) + { + stopEnableAttemptsTimer(); + _isEnabled = true; + isEnableFailed = false; + emit enableStateChanged(_isEnabled); + Info(_log, "LedDevice '%s' enabled", QSTRING_CSTR(_activeDeviceType)); + } + } + + if (isEnableFailed) + { + emit enableStateChanged(false); + + if (_maxEnableAttempts > 0) + { + Debug(_log, "Device's enablement failed - Start retry timer. Retried already done [%d], isEnabled: [%d]", _enableAttempts, _isEnabled); + startEnableAttemptsTimer(); + } + else + { + Debug(_log, "Device's enablement failed"); + } + } + } +} + +void LedDevice::disable() +{ + Debug(_log, "Disable device %s'", QSTRING_CSTR(_activeDeviceType)); + if (_isEnabled) + { + _isEnabled = false; + this->stopEnableAttemptsTimer(); + this->stopRefreshTimer(); + + switchOff(); + close(); + + emit enableStateChanged(_isEnabled); + } +} + +void LedDevice::setActiveDeviceType(const QString& deviceType) +{ + _activeDeviceType = deviceType; +} + +bool LedDevice::init(const QJsonObject& deviceConfig) +{ + Debug(_log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData()); + + setLedCount(deviceConfig[CONFIG_CURRENT_LED_COUNT].toInt(DEFAULT_LED_COUNT)); // property injected to reflect real led count + setColorOrder(deviceConfig[CONFIG_COLOR_ORDER].toString(DEFAULT_COLOR_ORDER)); + setLatchTime(deviceConfig[CONFIG_LATCH_TIME].toInt(_latchTime_ms)); + setRewriteTime(deviceConfig[CONFIG_REWRITE_TIME].toInt(_refreshTimerInterval_ms)); + setAutoStart(deviceConfig[CONFIG_AUTOSTART].toBool(DEFAULT_IS_AUTOSTART)); + setEnableAttempts(deviceConfig[CONFIG_ENABLE_ATTEMPTS].toInt(DEFAULT_MAX_ENABLE_ATTEMPTS), + std::chrono::seconds(deviceConfig[CONFIG_ENABLE_ATTEMPTS_INTERVALL].toInt(DEFAULT_ENABLE_ATTEMPTS_INTERVAL.count())) + ); + + return true; +} + +void LedDevice::startRefreshTimer() +{ + if (_refreshTimerInterval_ms > 0) + { + if (_isDeviceReady && _isOn) + { + // setup refreshTimer + if (_refreshTimer == nullptr) + { + _refreshTimer = new QTimer(this); + _refreshTimer->setTimerType(Qt::PreciseTimer); + connect(_refreshTimer, &QTimer::timeout, this, &LedDevice::rewriteLEDs); + } + _refreshTimer->setInterval(_refreshTimerInterval_ms); + + //Debug(_log, "Start refresh timer with interval = %ims", _refreshTimer->interval()); + _refreshTimer->start(); + } + else + { + Debug(_log, "Device is not ready to start a refresh timer"); + } + } +} + +void LedDevice::stopRefreshTimer() +{ + if (_refreshTimer != nullptr) + { + //Debug(_log, "Stopping refresh timer"); + _refreshTimer->stop(); + delete _refreshTimer; + _refreshTimer = nullptr; + + } +} + +void LedDevice::startEnableAttemptsTimer() +{ + ++_enableAttempts; + + if (_enableAttempts <= _maxEnableAttempts) + { + if (_enableAttemptTimerInterval.count() > 0) + { + // setup enable retry timer + if (_enableAttemptsTimer == nullptr) + { + _enableAttemptsTimer = new QTimer(this); + _enableAttemptsTimer->setTimerType(Qt::PreciseTimer); + connect(_enableAttemptsTimer, &QTimer::timeout, this, &LedDevice::enable); + } + _enableAttemptsTimer->setInterval(static_cast(_enableAttemptTimerInterval.count() * 1000)); //NOLINT + + Info(_log, "Start %d. attempt of %d to enable the device in %d seconds", _enableAttempts, _maxEnableAttempts, _enableAttemptTimerInterval.count()); + _enableAttemptsTimer->start(); + } + } + else + { + Error(_log, "Device disabled. Maximum number of %d attempts enabling the device reached. Tried for %d seconds.", _maxEnableAttempts, _enableAttempts * _enableAttemptTimerInterval.count()); + _enableAttempts = 0; + } +} + +void LedDevice::stopEnableAttemptsTimer() +{ + if (_enableAttemptsTimer != nullptr) + { + Debug(_log, "Stopping enable retry timer"); + _enableAttemptsTimer->stop(); + delete _enableAttemptsTimer; + _enableAttemptsTimer = nullptr; + _enableAttempts = 0; + } +} + +int LedDevice::updateLeds(std::vector ledValues) +{ + int retval = 0; + if (!_isEnabled || !_isOn || !_isDeviceReady || _isDeviceInError) + { + //std::cout << "LedDevice::updateLeds(), LedDevice NOT ready! "; + retval = -1; + } + else + { + qint64 elapsedTimeMs = _lastWriteTime.msecsTo(QDateTime::currentDateTime()); + if (_latchTime_ms == 0 || elapsedTimeMs >= _latchTime_ms) + { + //std::cout << "LedDevice::updateLeds(), Elapsed time since last write (" << elapsedTimeMs << ") ms > _latchTime_ms (" << _latchTime_ms << ") ms" << std::endl; + retval = write(ledValues); + _lastWriteTime = QDateTime::currentDateTime(); + + // if device requires refreshing, save Led-Values and restart the timer + if (_isRefreshEnabled && _isEnabled) + { + _lastLedValues = ledValues; + this->startRefreshTimer(); + } + } + else + { + //std::cout << "LedDevice::updateLeds(), Skip write. elapsedTime (" << elapsedTimeMs << ") ms < _latchTime_ms (" << _latchTime_ms << ") ms" << std::endl; + if (_isRefreshEnabled) + { + //Stop timer to allow for next non-refresh update + this->stopRefreshTimer(); + } + } + } + return retval; +} + +int LedDevice::rewriteLEDs() +{ + int retval = -1; + + if (_isEnabled && _isOn && _isDeviceReady && !_isDeviceInError) + { + // qint64 elapsedTimeMs = _lastWriteTime.msecsTo(QDateTime::currentDateTime()); + // std::cout << "LedDevice::rewriteLEDs(): Rewrite LEDs now, elapsedTime [" << elapsedTimeMs << "] ms" << std::endl; + // //:TESTING: Inject "white" output records to differentiate from normal writes + // _lastLedValues.clear(); + // _lastLedValues.resize(static_cast(_ledCount), ColorRgb::WHITE); + // printLedValues(_lastLedValues); + // //:TESTING: + + if (!_lastLedValues.empty()) + { + retval = write(_lastLedValues); + _lastWriteTime = QDateTime::currentDateTime(); + } + } + else + { + // If Device is not ready stop timer + this->stopRefreshTimer(); + } + return retval; +} + +int LedDevice::writeBlack(int numberOfWrites) +{ + Debug(_log, "Set LED strip to black to switch of LEDs"); + return writeColor(ColorRgb::BLACK, numberOfWrites); +} + +int LedDevice::writeColor(const ColorRgb& color, int numberOfWrites) +{ + int rc = -1; + + for (int i = 0; i < numberOfWrites; i++) + { + if (_latchTime_ms > 0) + { + // Wait latch time before writing black + QEventLoop loop; + QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit); + loop.exec(); + } + _lastLedValues = std::vector(static_cast(_ledCount), color); + rc = write(_lastLedValues); + } + return rc; +} + +bool LedDevice::switchOn() +{ + bool rc{ false }; + + if (_isOn) + { + Debug(_log, "Device %s is already on. Skipping.", QSTRING_CSTR(_activeDeviceType)); + rc = true; + } + else + { + if (_isDeviceReady) + { + Info(_log, "Switching device %s ON", QSTRING_CSTR(_activeDeviceType)); + if (storeState()) + { + if (powerOn()) + { + Info(_log, "Device %s is ON", QSTRING_CSTR(_activeDeviceType)); + _isOn = true; + emit enableStateChanged(_isEnabled); + rc = true; + } + else + { + Warning(_log, "Failed switching device %s ON", QSTRING_CSTR(_activeDeviceType)); + } + } + } + } + return rc; +} + +bool LedDevice::switchOff() +{ + bool rc{ false }; + + if (!_isOn) + { + rc = true; + } + else + { + if (_isDeviceInitialised) + { + Info(_log, "Switching device %s OFF", QSTRING_CSTR(_activeDeviceType)); + + // Disable device to ensure no standard LED updates are written/processed + _isOn = false; + + rc = true; + + if (_isDeviceReady) + { + if (_isRestoreOrigState) + { + //Restore devices state + restoreState(); + } + else + { + if (powerOff()) + { + Info(_log, "Device %s is OFF", QSTRING_CSTR(_activeDeviceType)); + } + else + { + Warning(_log, "Failed switching device %s OFF", QSTRING_CSTR(_activeDeviceType)); + } + } + } + } + } + return rc; +} + +bool LedDevice::powerOff() +{ + bool rc{ false }; + + Debug(_log, "Power Off: %s", QSTRING_CSTR(_activeDeviceType)); + + // Simulate power-off by writing a final "Black" to have a defined outcome + if (writeBlack() >= 0) + { + rc = true; + } + return rc; +} + +bool LedDevice::powerOn() +{ + bool rc{ true }; + + Debug(_log, "Power On: %s", QSTRING_CSTR(_activeDeviceType)); + + return rc; +} + +bool LedDevice::storeState() +{ + bool rc{ true }; + + if (_isRestoreOrigState) + { + // Save device's original state + // _originalStateValues = get device's state; + // store original power on/off state, if available + } + return rc; +} + +bool LedDevice::restoreState() +{ + bool rc{ true }; + + if (_isRestoreOrigState) + { + // Restore device's original state + // update device using _originalStateValues + // update original power on/off state, if supported + } + return rc; +} + +QJsonObject LedDevice::discover(const QJsonObject& /*params*/) +{ + QJsonObject devicesDiscovered; + + devicesDiscovered.insert("ledDeviceType", _activeDeviceType); + + QJsonArray deviceList; + devicesDiscovered.insert("devices", deviceList); + + Debug(_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData()); + return devicesDiscovered; +} + +QString LedDevice::discoverFirst() +{ + QString deviceDiscovered; + + Debug(_log, "deviceDiscovered: [%s]", QSTRING_CSTR(deviceDiscovered)); + return deviceDiscovered; +} + + +QJsonObject LedDevice::getProperties(const QJsonObject& params) +{ + Debug(_log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData()); + + QJsonObject properties; + + QJsonObject deviceProperties; + properties.insert("properties", deviceProperties); + + Debug(_log, "properties: [%s]", QString(QJsonDocument(properties).toJson(QJsonDocument::Compact)).toUtf8().constData()); + + return properties; +} + +void LedDevice::setLogger(Logger* log) +{ + _log = log; +} + +void LedDevice::setLedCount(int ledCount) +{ + assert(ledCount >= 0); + _ledCount = static_cast(ledCount); + _ledRGBCount = _ledCount * sizeof(ColorRgb); + _ledRGBWCount = _ledCount * sizeof(ColorRgbw); + Debug(_log, "LedCount set to %d", _ledCount); +} + +void LedDevice::setColorOrder(const QString& colorOrder) +{ + _colorOrder = colorOrder; + Debug(_log, "ColorOrder set to %s", QSTRING_CSTR(_colorOrder.toUpper())); +} + +void LedDevice::setLatchTime(int latchTime_ms) +{ + assert(latchTime_ms >= 0); + _latchTime_ms = latchTime_ms; + Debug(_log, "LatchTime set to %dms", _latchTime_ms); +} + +void LedDevice::setAutoStart(bool isAutoStart) +{ + _isAutoStart = isAutoStart; + Debug(_log, "AutoStart %s", (_isAutoStart ? "enabled" : "disabled")); +} + +void LedDevice::setRewriteTime(int rewriteTime_ms) +{ + _refreshTimerInterval_ms = qMax(rewriteTime_ms, 0); + + if (_refreshTimerInterval_ms > 0) + { + _isRefreshEnabled = true; + + if (_refreshTimerInterval_ms <= _latchTime_ms) + { + int new_refresh_timer_interval = _latchTime_ms + 10; //NOLINT + Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval); + _refreshTimerInterval_ms = new_refresh_timer_interval; + } + + Debug(_log, "Refresh interval = %dms", _refreshTimerInterval_ms); + startRefreshTimer(); + } + else + { + _isRefreshEnabled = false; + stopRefreshTimer(); + } +} + +void LedDevice::setEnableAttempts(int maxEnableRetries, std::chrono::seconds enableRetryTimerInterval) +{ + stopEnableAttemptsTimer(); + maxEnableRetries = qMax(maxEnableRetries, 0); + + _enableAttempts = 0; + _maxEnableAttempts = maxEnableRetries; + _enableAttemptTimerInterval = enableRetryTimerInterval; + + Debug(_log, "Max enable retries: %d, enable retry interval = %llds", _maxEnableAttempts, _enableAttemptTimerInterval.count()); +} + +void LedDevice::printLedValues(const std::vector& ledValues) +{ + std::cout << "LedValues [" << ledValues.size() << "] ["; + for (const ColorRgb& color : ledValues) + { + std::cout << color; + } + std::cout << "]" << std::endl; +} + +QString LedDevice::uint8_t_to_hex_string(const uint8_t* data, const int size, int number) +{ + if (number <= 0 || number > size) + { + number = size; + } + + QByteArray bytes(reinterpret_cast(data), number); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return bytes.toHex(':'); +#else + return bytes.toHex(); +#endif +} + +QString LedDevice::toHex(const QByteArray& data, int number) +{ + if (number <= 0 || number > data.size()) + { + number = data.size(); + } + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return data.left(number).toHex(':'); +#else + return data.left(number).toHex(); +#endif +} +bool LedDevice::isInitialised() const +{ + return _isDeviceInitialised; +} + +bool LedDevice::isReady() const +{ + return _isDeviceReady; +} + +bool LedDevice::isInError() const +{ + return _isDeviceInError; +} + +int LedDevice::getLatchTime() const +{ + return _latchTime_ms; +} + +int LedDevice::getRewriteTime() const +{ + return _refreshTimerInterval_ms; +} + +int LedDevice::getLedCount() const +{ + return static_cast(_ledCount); +} + +QString LedDevice::getActiveDeviceType() const +{ + return _activeDeviceType; +} + +QString LedDevice::getColorOrder() const +{ + return _colorOrder; +} + +bool LedDevice::componentState() const { + return _isEnabled; +} + diff --git a/libsrc/leddevice/dev_net/LedDeviceRazer.cpp b/libsrc/leddevice/dev_net/LedDeviceRazer.cpp index 8637a31a..697b5c92 100644 --- a/libsrc/leddevice/dev_net/LedDeviceRazer.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceRazer.cpp @@ -279,7 +279,7 @@ int LedDeviceRazer::write(const std::vector& ledValues) for (int col = 0; col < _maxColumn; col++) { int pos = row * _maxColumn + col; int bgrColor; - if (pos < ledValues.size()) + if (pos < static_cast(ledValues.size())) { bgrColor = (ledValues[pos].red * 65536) + (ledValues[pos].green * 256) + ledValues[pos].blue; } diff --git a/libsrc/leddevice/dev_net/ProviderRestApi.cpp b/libsrc/leddevice/dev_net/ProviderRestApi.cpp index 6957891c..b1fe965e 100644 --- a/libsrc/leddevice/dev_net/ProviderRestApi.cpp +++ b/libsrc/leddevice/dev_net/ProviderRestApi.cpp @@ -14,8 +14,6 @@ // Constants namespace { -bool verbose = false; - const QChar ONE_SLASH = '/'; const int HTTP_STATUS_NO_CONTENT = 204; diff --git a/libsrc/protoserver/ProtoClientConnection.cpp b/libsrc/protoserver/ProtoClientConnection.cpp index 247d4ff1..bf59c833 100644 --- a/libsrc/protoserver/ProtoClientConnection.cpp +++ b/libsrc/protoserver/ProtoClientConnection.cpp @@ -198,6 +198,7 @@ void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &messag } emit setGlobalInputImage(_priority, imageRGB, duration); + emit setBufferImage("ProtoBuffer", imageRGB); // send reply sendSuccessReply(); diff --git a/libsrc/protoserver/ProtoClientConnection.h b/libsrc/protoserver/ProtoClientConnection.h index 28d0b6b7..049d9852 100644 --- a/libsrc/protoserver/ProtoClientConnection.h +++ b/libsrc/protoserver/ProtoClientConnection.h @@ -56,6 +56,11 @@ signals: /// void setGlobalInputColor(int priority, const std::vector &ledColor, int timeout_ms, const QString& origin = "ProtoBuffer" ,bool clearEffects = true); + /// + /// @brief Emit the final processed image + /// + void setBufferImage(const QString& name, const Image& image); + /// /// @brief Emits whenever the client disconnected /// diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp index 5ba8d98a..aa806125 100644 --- a/libsrc/protoserver/ProtoServer.cpp +++ b/libsrc/protoserver/ProtoServer.cpp @@ -80,6 +80,7 @@ void ProtoServer::newConnection() connect(client, &ProtoClientConnection::clearGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearGlobalInput); connect(client, &ProtoClientConnection::setGlobalInputImage, GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage); connect(client, &ProtoClientConnection::setGlobalInputColor, GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor); + connect(client, &ProtoClientConnection::setBufferImage, GlobalSignals::getInstance(), &GlobalSignals::setBufferImage); connect(GlobalSignals::getInstance(), &GlobalSignals::globalRegRequired, client, &ProtoClientConnection::registationRequired); _openConnections.append(client); }