diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index 3539db3a..7d78ed18 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -29,7 +29,13 @@ public: unsigned getLedCount() const; - void setValue(int priority, std::vector &ledColors, const int timeout_ms); + void setColor(int priority, RgbColor &ledColor, const int timeout_ms); + + void setColors(int priority, std::vector &ledColors, const int timeout_ms); + + void clear(int priority); + + void clearall(); private slots: void update(); @@ -37,15 +43,15 @@ private slots: private: void applyTransform(std::vector& colors) const; - LedString mLedString; + LedString _ledString; - PriorityMuxer mMuxer; + PriorityMuxer _muxer; - hyperion::ColorTransform* mRedTransform; - hyperion::ColorTransform* mGreenTransform; - hyperion::ColorTransform* mBlueTransform; + hyperion::ColorTransform* _redTransform; + hyperion::ColorTransform* _greenTransform; + hyperion::ColorTransform* _blueTransform; - LedDevice* mDevice; + LedDevice* _device; QTimer _timer; }; diff --git a/include/hyperion/PriorityMuxer.h b/include/hyperion/PriorityMuxer.h index c2e05fdf..73ca7694 100644 --- a/include/hyperion/PriorityMuxer.h +++ b/include/hyperion/PriorityMuxer.h @@ -26,7 +26,7 @@ public: std::vector ledColors; }; - PriorityMuxer(); + PriorityMuxer(int ledCount); ~PriorityMuxer(); @@ -47,9 +47,11 @@ public: void setCurrentTime(const int64_t& now); private: - int mCurrentPriority; + int _currentPriority; - QMap mActiveInputs; + QMap _activeInputs; - const static int MAX_PRIORITY = std::numeric_limits::max(); + InputInfo _lowestPriorityInfo; + + const static int LOWEST_PRIORITY = std::numeric_limits::max(); }; diff --git a/libsrc/dispmanx-grabber/DispmanxWrapper.cpp b/libsrc/dispmanx-grabber/DispmanxWrapper.cpp index 413159ed..ad8261f8 100644 --- a/libsrc/dispmanx-grabber/DispmanxWrapper.cpp +++ b/libsrc/dispmanx-grabber/DispmanxWrapper.cpp @@ -53,7 +53,7 @@ void DispmanxWrapper::action() _processor->process(_image, _ledColors); - _hyperion->setValue(_priority, _ledColors, _timeout_ms); + _hyperion->setColors(_priority, _ledColors, _timeout_ms); } void DispmanxWrapper::stop() { diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index 5ad60f52..64c1db85 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -76,74 +76,108 @@ LedString Hyperion::createLedString(const Json::Value& ledsConfig) } Hyperion::Hyperion(const Json::Value &jsonConfig) : - mLedString(createLedString(jsonConfig["leds"])), - mRedTransform( createColorTransform(jsonConfig["color"]["red"])), - mGreenTransform(createColorTransform(jsonConfig["color"]["green"])), - mBlueTransform( createColorTransform(jsonConfig["color"]["blue"])), - mDevice(constructDevice(jsonConfig["device"])), + _ledString(createLedString(jsonConfig["leds"])), + _muxer(_ledString.leds().size()), + _redTransform(createColorTransform(jsonConfig["color"]["red"])), + _greenTransform(createColorTransform(jsonConfig["color"]["green"])), + _blueTransform(createColorTransform(jsonConfig["color"]["blue"])), + _device(constructDevice(jsonConfig["device"])), _timer() { - ImageProcessorFactory::getInstance().init(mLedString); + ImageProcessorFactory::getInstance().init(_ledString); _timer.setSingleShot(true); QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update())); + // initialize the leds + update(); } Hyperion::~Hyperion() { // Delete the Led-String - delete mDevice; + delete _device; // Delete the color-transform - delete mBlueTransform; - delete mGreenTransform; - delete mRedTransform; + delete _blueTransform; + delete _greenTransform; + delete _redTransform; } unsigned Hyperion::getLedCount() const { - return mLedString.leds().size(); + return _ledString.leds().size(); } -void Hyperion::setValue(int priority, std::vector& ledColors, const int timeout_ms) +void Hyperion::setColor(int priority, RgbColor & color, const int timeout_ms) +{ + // create led output + std::vector ledColors(_ledString.leds().size(), color); + + // set colors + setColors(priority, ledColors, timeout_ms); +} + +void Hyperion::setColors(int priority, std::vector& ledColors, const int timeout_ms) { // Apply the transform to each led and color-channel for (RgbColor& color : ledColors) { - color.red = mRedTransform->transform(color.red); - color.green = mGreenTransform->transform(color.green); - color.blue = mBlueTransform->transform(color.blue); + color.red = _redTransform->transform(color.red); + color.green = _greenTransform->transform(color.green); + color.blue = _blueTransform->transform(color.blue); } if (timeout_ms > 0) { const uint64_t timeoutTime = QDateTime::currentMSecsSinceEpoch() + timeout_ms; - mMuxer.setInput(priority, ledColors, timeoutTime); + _muxer.setInput(priority, ledColors, timeoutTime); } else { - mMuxer.setInput(priority, ledColors); + _muxer.setInput(priority, ledColors); } - if (priority == mMuxer.getCurrentPriority()) + if (priority == _muxer.getCurrentPriority()) { update(); } } +void Hyperion::clear(int priority) +{ + if (_muxer.hasPriority(priority)) + { + _muxer.clearInput(priority); + + // update leds if necessary + if (priority < _muxer.getCurrentPriority()); + { + update(); + } + } +} + +void Hyperion::clearall() +{ + _muxer.clearAll(); + + // update leds + update(); +} + void Hyperion::update() { // Update the muxer, cleaning obsolete priorities - mMuxer.setCurrentTime(QDateTime::currentMSecsSinceEpoch()); + _muxer.setCurrentTime(QDateTime::currentMSecsSinceEpoch()); // Obtain the current priority channel - int priority = mMuxer.getCurrentPriority(); - const PriorityMuxer::InputInfo & priorityInfo = mMuxer.getInputInfo(priority); + int priority = _muxer.getCurrentPriority(); + const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority); // Write the data to the device - mDevice->write(priorityInfo.ledColors); + _device->write(priorityInfo.ledColors); // Start the timeout-timer if (priorityInfo.timeoutTime_ms == -1) diff --git a/libsrc/hyperion/PriorityMuxer.cpp b/libsrc/hyperion/PriorityMuxer.cpp index 2321cccd..c8aa98a3 100644 --- a/libsrc/hyperion/PriorityMuxer.cpp +++ b/libsrc/hyperion/PriorityMuxer.cpp @@ -6,10 +6,14 @@ // Hyperion includes #include -PriorityMuxer::PriorityMuxer() : - mCurrentPriority(MAX_PRIORITY) +PriorityMuxer::PriorityMuxer(int ledCount) : + _currentPriority(LOWEST_PRIORITY), + _activeInputs(), + _lowestPriorityInfo() { - // empty + _lowestPriorityInfo.priority = LOWEST_PRIORITY; + _lowestPriorityInfo.timeoutTime_ms = -1; + _lowestPriorityInfo.ledColors = std::vector(ledCount, {0, 0, 0}); } PriorityMuxer::~PriorityMuxer() @@ -19,23 +23,28 @@ PriorityMuxer::~PriorityMuxer() int PriorityMuxer::getCurrentPriority() const { - return mCurrentPriority; + return _currentPriority; } QList PriorityMuxer::getPriorities() const { - return mActiveInputs.keys(); + return _activeInputs.keys(); } bool PriorityMuxer::hasPriority(const int priority) const { - return mActiveInputs.contains(priority); + return _activeInputs.contains(priority); } const PriorityMuxer::InputInfo& PriorityMuxer::getInputInfo(const int priority) const { - auto elemIt = mActiveInputs.find(priority); - if (elemIt == mActiveInputs.end()) + if (priority == LOWEST_PRIORITY) + { + return _lowestPriorityInfo; + } + + auto elemIt = _activeInputs.find(priority); + if (elemIt == _activeInputs.end()) { throw std::runtime_error("no such priority"); } @@ -44,50 +53,50 @@ const PriorityMuxer::InputInfo& PriorityMuxer::getInputInfo(const int priority) void PriorityMuxer::setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms) { - InputInfo& input = mActiveInputs[priority]; + InputInfo& input = _activeInputs[priority]; input.priority = priority; input.timeoutTime_ms = timeoutTime_ms; input.ledColors = ledColors; - mCurrentPriority = std::min(mCurrentPriority, priority); + _currentPriority = std::min(_currentPriority, priority); } void PriorityMuxer::clearInput(const int priority) { - mActiveInputs.remove(priority); - if (mCurrentPriority == priority) + _activeInputs.remove(priority); + if (_currentPriority == priority) { - if (mActiveInputs.empty()) + if (_activeInputs.empty()) { - mCurrentPriority = MAX_PRIORITY; + _currentPriority = LOWEST_PRIORITY; } else { - QList keys = mActiveInputs.keys(); - mCurrentPriority = *std::min_element(keys.begin(), keys.end()); + QList keys = _activeInputs.keys(); + _currentPriority = *std::min_element(keys.begin(), keys.end()); } } } void PriorityMuxer::clearAll() { - mActiveInputs.clear(); - mCurrentPriority = MAX_PRIORITY; + _activeInputs.clear(); + _currentPriority = LOWEST_PRIORITY; } void PriorityMuxer::setCurrentTime(const int64_t& now) { - mCurrentPriority = MAX_PRIORITY; + _currentPriority = LOWEST_PRIORITY; - for (auto infoIt = mActiveInputs.begin(); infoIt != mActiveInputs.end();) + for (auto infoIt = _activeInputs.begin(); infoIt != _activeInputs.end();) { if (infoIt->timeoutTime_ms != -1 && infoIt->timeoutTime_ms <= now) { - infoIt = mActiveInputs.erase(infoIt); + infoIt = _activeInputs.erase(infoIt); } else { - mCurrentPriority = std::min(mCurrentPriority, infoIt->priority); + _currentPriority = std::min(_currentPriority, infoIt->priority); ++infoIt; } } diff --git a/libsrc/jsonserver/JsonClientConnection.cpp b/libsrc/jsonserver/JsonClientConnection.cpp index c9cc1b4f..eddb78e2 100644 --- a/libsrc/jsonserver/JsonClientConnection.cpp +++ b/libsrc/jsonserver/JsonClientConnection.cpp @@ -76,7 +76,7 @@ void JsonClientConnection::handleMessage(const std::string &messageString) // check specific message const std::string command = message["command"].asString(); - if (!checkJson(message, QString("schema-%1").arg(QString::fromStdString(command)), errors)) + if (!checkJson(message, QString(":schema-%1").arg(QString::fromStdString(command)), errors)) { sendErrorReply("Error while validating json: " + errors); return; @@ -104,14 +104,10 @@ void JsonClientConnection::handleColorCommand(const Json::Value &message) // extract parameters int priority = message["priority"].asInt(); int duration = message.get("duration", -1).asInt(); - RgbColor color = {message["color"][0u].asInt(), message["color"][1u].asInt(), message["color"][2u].asInt()}; - - - // create led output - std::vector ledColors(_hyperion->getLedCount(), color); + RgbColor color = {uint8_t(message["color"][0u].asInt()), uint8_t(message["color"][1u].asInt()), uint8_t(message["color"][2u].asInt())}; // set output - _hyperion->setValue(priority, ledColors, duration); + _hyperion->setColor(priority, color, duration); // send reply sendSuccessReply(); @@ -129,12 +125,23 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &message) void JsonClientConnection::handleClearCommand(const Json::Value &message) { - handleNotImplemented(); + // extract parameters + int priority = message["priority"].asInt(); + + // clear priority + _hyperion->clear(priority); + + // send reply + sendSuccessReply(); } -void JsonClientConnection::handleClearallCommand(const Json::Value &message) +void JsonClientConnection::handleClearallCommand(const Json::Value &) { - handleNotImplemented(); + // clear priority + _hyperion->clearall(); + + // send reply + sendSuccessReply(); } void JsonClientConnection::handleTransformCommand(const Json::Value &message) diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index 56c98a95..16c833b9 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -44,7 +44,7 @@ int main(int argc, char * argv[]) ImageParameter & argImage = parameters.add ('i', "image" , "Set the leds to the colors according to the given image file"); SwitchParameter<> & argServerInfo = parameters.add >('s', "info" , "List server info"); SwitchParameter<> & argClear = parameters.add >('x', "clear" , "Clear data for the priority channel provided by the -p option"); - SwitchParameter<> & argClearAll = parameters.add >(0x0, "clear-all" , "Clear data for all priority channels"); + SwitchParameter<> & argClearAll = parameters.add >(0x0, "clearall" , "Clear data for all active priority channels"); TransformParameter & argGamma = parameters.add('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)"); TransformParameter & argThreshold = parameters.add('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)"); TransformParameter & argBlacklevel = parameters.add('b', "blacklevel", "Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");