diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..b821038f --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc-5", + "intelliSenseMode": "gcc-x64", + "cppStandard": "c++11", + "cStandard": "c11", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/assets/webconfig/js/content_leds.js b/assets/webconfig/js/content_leds.js index 7bd132ad..b65b3825 100644 --- a/assets/webconfig/js/content_leds.js +++ b/assets/webconfig/js/content_leds.js @@ -40,10 +40,10 @@ function createLedPreview(leds, origin){ var led = leds[idx]; var led_id='ledc_'+[idx]; var bgcolor = "background-color:hsl("+(idx*360/leds.length)+",100%,50%);"; - var pos = "left:"+(led.h.min * canvas_width)+"px;"+ - "top:"+(led.v.min * canvas_height)+"px;"+ - "width:"+((led.h.max-led.h.min) * (canvas_width-1))+"px;"+ - "height:"+((led.v.max-led.v.min) * (canvas_height-1))+"px;"; + var pos = "left:"+(led.hmin * canvas_width)+"px;"+ + "top:"+(led.vmin * canvas_height)+"px;"+ + "width:"+((led.hmax-led.hmin) * (canvas_width-1))+"px;"+ + "height:"+((led.vmax-led.vmin) * (canvas_height-1))+"px;"; leds_html += '
'+idx+'
'; } $('#leds_preview').html(leds_html); @@ -91,11 +91,11 @@ function createClassicLeds(){ function createFinalArray(array){ finalLedArray = []; for(var i = 0; i & image); diff --git a/include/grabber/V4L2Wrapper.h b/include/grabber/V4L2Wrapper.h index c805d72d..00744f25 100644 --- a/include/grabber/V4L2Wrapper.h +++ b/include/grabber/V4L2Wrapper.h @@ -27,7 +27,7 @@ public slots: void setDeviceVideoStandard(QString device, VideoStandard videoStandard); signals: - void componentStateChanged(const hyperion::Components component, bool enable); + void compStateChangeRequest(const hyperion::Components component, bool enable); private slots: void newFrame(const Image & image); diff --git a/include/hyperion/BGEffectHandler.h b/include/hyperion/BGEffectHandler.h index 3ca229dc..9dc6563c 100644 --- a/include/hyperion/BGEffectHandler.h +++ b/include/hyperion/BGEffectHandler.h @@ -46,13 +46,15 @@ private slots: const QJsonValue bgColorConfig = BGEffectConfig["color"]; if (bgTypeConfig.contains("color")) { - ColorRgb bg_color = { - (uint8_t)BGCONFIG_ARRAY.at(0).toInt(0), - (uint8_t)BGCONFIG_ARRAY.at(1).toInt(0), - (uint8_t)BGCONFIG_ARRAY.at(2).toInt(0) + std::vector bg_color = { + ColorRgb { + (uint8_t)BGCONFIG_ARRAY.at(0).toInt(0), + (uint8_t)BGCONFIG_ARRAY.at(1).toInt(0), + (uint8_t)BGCONFIG_ARRAY.at(2).toInt(0) + } }; _hyperion->setColor(254, bg_color); - Info(Logger::getInstance("HYPERION"),"Inital background color set (%d %d %d)",bg_color.red,bg_color.green,bg_color.blue); + Info(Logger::getInstance("HYPERION"),"Inital background color set (%d %d %d)",bg_color.at(0).red, bg_color.at(0).green, bg_color.at(0).blue); } else { diff --git a/include/hyperion/CaptureCont.h b/include/hyperion/CaptureCont.h index 3c7e866c..55693b91 100644 --- a/include/hyperion/CaptureCont.h +++ b/include/hyperion/CaptureCont.h @@ -28,7 +28,7 @@ private slots: /// @param component The component from enum /// @param enable The new state /// - void componentStateChanged(const hyperion::Components component, bool enable); + void handleCompStateChangeRequest(const hyperion::Components component, bool enable); /// /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor diff --git a/include/hyperion/ComponentRegister.h b/include/hyperion/ComponentRegister.h index 4f1a13c6..f10ad3b6 100644 --- a/include/hyperion/ComponentRegister.h +++ b/include/hyperion/ComponentRegister.h @@ -22,14 +22,6 @@ public: ComponentRegister(Hyperion* hyperion); ~ComponentRegister(); - /// - /// @brief Enable or disable Hyperion (all components) - /// @param state The new state of Hyperion - /// - /// @return Returns true on success, false when Hyperion is already at the requested state - /// - bool setHyperionEnable(const bool& state); - /// /// @brief Check if a component is currently enabled /// @param comp The component from enum @@ -50,11 +42,17 @@ signals: public slots: /// - /// @brief is called whenever a component change a state, DO NOT CALL FROM API (use hyperion->setComponentState() instead) + /// @brief is called whenever a component change a state, DO NOT CALL FROM API, use signal hyperion->compStateChangeRequest /// @param comp The component /// @param state The new state of the component /// - void componentStateChanged(const hyperion::Components comp, const bool activated); + void setNewComponentState(const hyperion::Components comp, const bool activated); + +private slots: + /// + /// @brief Handle COMP_ALL changes from Hyperion->compStateChangeRequest + /// + void handleCompStateChangeRequest(const hyperion::Components comp, const bool activated); private: /// Hyperion instance @@ -65,4 +63,6 @@ private: std::map _componentStates; /// on hyperion off we save the previous states of all components std::map _prevComponentStates; + // helper to prevent self emit chains + bool _inProgress = false; }; diff --git a/include/hyperion/Grabber.h b/include/hyperion/Grabber.h index cb0c3171..c163d36a 100644 --- a/include/hyperion/Grabber.h +++ b/include/hyperion/Grabber.h @@ -101,7 +101,7 @@ signals: /// /// @brief PIPE component state changes from HyperionDaemon to V4L2Grabber /// - void componentStateChanged(const hyperion::Components component, bool enable); + void compStateChangeRequest(const hyperion::Components component, bool enable); protected: ImageResampler _imageResampler; diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index f4f25166..e4c585d6 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -206,12 +206,17 @@ public: void setNewComponentState(const hyperion::Components& component, const bool& state); /// - /// @brief Enable/Disable components during runtime, called from external API (requests) + /// @brief Get a list of all contrable components and their current state + /// @return list of components /// - /// @param component The component from enum - /// @param state The state of the component [true | false] + std::map getAllComponents(); + /// - void setComponentState(const hyperion::Components component, const bool state); + /// @brief Test if a component is enabled + /// @param The component to test + /// @return Component state + /// + int isComponentEnabled(const hyperion::Components& comp); ComponentRegister& getComponentRegister() { return _componentRegister; }; @@ -278,12 +283,12 @@ public slots: /// Should be never used to update leds continuous /// /// @param[in] priority The priority of the written color - /// @param[in] ledColor The color to write to the leds + /// @param[in] ledColors The color to write to the leds /// @param[in] timeout_ms The time the leds are set to the given color [ms] /// @param[in] origin The setter /// @param clearEffect Should be true when NOT called from an effect /// - void setColor(const int priority, const ColorRgb &ledColor, const int timeout_ms = -1, const QString& origin = "System" ,bool clearEffects = true); + void setColor(const int priority, const std::vector &ledColors, const int timeout_ms = -1, const QString& origin = "System" ,bool clearEffects = true); /// /// @brief Set the given priority to inactive @@ -311,15 +316,11 @@ public slots: /// Clears the given priority channel. This will switch the led-colors to the colors of the next /// lower priority channel (or off if no more channels are set) /// - /// @param[in] priority The priority channel + /// @param[in] priority The priority channel. -1 clears all priorities + /// @param[in] forceClearAll Force the clear /// @return True on success else false (not found) /// - bool clear(const int priority); - - /// - /// @brief Clears all priority channels. This will switch the leds off until a new priority is written. - /// - void clearall(bool forceClearAll=false); + bool clear(const int priority, bool forceClearAll=false); /// Run the specified effect on the given priority channel and optionally specify a timeout /// @param effectName Name of the effec to run @@ -375,7 +376,7 @@ signals: /// @param component The component from enum /// @param enabled The new state of the component /// - void componentStateChanged(const hyperion::Components component, bool enabled); + void compStateChangeRequest(const hyperion::Components component, bool enabled); /// /// @brief Emits whenever the imageToLedsMapping has changed diff --git a/include/hyperion/HyperionIManager.h b/include/hyperion/HyperionIManager.h index 7a8134d5..1c36f3a6 100644 --- a/include/hyperion/HyperionIManager.h +++ b/include/hyperion/HyperionIManager.h @@ -130,7 +130,7 @@ signals: /// /// @brief PIPE component state changes from Hyperion to HyperionDaemon /// - void componentStateChanged(const hyperion::Components component, bool enable); + void compStateChangeRequest(const hyperion::Components component, bool enable); private slots: /// diff --git a/include/hyperion/MessageForwarder.h b/include/hyperion/MessageForwarder.h index eaf7ef4b..7c0ceb4c 100644 --- a/include/hyperion/MessageForwarder.h +++ b/include/hyperion/MessageForwarder.h @@ -52,7 +52,7 @@ private slots: /// @param component The component from enum /// @param enable The new state /// - void componentStateChanged(const hyperion::Components component, bool enable); + void handleCompStateChangeRequest(const hyperion::Components component, bool enable); /// /// @brief Handle priority updates from Priority Muxer diff --git a/include/hyperion/SettingsManager.h b/include/hyperion/SettingsManager.h index 498d58ec..d14a31d6 100644 --- a/include/hyperion/SettingsManager.h +++ b/include/hyperion/SettingsManager.h @@ -53,6 +53,14 @@ signals: void settingsChanged(const settings::type& type, const QJsonDocument& data); private: + /// + /// @brief Add possile migrations steps for config here + /// @param config The configuration object + /// @return True when a migration has been triggered + /// + bool handleConfigUpgrade(QJsonObject& config); + + /// Hyperion instance Hyperion* _hyperion; diff --git a/include/ssdp/SSDPHandler.h b/include/ssdp/SSDPHandler.h index 1ded1ce3..756b4dee 100644 --- a/include/ssdp/SSDPHandler.h +++ b/include/ssdp/SSDPHandler.h @@ -19,7 +19,7 @@ class QNetworkConfigurationManager; class SSDPHandler : public SSDPServer{ Q_OBJECT public: - SSDPHandler(WebServer* webserver, const quint16& flatBufPort, const quint16& jsonServerPort, QObject * parent = nullptr); + SSDPHandler(WebServer* webserver, const quint16& flatBufPort, const quint16& jsonServerPort, const QString &name, QObject * parent = nullptr); ~SSDPHandler(); public slots: diff --git a/include/ssdp/SSDPServer.h b/include/ssdp/SSDPServer.h index 2485026d..983c9414 100644 --- a/include/ssdp/SSDPServer.h +++ b/include/ssdp/SSDPServer.h @@ -93,6 +93,17 @@ public: /// quint16 getJsonServerPort() { return _jssPort.toInt(); }; + /// + /// @brief set new hyperion name + /// + void setHyperionName(const QString &name) { _name = name; }; + + /// + /// @brief get hyperion name + /// + QString getHyperionName() { return _name; }; + + signals: /// /// @brief Emits whenever a new SSDP search "man : ssdp:discover" is received along with the service type @@ -111,6 +122,7 @@ private: QString _uuid; QString _fbsPort; QString _jssPort; + QString _name; QString _descAddress; bool _running; diff --git a/include/utils/GlobalSignals.h b/include/utils/GlobalSignals.h index 4f5acc67..07864171 100644 --- a/include/utils/GlobalSignals.h +++ b/include/utils/GlobalSignals.h @@ -58,14 +58,10 @@ signals: /// /// @brief PIPE the clear command for the global priority channel over HyperionDaemon to Hyperion class - /// @param[in] priority The priority channel + /// @param[in] priority The priority channel (-1 to clear all possible priorities) + /// @param[in] forceclearAll Force the clear /// - void clearGlobalInput(int priority); - - /// - /// @brief PIPE the clearAll command over HyperionDaemon to Hyperion class - /// - void clearAllGlobalInput(bool forceClearAll=false); + void clearGlobalInput(int priority, bool forceClearAll=false); /// /// @brief PIPE external images over HyperionDaemon to Hyperion class @@ -84,7 +80,7 @@ signals: /// @param[in] origin The setter /// @param clearEffect Should be true when NOT called from an effect /// - void setGlobalColor(const int priority, const ColorRgb &ledColor, const int timeout_ms, const QString& origin = "External" ,bool clearEffects = true); + void setGlobalColor(const int priority, const std::vector &ledColor, const int timeout_ms, const QString& origin = "External" ,bool clearEffects = true); /////////////////////////////////////// //////////// FROM HYPERION //////////// diff --git a/include/utils/hyperion.h b/include/utils/hyperion.h index 7c19e295..a992ad01 100644 --- a/include/utils/hyperion.h +++ b/include/utils/hyperion.h @@ -34,13 +34,15 @@ namespace hyperion { } if ( fgTypeConfig.contains("color") ) { - ColorRgb fg_color = { - (uint8_t)FGCONFIG_ARRAY.at(0).toInt(0), - (uint8_t)FGCONFIG_ARRAY.at(1).toInt(0), - (uint8_t)FGCONFIG_ARRAY.at(2).toInt(0) + std::vector fg_color = { + ColorRgb { + (uint8_t)FGCONFIG_ARRAY.at(0).toInt(0), + (uint8_t)FGCONFIG_ARRAY.at(1).toInt(0), + (uint8_t)FGCONFIG_ARRAY.at(2).toInt(0) + } }; hyperion->setColor(FG_PRIORITY, fg_color, fg_duration_ms); - Info(Logger::getInstance("HYPERION"),"Initial foreground color set (%d %d %d)",fg_color.red,fg_color.green,fg_color.blue); + Info(Logger::getInstance("HYPERION"),"Initial foreground color set (%d %d %d)",fg_color.at(0).red,fg_color.at(0).green,fg_color.at(0).blue); } else { @@ -195,15 +197,13 @@ namespace hyperion { for (signed i = 0; i < ledConfigArray.size(); ++i) { - const QJsonObject& index = ledConfigArray[i].toObject(); + const QJsonObject& ledConfig = ledConfigArray[i].toObject(); Led led; - const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["h"].toObject(); - const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["v"].toObject(); - led.minX_frac = qMax(0.0, qMin(1.0, hscanConfig["min"].toDouble())); - led.maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["max"].toDouble())); - led.minY_frac = qMax(0.0, qMin(1.0, vscanConfig["min"].toDouble())); - led.maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["max"].toDouble())); + led.minX_frac = qMax(0.0, qMin(1.0, ledConfig["hmin"].toDouble())); + led.maxX_frac = qMax(0.0, qMin(1.0, ledConfig["hmax"].toDouble())); + led.minY_frac = qMax(0.0, qMin(1.0, ledConfig["vmin"].toDouble())); + led.maxY_frac = qMax(0.0, qMin(1.0, ledConfig["vmax"].toDouble())); // Fix if the user swapped min and max if (led.minX_frac > led.maxX_frac) { @@ -215,7 +215,7 @@ namespace hyperion { } // Get the order of the rgb channels for this led (default is device order) - led.colorOrder = stringToColorOrder(index["colorOrder"].toString(deviceOrderStr)); + led.colorOrder = stringToColorOrder(ledConfig["colorOrder"].toString(deviceOrderStr)); ledString.leds().push_back(led); } return ledString; @@ -228,12 +228,12 @@ namespace hyperion { for (signed i = 0; i < ledConfigArray.size(); ++i) { - const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["h"].toObject(); - const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["v"].toObject(); - double minX_frac = qMax(0.0, qMin(1.0, hscanConfig["min"].toDouble())); - double maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["max"].toDouble())); - double minY_frac = qMax(0.0, qMin(1.0, vscanConfig["min"].toDouble())); - double maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["max"].toDouble())); + const QJsonObject& ledConfig = ledConfigArray[i].toObject(); + + double minX_frac = qMax(0.0, qMin(1.0, ledConfig["hmin"].toDouble())); + double maxX_frac = qMax(0.0, qMin(1.0, ledConfig["hmax"].toDouble())); + double minY_frac = qMax(0.0, qMin(1.0, ledConfig["vmin"].toDouble())); + double maxY_frac = qMax(0.0, qMin(1.0, ledConfig["vmax"].toDouble())); // Fix if the user swapped min and max if (minX_frac > maxX_frac) { diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index 0ab8e360..bb94ebef 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -204,17 +204,29 @@ void JsonAPI::handleMessage(const QString& messageString, const QString& httpAut void JsonAPI::handleColorCommand(const QJsonObject& message, const QString& command, const int tan) { emit forwardJsonMessage(message); - - // extract parameters int priority = message["priority"].toInt(); int duration = message["duration"].toInt(-1); - const QString origin = message["origin"].toString("JsonRpc") + "@"+_peerAddress; + const QString origin = message["origin"].toString("JsonRpc") + "@" + _peerAddress; - const QJsonArray & jsonColor = message["color"].toArray(); - const ColorRgb color = {uint8_t(jsonColor.at(0).toInt()),uint8_t(jsonColor.at(1).toInt()),uint8_t(jsonColor.at(2).toInt())}; + const QJsonArray &jsonColor = message["color"].toArray(); + std::vector colors; + // TODO faster copy + for (const auto &entry : jsonColor) + { + colors.emplace_back(uint8_t(entry.toInt())); + } + + std::vector fledColors; + if (colors.size() % 3 == 0) + { + for (unsigned i = 0; i < colors.size(); i += 3) + { + fledColors.emplace_back(ColorRgb{colors[i], colors[i + 1], colors[i + 2]}); + } + } // set color - _hyperion->setColor(priority, color, duration, origin); + _hyperion->setColor(priority, fledColors, duration, origin); // send reply sendSuccessReply(command, tan); @@ -562,7 +574,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString& // get available components QJsonArray component; - std::map components = _hyperion->getComponentRegister().getRegister(); + std::map components = _hyperion->getAllComponents(); for(auto comp : components) { QJsonObject item; @@ -744,7 +756,7 @@ void JsonAPI::handleClearCommand(const QJsonObject& message, const QString& comm if(priority > 0) _hyperion->clear(priority); else if(priority < 0) - _hyperion->clearall(); + _hyperion->clear(-1); else { sendErrorReply("Priority 0 is not allowed", command, tan); @@ -760,7 +772,7 @@ void JsonAPI::handleClearallCommand(const QJsonObject& message, const QString& c emit forwardJsonMessage(message); // clear priority - _hyperion->clearall(); + _hyperion->clear(-1); // send reply sendSuccessReply(command, tan); @@ -920,7 +932,7 @@ void JsonAPI::handleConfigSetCommand(const QJsonObject& message, const QString & if (message.contains("config")) { QJsonObject config = message["config"].toObject(); - if(_hyperion->getComponentRegister().isComponentEnabled(hyperion::COMP_ALL)) + if(_hyperion->isComponentEnabled(hyperion::COMP_ALL)) { if(_hyperion->saveSettings(config, true)) sendSuccessReply(command,tan); @@ -1004,18 +1016,11 @@ void JsonAPI::handleComponentStateCommand(const QJsonObject& message, const QStr Components component = stringToComponent(compStr); - if (compStr == "ALL" ) - { - if(_hyperion->getComponentRegister().setHyperionEnable(compState)) - sendSuccessReply(command, tan); - - return; - } - else if (component != COMP_INVALID) + if (component != COMP_INVALID) { // send result before apply sendSuccessReply(command, tan); - _hyperion->setComponentState(component, compState); + emit _hyperion->compStateChangeRequest(component, compState); return; } sendErrorReply("invalid component name", command, tan); diff --git a/libsrc/blackborder/BlackBorderProcessor.cpp b/libsrc/blackborder/BlackBorderProcessor.cpp index a566df17..4a86d0c2 100644 --- a/libsrc/blackborder/BlackBorderProcessor.cpp +++ b/libsrc/blackborder/BlackBorderProcessor.cpp @@ -32,7 +32,7 @@ BlackBorderProcessor::BlackBorderProcessor(Hyperion* hyperion, QObject* parent) connect(_hyperion, &Hyperion::settingsChanged, this, &BlackBorderProcessor::handleSettingsUpdate); // listen for component state changes - connect(_hyperion, &Hyperion::componentStateChanged, this, &BlackBorderProcessor::componentStateChanged); + connect(_hyperion, &Hyperion::compStateChangeRequest, this, &BlackBorderProcessor::handleCompStateChangeRequest); } BlackBorderProcessor::~BlackBorderProcessor() @@ -65,11 +65,11 @@ void BlackBorderProcessor::handleSettingsUpdate(const settings::type& type, cons Debug(Logger::getInstance("BLACKBORDER"), "Set mode to: %s", QSTRING_CSTR(_detectionMode)); // eval the comp state - componentStateChanged(hyperion::COMP_BLACKBORDER, obj["enable"].toBool(true)); + handleCompStateChangeRequest(hyperion::COMP_BLACKBORDER, obj["enable"].toBool(true)); } } -void BlackBorderProcessor::componentStateChanged(const hyperion::Components component, bool enable) +void BlackBorderProcessor::handleCompStateChangeRequest(const hyperion::Components component, bool enable) { if(component == hyperion::COMP_BLACKBORDER) { @@ -85,7 +85,7 @@ void BlackBorderProcessor::componentStateChanged(const hyperion::Components comp _enabled = enable; } - _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_BLACKBORDER, enable); + _hyperion->setNewComponentState(hyperion::COMP_BLACKBORDER, enable); } } diff --git a/libsrc/boblightserver/BoblightServer.cpp b/libsrc/boblightserver/BoblightServer.cpp index f656dc8d..bd7a65ed 100644 --- a/libsrc/boblightserver/BoblightServer.cpp +++ b/libsrc/boblightserver/BoblightServer.cpp @@ -28,7 +28,7 @@ BoblightServer::BoblightServer(Hyperion* hyperion,const QJsonDocument& config) Debug(_log, "Instance created"); // listen for component change - connect(_hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool))); + connect(_hyperion, SIGNAL(compStateChangeRequest(hyperion::Components,bool)), this, SLOT(compStateChangeRequest(hyperion::Components,bool))); // listen new connection signal from server connect(_server, SIGNAL(newConnection()), this, SLOT(newConnection())); @@ -51,7 +51,7 @@ void BoblightServer::start() Info(_log, "Started on port %d", _port); - _hyperion->getComponentRegister().componentStateChanged(COMP_BOBLIGHTSERVER, _server->isListening()); + _hyperion->setNewComponentState(COMP_BOBLIGHTSERVER, _server->isListening()); } void BoblightServer::stop() @@ -65,7 +65,7 @@ void BoblightServer::stop() _server->close(); Info(_log, "Stopped"); - _hyperion->getComponentRegister().componentStateChanged(COMP_BOBLIGHTSERVER, _server->isListening()); + _hyperion->setNewComponentState(COMP_BOBLIGHTSERVER, _server->isListening()); } bool BoblightServer::active() @@ -73,7 +73,7 @@ bool BoblightServer::active() return _server->isListening(); } -void BoblightServer::componentStateChanged(const hyperion::Components component, bool enable) +void BoblightServer::compStateChangeRequest(const hyperion::Components component, bool enable) { if (component == COMP_BOBLIGHTSERVER) { diff --git a/libsrc/flatbufserver/FlatBufferClient.cpp b/libsrc/flatbufserver/FlatBufferClient.cpp index 0444851f..a20898f6 100644 --- a/libsrc/flatbufserver/FlatBufferClient.cpp +++ b/libsrc/flatbufserver/FlatBufferClient.cpp @@ -95,10 +95,7 @@ void FlatBufferClient::handleColorCommand(const hyperionnet::Color *colorReq) { // extract parameters const int32_t rgbData = colorReq->data(); - ColorRgb color; - color.red = qRed(rgbData); - color.green = qGreen(rgbData); - color.blue = qBlue(rgbData); + std::vector color{ ColorRgb{ uint8_t(qRed(rgbData)), uint8_t(qGreen(rgbData)), uint8_t(qBlue(rgbData)) } }; // set output emit setGlobalInputColor(_priority, color, colorReq->duration()); @@ -172,17 +169,12 @@ void FlatBufferClient::handleClearCommand(const hyperionnet::Clear *clear) // extract parameters const int priority = clear->priority(); - if (priority == -1) { - emit clearAllGlobalInput(); + // Check if we are clearing ourselves. + if (priority == _priority) { + _priority = -1; } - else { - // Check if we are clearing ourselves. - if (priority == _priority) { - _priority = -1; - } - emit clearGlobalInput(priority); - } + emit clearGlobalInput(priority); sendSuccessReply(); } diff --git a/libsrc/flatbufserver/FlatBufferClient.h b/libsrc/flatbufserver/FlatBufferClient.h index 7cb678c7..e0416e68 100644 --- a/libsrc/flatbufserver/FlatBufferClient.h +++ b/libsrc/flatbufserver/FlatBufferClient.h @@ -41,12 +41,7 @@ signals: /// /// @brief Forward clear command to HyperionDaemon /// - void clearGlobalInput(const int priority); - - /// - /// @brief Forward clearAll command to HyperionDaemon - /// - void clearAllGlobalInput(bool forceClearAll=false); + void clearGlobalInput(const int priority, bool forceClearAll=false); /// /// @brief forward prepared image to HyperionDaemon @@ -56,7 +51,7 @@ signals: /// /// @brief Forward requested color /// - void setGlobalInputColor(const int priority, const ColorRgb &ledColor, const int timeout_ms, const QString& origin = "FlatBuffer" ,bool clearEffects = true); + void setGlobalInputColor(const int priority, const std::vector &ledColor, const int timeout_ms, const QString& origin = "FlatBuffer" ,bool clearEffects = true); /// /// @brief Emits whenever the client disconnected diff --git a/libsrc/flatbufserver/FlatBufferServer.cpp b/libsrc/flatbufserver/FlatBufferServer.cpp index ec88aa7c..3c9d15d4 100644 --- a/libsrc/flatbufserver/FlatBufferServer.cpp +++ b/libsrc/flatbufserver/FlatBufferServer.cpp @@ -71,7 +71,6 @@ void FlatBufferServer::newConnection() connect(client, &FlatBufferClient::clientDisconnected, this, &FlatBufferServer::clientDisconnected); connect(client, &FlatBufferClient::registerGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::registerGlobalInput); connect(client, &FlatBufferClient::clearGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearGlobalInput); - connect(client, &FlatBufferClient::clearAllGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearAllGlobalInput); connect(client, &FlatBufferClient::setGlobalInputImage, GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage); connect(client, &FlatBufferClient::setGlobalInputColor, GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor); connect(GlobalSignals::getInstance(), &GlobalSignals::globalRegRequired, client, &FlatBufferClient::registationRequired); diff --git a/libsrc/grabber/v4l2/V4L2Grabber.cpp b/libsrc/grabber/v4l2/V4L2Grabber.cpp index 82f3749d..d64f481f 100644 --- a/libsrc/grabber/v4l2/V4L2Grabber.cpp +++ b/libsrc/grabber/v4l2/V4L2Grabber.cpp @@ -60,7 +60,7 @@ V4L2Grabber::V4L2Grabber(const QString & device // connect componentStateChange only for build-in grabber if (HyperionIManager::HIMinstance) - connect(this, &Grabber::componentStateChanged, this, &V4L2Grabber::componentStateChanged); + connect(this, &Grabber::compStateChangeRequest, this, &V4L2Grabber::compStateChangeRequest); // init setDeviceVideoStandard(device, videoStandard); @@ -1176,7 +1176,7 @@ void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStan } } -void V4L2Grabber::componentStateChanged(const hyperion::Components component, bool enable) +void V4L2Grabber::compStateChangeRequest(const hyperion::Components component, bool enable) { if (component == hyperion::COMP_V4L) { diff --git a/libsrc/grabber/v4l2/V4L2Wrapper.cpp b/libsrc/grabber/v4l2/V4L2Wrapper.cpp index a4e89192..e3cccfa6 100644 --- a/libsrc/grabber/v4l2/V4L2Wrapper.cpp +++ b/libsrc/grabber/v4l2/V4L2Wrapper.cpp @@ -24,7 +24,7 @@ V4L2Wrapper::V4L2Wrapper(const QString &device, connect(&_grabber, SIGNAL(newFrame(Image)), this, SLOT(newFrame(Image)), Qt::DirectConnection); connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection); - connect(this, &V4L2Wrapper::componentStateChanged, _ggrabber, &Grabber::componentStateChanged); + connect(this, &V4L2Wrapper::compStateChangeRequest, _ggrabber, &Grabber::compStateChangeRequest); } bool V4L2Wrapper::start() diff --git a/libsrc/hyperion/CaptureCont.cpp b/libsrc/hyperion/CaptureCont.cpp index 28941936..bd83ee0d 100644 --- a/libsrc/hyperion/CaptureCont.cpp +++ b/libsrc/hyperion/CaptureCont.cpp @@ -25,7 +25,7 @@ CaptureCont::CaptureCont(Hyperion* hyperion) connect(_hyperion, &Hyperion::settingsChanged, this, &CaptureCont::handleSettingsUpdate); // comp changes - connect(_hyperion, &Hyperion::componentStateChanged, this, &CaptureCont::componentStateChanged); + connect(_hyperion, &Hyperion::compStateChangeRequest, this, &CaptureCont::handleCompStateChangeRequest); // inactive timer system connect(_systemInactiveTimer, &QTimer::timeout, this, &CaptureCont::setSystemInactive); @@ -85,8 +85,8 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable) _systemCaptName = ""; } _systemCaptEnabled = enable; - _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_GRABBER, enable); - _hyperion->setComponentState(hyperion::COMP_GRABBER, enable); + _hyperion->setNewComponentState(hyperion::COMP_GRABBER, enable); + //emit _hyperion->compStateChangeRequest(hyperion::COMP_GRABBER, enable); } } @@ -108,8 +108,8 @@ void CaptureCont::setV4LCaptureEnable(const bool& enable) _v4lCaptName = ""; } _v4lCaptEnabled = enable; - _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable); - _hyperion->setComponentState(hyperion::COMP_V4L, enable); + _hyperion->setNewComponentState(hyperion::COMP_V4L, enable); + //emit _hyperion->compStateChangeRequest(hyperion::COMP_V4L, enable); } } @@ -134,7 +134,7 @@ void CaptureCont::handleSettingsUpdate(const settings::type& type, const QJsonDo } } -void CaptureCont::componentStateChanged(const hyperion::Components component, bool enable) +void CaptureCont::handleCompStateChangeRequest(const hyperion::Components component, bool enable) { if(component == hyperion::COMP_GRABBER) { diff --git a/libsrc/hyperion/ComponentRegister.cpp b/libsrc/hyperion/ComponentRegister.cpp index 6bbfc802..61b830cd 100644 --- a/libsrc/hyperion/ComponentRegister.cpp +++ b/libsrc/hyperion/ComponentRegister.cpp @@ -16,51 +16,20 @@ ComponentRegister::ComponentRegister(Hyperion* hyperion) { _componentStates.emplace(e, ((e == COMP_ALL) ? true : false)); } + + connect(_hyperion, &Hyperion::compStateChangeRequest, this, &ComponentRegister::handleCompStateChangeRequest); } ComponentRegister::~ComponentRegister() { } -bool ComponentRegister::setHyperionEnable(const bool& state) -{ - if(!state && _prevComponentStates.empty()) - { - Debug(_log,"Disable Hyperion, store current component states"); - for(const auto comp : _componentStates) - { - // save state - _prevComponentStates.emplace(comp.first, comp.second); - // disable if enabled - if(comp.second) - _hyperion->setComponentState(comp.first, false); - } - componentStateChanged(COMP_ALL, false); - return true; - } - else if(state && !_prevComponentStates.empty()) - { - Debug(_log,"Enable Hyperion, recover previous component states"); - for(const auto comp : _prevComponentStates) - { - // if comp was enabled, enable again - if(comp.second) - _hyperion->setComponentState(comp.first, true); - - } - _prevComponentStates.clear(); - componentStateChanged(COMP_ALL, true); - return true; - } - return false; -} - int ComponentRegister::isComponentEnabled(const hyperion::Components& comp) const { return (_componentStates.count(comp)) ? _componentStates.at(comp) : -1; } -void ComponentRegister::componentStateChanged(const hyperion::Components comp, const bool activated) +void ComponentRegister::setNewComponentState(const hyperion::Components comp, const bool activated) { if(_componentStates[comp] != activated) { @@ -70,3 +39,38 @@ void ComponentRegister::componentStateChanged(const hyperion::Components comp, c emit updatedComponentState(comp, activated); } } + +void ComponentRegister::handleCompStateChangeRequest(const hyperion::Components comp, const bool activated) +{ + if(comp == COMP_ALL && !_inProgress) + { + _inProgress = true; + if(!activated && _prevComponentStates.empty()) + { + Debug(_log,"Disable Hyperion, store current component states"); + for(const auto comp : _componentStates) + { + // save state + _prevComponentStates.emplace(comp.first, comp.second); + // disable if enabled + if(comp.second) + emit _hyperion->compStateChangeRequest(comp.first, false); + } + setNewComponentState(COMP_ALL, false); + } + else if(activated && !_prevComponentStates.empty()) + { + Debug(_log,"Enable Hyperion, recover previous component states"); + for(const auto comp : _prevComponentStates) + { + // if comp was enabled, enable again + if(comp.second) + emit _hyperion->compStateChangeRequest(comp.first, true); + + } + _prevComponentStates.clear(); + setNewComponentState(COMP_ALL, true); + } + _inProgress = false; + } +} \ No newline at end of file diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index 1997a98e..cc6d7921 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -104,7 +104,7 @@ void Hyperion::start() ledDevice["currentLedCount"] = int(_hwLedCount); // Inject led count info _ledDeviceWrapper = new LedDeviceWrapper(this); - connect(this, &Hyperion::componentStateChanged, _ledDeviceWrapper, &LedDeviceWrapper::handleComponentState); + connect(this, &Hyperion::compStateChangeRequest, _ledDeviceWrapper, &LedDeviceWrapper::handleComponentState); connect(this, &Hyperion::ledDeviceData, _ledDeviceWrapper, &LedDeviceWrapper::updateLeds); _ledDeviceWrapper->createLedDevice(ledDevice); @@ -132,7 +132,6 @@ void Hyperion::start() // forwards global signals to the corresponding slots connect(GlobalSignals::getInstance(), &GlobalSignals::registerGlobalInput, this, &Hyperion::registerInput); connect(GlobalSignals::getInstance(), &GlobalSignals::clearGlobalInput, this, &Hyperion::clear); - connect(GlobalSignals::getInstance(), &GlobalSignals::clearAllGlobalInput, this, &Hyperion::clearall); connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor, this, &Hyperion::setColor); connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage, this, &Hyperion::setInputImage); @@ -157,7 +156,7 @@ void Hyperion::stop() void Hyperion::freeObjects(bool emitCloseSignal) { // switch off all leds - clearall(true); + clear(-1,true); if (emitCloseSignal) { @@ -309,13 +308,17 @@ bool Hyperion::sourceAutoSelectEnabled() void Hyperion::setNewComponentState(const hyperion::Components& component, const bool& state) { - _componentRegister.componentStateChanged(component, state); + _componentRegister.setNewComponentState(component, state); } -void Hyperion::setComponentState(const hyperion::Components component, const bool state) +std::map Hyperion::getAllComponents() { - // TODO REMOVE THIS STEP - emit componentStateChanged(component, state); + return _componentRegister.getRegister(); +} + +int Hyperion::isComponentEnabled(const hyperion::Components &comp) +{ + return _componentRegister.isComponentEnabled(comp); } void Hyperion::registerInput(const int priority, const hyperion::Components& component, const QString& origin, const QString& owner, unsigned smooth_cfg) @@ -372,14 +375,25 @@ bool Hyperion::setInputInactive(const quint8& priority) return _muxer.setInputInactive(priority); } -void Hyperion::setColor(const int priority, const ColorRgb &color, const int timeout_ms, const QString& origin, bool clearEffects) +void Hyperion::setColor(const int priority, const std::vector &ledColors, const int timeout_ms, const QString &origin, bool clearEffects) { // clear effect if this call does not come from an effect - if(clearEffects) + if (clearEffects) _effectEngine->channelCleared(priority); - // create led vector from single color - std::vector ledColors(_ledString.leds().size(), color); + // create full led vector from single/multiple colors + unsigned int size = _ledString.leds().size(); + std::vector newLedColors; + while (true) + { + for (const auto &entry : ledColors) + { + newLedColors.emplace_back(entry); + if (newLedColors.size() == size) + goto end; + } + } +end: if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR) clear(priority); @@ -388,8 +402,8 @@ void Hyperion::setColor(const int priority, const ColorRgb &color, const int tim registerInput(priority, hyperion::COMP_COLOR, origin); // write color to muxer & queuePush - setInput(priority, ledColors, timeout_ms); - if(timeout_ms <= 0) + setInput(priority, newLedColors, timeout_ms); + if (timeout_ms <= 0) _muxer.queuePush(); } @@ -409,26 +423,28 @@ void Hyperion::adjustmentsUpdated() update(); } -bool Hyperion::clear(const int priority) +bool Hyperion::clear(const int priority, bool forceClearAll) { - // send clear signal to the effect engine - // (outside the check so the effect gets cleared even when the effect is not sending colors) - _effectEngine->channelCleared(priority); + if (priority < 0) + { + _muxer.clearAll(forceClearAll); - if(_muxer.clearInput(priority)) + // send clearall signal to the effect engine + _effectEngine->allChannelsCleared(); return true; + } + else + { + // send clear signal to the effect engine + // (outside the check so the effect gets cleared even when the effect is not sending colors) + _effectEngine->channelCleared(priority); + if (_muxer.clearInput(priority)) + return true; + } return false; } -void Hyperion::clearall(bool forceClearAll) -{ - _muxer.clearAll(forceClearAll); - - // send clearall signal to the effect engine - _effectEngine->allChannelsCleared(); -} - int Hyperion::getCurrentPriority() const { return _muxer.getCurrentPriority(); diff --git a/libsrc/hyperion/HyperionIManager.cpp b/libsrc/hyperion/HyperionIManager.cpp index 0b11f9a1..2e57015c 100644 --- a/libsrc/hyperion/HyperionIManager.cpp +++ b/libsrc/hyperion/HyperionIManager.cpp @@ -76,7 +76,7 @@ bool HyperionIManager::startInstance(const quint8& inst, const bool& block) // from Hyperion connect(hyperion, &Hyperion::settingsChanged, this, &HyperionIManager::settingsChanged); connect(hyperion, &Hyperion::videoMode, this, &HyperionIManager::requestVideoMode); - connect(hyperion, &Hyperion::componentStateChanged, this, &HyperionIManager::componentStateChanged); + connect(hyperion, &Hyperion::compStateChangeRequest, this, &HyperionIManager::compStateChangeRequest); // to Hyperion connect(this, &HyperionIManager::newVideoMode, hyperion, &Hyperion::newVideoMode); diff --git a/libsrc/hyperion/LinearColorSmoothing.cpp b/libsrc/hyperion/LinearColorSmoothing.cpp index 1db5464d..c145ed27 100644 --- a/libsrc/hyperion/LinearColorSmoothing.cpp +++ b/libsrc/hyperion/LinearColorSmoothing.cpp @@ -38,7 +38,7 @@ LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument& config, Hyperion _cfgList.append(cfg); // listen for comp changes - connect(_hyperion, &Hyperion::componentStateChanged, this, &LinearColorSmoothing::componentStateChange); + connect(_hyperion, &Hyperion::compStateChangeRequest, this, &LinearColorSmoothing::componentStateChange); // timer connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds); } @@ -235,7 +235,7 @@ void LinearColorSmoothing::setEnable(bool enable) clearQueuedColors(); } // update comp register - _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, enable); + _hyperion->setNewComponentState(hyperion::COMP_SMOOTHING, enable); } void LinearColorSmoothing::setPause(bool pause) diff --git a/libsrc/hyperion/MessageForwarder.cpp b/libsrc/hyperion/MessageForwarder.cpp index 9433ffe9..41b3e5a0 100644 --- a/libsrc/hyperion/MessageForwarder.cpp +++ b/libsrc/hyperion/MessageForwarder.cpp @@ -28,7 +28,7 @@ MessageForwarder::MessageForwarder(Hyperion *hyperion) connect(_hyperion, &Hyperion::settingsChanged, this, &MessageForwarder::handleSettingsUpdate); // component changes - connect(_hyperion, &Hyperion::componentStateChanged, this, &MessageForwarder::componentStateChanged); + connect(_hyperion, &Hyperion::compStateChangeRequest, this, &MessageForwarder::handleCompStateChangeRequest); // connect with Muxer visible priority changes connect(_muxer, &PriorityMuxer::visiblePriorityChanged, this, &MessageForwarder::handlePriorityChanges); @@ -91,18 +91,18 @@ void MessageForwarder::handleSettingsUpdate(const settings::type &type, const QJ } // update comp state - _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_FORWARDER, obj["enable"].toBool(true)); + _hyperion->setNewComponentState(hyperion::COMP_FORWARDER, obj["enable"].toBool(true)); } } -void MessageForwarder::componentStateChanged(const hyperion::Components component, bool enable) +void MessageForwarder::handleCompStateChangeRequest(const hyperion::Components component, bool enable) { if (component == hyperion::COMP_FORWARDER && _forwarder_enabled != enable) { _forwarder_enabled = enable; handleSettingsUpdate(settings::NETFORWARD, _hyperion->getSetting(settings::NETFORWARD)); Info(_log, "Forwarder change state to %s", (_forwarder_enabled ? "enabled" : "disabled")); - _hyperion->getComponentRegister().componentStateChanged(component, _forwarder_enabled); + _hyperion->setNewComponentState(component, _forwarder_enabled); } } diff --git a/libsrc/hyperion/SettingsManager.cpp b/libsrc/hyperion/SettingsManager.cpp index f8bdb319..034b0167 100644 --- a/libsrc/hyperion/SettingsManager.cpp +++ b/libsrc/hyperion/SettingsManager.cpp @@ -74,6 +74,13 @@ SettingsManager::SettingsManager(const quint8& instance, QObject* parent) dbConfig[key] = doc.object(); } + // possible data upgrade steps to prevent data loss + if(handleConfigUpgrade(dbConfig)) + { + saveSettings(dbConfig, true); + } + + // validate full dbconfig against schema, on error we need to rewrite entire table QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson); @@ -108,6 +115,9 @@ const QJsonDocument SettingsManager::getSetting(const settings::type& type) bool SettingsManager::saveSettings(QJsonObject config, const bool& correct) { + // optional data upgrades e.g. imported legacy/older configs + // handleConfigUpgrade(config); + // we need to validate data against schema QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson); @@ -156,3 +166,66 @@ bool SettingsManager::saveSettings(QJsonObject config, const bool& correct) } return true; } + +bool SettingsManager::handleConfigUpgrade(QJsonObject& config) +{ + bool migrated = false; + + // LED LAYOUT UPGRADE + // from { hscan: { minimum: 0.2, maximum: 0.3 }, vscan: { minimum: 0.2, maximumn: 0.3 } } + // from { h: { min: 0.2, max: 0.3 }, v: { min: 0.2, max: 0.3 } } + // to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3} + if(config.contains("leds")) + { + const QJsonArray ledarr = config["leds"].toArray(); + const QJsonObject led = ledarr[0].toObject(); + + if(led.contains("hscan") || led.contains("h")) + { + const bool whscan = led.contains("hscan"); + QJsonArray newLedarr; + + for(const auto & entry : ledarr) + { + const QJsonObject led = entry.toObject(); + QJsonObject hscan; + QJsonObject vscan; + QJsonValue hmin; + QJsonValue hmax; + QJsonValue vmin; + QJsonValue vmax; + QJsonObject nL; + + if(whscan) + { + hscan = led["hscan"].toObject(); + vscan = led["vscan"].toObject(); + hmin = hscan["minimum"]; + hmax = hscan["maximum"]; + vmin = vscan["minimum"]; + vmax = vscan["maximum"]; + } + else + { + hscan = led["h"].toObject(); + vscan = led["v"].toObject(); + hmin = hscan["min"]; + hmax = hscan["max"]; + vmin = vscan["min"]; + vmax = vscan["max"]; + } + // append to led object + nL["hmin"] = hmin; + nL["hmax"] = hmax; + nL["vmin"] = vmin; + nL["vmax"] = vmax; + newLedarr.append(nL); + } + // replace + config["leds"] = newLedarr; + migrated = true; + Debug(_log,"LED Layout migrated"); + } + } + return migrated; +} diff --git a/libsrc/hyperion/schema/schema-leds.json b/libsrc/hyperion/schema/schema-leds.json index c2f23f94..b663f645 100644 --- a/libsrc/hyperion/schema/schema-leds.json +++ b/libsrc/hyperion/schema/schema-leds.json @@ -1,72 +1,64 @@ { - "type":"array", - "required":true, - "minItems":1, - "items": - { - "type":"object", - "required" : true, - "properties": - { - "h": - { - "type":"object", - "required" : true, - "properties": - { - "min": - { - "type":"number", - "minimum" : 0, - "maximum" : 1, - "required":true, - "default" : 0 - }, - "max": - { - "type":"number", - "minimum" : 0, - "maximum" : 1, - "required":true, - "default" : 0.1 - } - }, - "additionalProperties" : false + "type": "array", + "required": true, + "minItems": 1, + "items": { + "type": "object", + "required": true, + "properties": { + "hmin": { + "type": "number", + "minimum": 0, + "maximum": 1, + "required": true, + "default": 0 }, - "v": - { - "type":"object", - "required" : true, - "properties": - { - "min": - { - "type":"number", - "minimum" : 0, - "maximum" : 1, - "required":true, - "default" : 0 - }, - "max": - { - "type":"number", - "minimum" : 0, - "maximum" : 1, - "required":true, - "default" : 0.1 - } - }, - "additionalProperties" : false + "hmax": { + "type": "number", + "minimum": 0, + "maximum": 1, + "required": true, + "default": 0.1 }, - "colorOrder": - { + "vmin": { + "type": "number", + "minimum": 0, + "maximum": 1, + "required": true, + "default": 0 + }, + "vmax": { + "type": "number", + "minimum": 0, + "maximum": 1, + "required": true, + "default": 0.1 + }, + "colorOrder": { "type": "string", - "enum" : ["rgb", "bgr", "rbg", "brg", "gbr", "grb"], - "options" : { - "enum_titles" : ["edt_conf_enum_rgb", "edt_conf_enum_bgr", "edt_conf_enum_rbg", "edt_conf_enum_brg", "edt_conf_enum_gbr", "edt_conf_enum_grb"] + "enum": [ + "rgb", + "bgr", + "rbg", + "brg", + "gbr", + "grb" + ], + "options": { + "enum_titles": [ + "edt_conf_enum_rgb", + "edt_conf_enum_bgr", + "edt_conf_enum_rbg", + "edt_conf_enum_brg", + "edt_conf_enum_gbr", + "edt_conf_enum_grb" + ] } + }, + "name": { + "type": "string" } }, - "additionalProperties" : false + "additionalProperties": false } -} +} \ No newline at end of file diff --git a/libsrc/protoserver/ProtoClientConnection.cpp b/libsrc/protoserver/ProtoClientConnection.cpp index a433f471..9338db10 100644 --- a/libsrc/protoserver/ProtoClientConnection.cpp +++ b/libsrc/protoserver/ProtoClientConnection.cpp @@ -119,10 +119,7 @@ void ProtoClientConnection::handleColorCommand(const proto::ColorRequest &messag // extract parameters int priority = message.priority(); int duration = message.has_duration() ? message.duration() : -1; - ColorRgb color; - color.red = qRed(message.rgbcolor()); - color.green = qGreen(message.rgbcolor()); - color.blue = qBlue(message.rgbcolor()); + std::vector color{ ColorRgb{ uint8_t(qRed(message.rgbcolor())), uint8_t(qGreen(message.rgbcolor())), uint8_t(qBlue(message.rgbcolor())) } }; if (priority < 100 || priority >= 200) { @@ -202,7 +199,7 @@ void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &messag void ProtoClientConnection::handleClearallCommand() { // clear all priority - emit clearAllGlobalInput(); + emit clearGlobalInput(-1); // send reply sendSuccessReply(); diff --git a/libsrc/protoserver/ProtoClientConnection.h b/libsrc/protoserver/ProtoClientConnection.h index ef88314f..e1083a59 100644 --- a/libsrc/protoserver/ProtoClientConnection.h +++ b/libsrc/protoserver/ProtoClientConnection.h @@ -41,12 +41,7 @@ signals: /// /// @brief Forward clear command to HyperionDaemon /// - void clearGlobalInput(const int priority); - - /// - /// @brief Forward clearAll command to HyperionDaemon - /// - void clearAllGlobalInput(bool forceClearAll=false); + void clearGlobalInput(const int priority, bool forceClearAll=false); /// /// @brief forward prepared image to HyperionDaemon @@ -56,7 +51,7 @@ signals: /// /// @brief Forward requested color /// - void setGlobalInputColor(const int priority, const ColorRgb &ledColor, const int timeout_ms, const QString& origin = "ProtoBuffer" ,bool clearEffects = true); + void setGlobalInputColor(const int priority, const std::vector &ledColor, const int timeout_ms, const QString& origin = "ProtoBuffer" ,bool clearEffects = true); /// /// @brief Emits whenever the client disconnected diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp index 519fae0c..154dc012 100644 --- a/libsrc/protoserver/ProtoServer.cpp +++ b/libsrc/protoserver/ProtoServer.cpp @@ -71,7 +71,6 @@ void ProtoServer::newConnection() connect(client, &ProtoClientConnection::clientDisconnected, this, &ProtoServer::clientDisconnected); connect(client, &ProtoClientConnection::registerGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::registerGlobalInput); connect(client, &ProtoClientConnection::clearGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearGlobalInput); - connect(client, &ProtoClientConnection::clearAllGlobalInput, GlobalSignals::getInstance(), &GlobalSignals::clearAllGlobalInput); connect(client, &ProtoClientConnection::setGlobalInputImage, GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage); connect(client, &ProtoClientConnection::setGlobalInputColor, GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor); connect(GlobalSignals::getInstance(), &GlobalSignals::globalRegRequired, client, &ProtoClientConnection::registationRequired); diff --git a/libsrc/ssdp/SSDPHandler.cpp b/libsrc/ssdp/SSDPHandler.cpp index 4f1cc16a..40d50876 100644 --- a/libsrc/ssdp/SSDPHandler.cpp +++ b/libsrc/ssdp/SSDPHandler.cpp @@ -9,7 +9,7 @@ #include #include -SSDPHandler::SSDPHandler(WebServer* webserver, const quint16& flatBufPort, const quint16& jsonServerPort, QObject * parent) +SSDPHandler::SSDPHandler(WebServer* webserver, const quint16& flatBufPort, const quint16& jsonServerPort, const QString& name, QObject * parent) : SSDPServer(parent) , _webserver(webserver) , _localAddress() @@ -17,6 +17,7 @@ SSDPHandler::SSDPHandler(WebServer* webserver, const quint16& flatBufPort, const { setFlatBufPort(flatBufPort); setJsonServerPort(jsonServerPort); + setHyperionName(name); } SSDPHandler::~SSDPHandler() @@ -76,6 +77,15 @@ void SSDPHandler::handleSettingsUpdate(const settings::type& type, const QJsonDo SSDPServer::setJsonServerPort(obj["port"].toInt()); } } + + if (type == settings::GENERAL) + { + const QJsonObject &obj = config.object(); + if (obj["name"].toString() != SSDPServer::getHyperionName()) + { + SSDPServer::setHyperionName(obj["name"].toString()); + } + } } void SSDPHandler::handleWebServerStateChange(const bool newState) diff --git a/libsrc/ssdp/SSDPServer.cpp b/libsrc/ssdp/SSDPServer.cpp index 96c23e8a..4556f956 100644 --- a/libsrc/ssdp/SSDPServer.cpp +++ b/libsrc/ssdp/SSDPServer.cpp @@ -28,6 +28,7 @@ static const QString UPNP_ALIVE_MESSAGE = "NOTIFY * HTTP/1.1\r\n" "USN: uuid:%5\r\n" "HYPERION-FBS-PORT: %6\r\n" "HYPERION-JSS-PORT: %7\r\n" + "HYPERION-NAME: %8\r\n" "\r\n"; // Implement ssdp:update as per spec 1.1, section 1.2.4 @@ -72,6 +73,7 @@ static const QString UPNP_MSEARCH_RESPONSE = "HTTP/1.1 200 OK\r\n" "USN: uuid:%6\r\n" "HYPERION-FBS-PORT: %7\r\n" "HYPERION-JSS-PORT: %8\r\n" + "HYPERION-NAME: %9\r\n" "\r\n"; SSDPServer::SSDPServer(QObject * parent) @@ -172,7 +174,8 @@ void SSDPServer::sendMSearchResponse(const QString& st, const QString& senderIp, , st , _uuid , _fbsPort - , _jssPort ); + , _jssPort + , _name ); _udpSocket->writeDatagram(message.toUtf8(), QHostAddress(senderIp), @@ -203,7 +206,8 @@ void SSDPServer::sendAlive(const QString& st) , _serverHeader , tempUSN , _fbsPort - , _jssPort ); + , _jssPort + , _name ); // we repeat 3 times quint8 rep = 0; diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 8fde0c5c..33a9d375 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -112,7 +112,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bo // pipe settings changes and component state changes from HyperionIManager to Daemon connect(_instanceManager, &HyperionIManager::settingsChanged, this, &HyperionDaemon::settingsChanged); - connect(_instanceManager, &HyperionIManager::componentStateChanged, this, &HyperionDaemon::componentStateChanged); + connect(_instanceManager, &HyperionIManager::compStateChangeRequest, this, &HyperionDaemon::compStateChangeRequest); // listen for setting changes of framegrabber and v4l2 connect(this, &HyperionDaemon::settingsChanged, this, &HyperionDaemon::handleSettingsUpdate); @@ -247,7 +247,7 @@ void HyperionDaemon::startNetworkServices() sslWsThread->start(); // Create SSDP server in thread - _ssdp = new SSDPHandler(_webserver, getSetting(settings::FLATBUFSERVER).object()["port"].toInt(), getSetting(settings::JSONSERVER).object()["port"].toInt()); + _ssdp = new SSDPHandler(_webserver, getSetting(settings::FLATBUFSERVER).object()["port"].toInt(), getSetting(settings::JSONSERVER).object()["port"].toInt(), getSetting(settings::GENERAL).object()["name"].toString()); QThread* ssdpThread = new QThread(this); _ssdp->moveToThread(ssdpThread); connect( ssdpThread, &QThread::started, _ssdp, &SSDPHandler::initServer ); @@ -436,7 +436,7 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& settingsType, co // connect to HyperionDaemon signal connect(this, &HyperionDaemon::videoMode, _v4l2Grabber, &V4L2Wrapper::setVideoMode); connect(this, &HyperionDaemon::settingsChanged, _v4l2Grabber, &V4L2Wrapper::handleSettingsUpdate); - connect(this, &HyperionDaemon::componentStateChanged, _v4l2Grabber, &V4L2Wrapper::componentStateChanged); + connect(this, &HyperionDaemon::compStateChangeRequest, _v4l2Grabber, &V4L2Wrapper::compStateChangeRequest); #else Error(_log, "The v4l2 grabber can not be instantiated, because it has been left out from the build"); #endif diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index 30fcc6ef..4f55bf4b 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -120,7 +120,7 @@ signals: /// /// @brief PIPE component state changes events from Hyperion class to HyperionDaemon components /// - void componentStateChanged(const hyperion::Components component, bool enable); + void compStateChangeRequest(const hyperion::Components component, bool enable); private slots: /// diff --git a/src/hyperiond/systray.cpp b/src/hyperiond/systray.cpp index 994966b2..03d4a4f3 100644 --- a/src/hyperiond/systray.cpp +++ b/src/hyperiond/systray.cpp @@ -102,10 +102,7 @@ void SysTray::createTrayIcon() void SysTray::setColor(const QColor & color) { - ColorRgb rgbColor; - rgbColor.red = color.red(); - rgbColor.green = color.green(); - rgbColor.blue =color.blue(); + std::vector rgbColor{ ColorRgb{ (uint8_t)color.red(), (uint8_t)color.green(), (uint8_t)color.blue() } }; _hyperion->setColor(1 ,rgbColor, 0); }