From eccd4e6637930e659ede747963b9ac569f310285 Mon Sep 17 00:00:00 2001 From: redPanther Date: Mon, 20 Jun 2016 23:41:07 +0200 Subject: [PATCH] rework bootsequence (#30) * udplistener/boblight: use hyperion::getInstance hyperiond: fix dispmanx is started twice hyperiond: rework bootsequence - now named as InitalEffect * pull out webconfig from hyperiondaemon to functional when daemon crashes initialEffect: forbid foreground effect duration infinitiy --- include/boblightserver/BoblightServer.h | 2 +- include/udplistener/UDPListener.h | 2 +- libsrc/boblightserver/BoblightServer.cpp | 4 +- libsrc/udplistener/UDPListener.cpp | 7 +- src/hyperiond/hyperiond.cpp | 109 +++++++++++++---------- src/hyperiond/hyperiond.h | 2 +- src/hyperiond/main.cpp | 18 +++- 7 files changed, 82 insertions(+), 62 deletions(-) diff --git a/include/boblightserver/BoblightServer.h b/include/boblightserver/BoblightServer.h index d6180ba3..e324a715 100644 --- a/include/boblightserver/BoblightServer.h +++ b/include/boblightserver/BoblightServer.h @@ -25,7 +25,7 @@ public: /// @param hyperion Hyperion instance /// @param port port number on which to start listening for connections /// - BoblightServer(Hyperion * hyperion, const int priority, uint16_t port = 19333); + BoblightServer(const int priority, uint16_t port = 19333); ~BoblightServer(); /// diff --git a/include/udplistener/UDPListener.h b/include/udplistener/UDPListener.h index ad587691..9b8f5154 100644 --- a/include/udplistener/UDPListener.h +++ b/include/udplistener/UDPListener.h @@ -25,7 +25,7 @@ public: /// @param hyperion Hyperion instance /// @param port port number on which to start listening for connections /// - UDPListener(Hyperion * hyperion, const int priority, const int timeout, uint16_t port = 2801); + UDPListener(const int priority, const int timeout, uint16_t port = 2801); ~UDPListener(); /// diff --git a/libsrc/boblightserver/BoblightServer.cpp b/libsrc/boblightserver/BoblightServer.cpp index 600a7d72..d06c2909 100644 --- a/libsrc/boblightserver/BoblightServer.cpp +++ b/libsrc/boblightserver/BoblightServer.cpp @@ -5,9 +5,9 @@ #include #include "BoblightClientConnection.h" -BoblightServer::BoblightServer(Hyperion *hyperion, const int priority,uint16_t port) : +BoblightServer::BoblightServer(const int priority,uint16_t port) : QObject(), - _hyperion(hyperion), + _hyperion(Hyperion::getInstance()), _server(), _openConnections(), _priority(priority) diff --git a/libsrc/udplistener/UDPListener.cpp b/libsrc/udplistener/UDPListener.cpp index 9dc06056..46d8c9ea 100644 --- a/libsrc/udplistener/UDPListener.cpp +++ b/libsrc/udplistener/UDPListener.cpp @@ -10,15 +10,14 @@ #include "utils/ColorRgb.h" #include "HyperionConfig.h" -UDPListener::UDPListener(Hyperion *hyperion, const int priority, const int timeout, uint16_t port) : +UDPListener::UDPListener(const int priority, const int timeout, uint16_t port) : QObject(), - _hyperion(hyperion), + _hyperion(Hyperion::getInstance()), _server(), _openConnections(), _priority(priority), _timeout(timeout), - _ledColors(hyperion->getLedCount(), ColorRgb::BLACK) - + _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK) { _server = new QUdpSocket(this); if (!_server->bind(QHostAddress::Any, port)) diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index bfa39be4..03f88456 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "HyperionConfig.h" @@ -35,7 +37,6 @@ HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent) , _amlGrabber(nullptr) , _fbGrabber(nullptr) , _osxGrabber(nullptr) - , _webConfig(nullptr) , _hyperion(nullptr) { loadConfig(configFile); @@ -55,29 +56,26 @@ HyperionDaemon::~HyperionDaemon() delete _protoServer; delete _boblightServer; delete _udpListener; - delete _webConfig; delete _hyperion; } void HyperionDaemon::run() { - startBootsequence(); + startInitialEffect(); createXBMCVideoChecker(); // ---- network services ----- startNetworkServices(); - _webConfig = new WebConfig(this); // ---- grabber ----- createGrabberV4L2(); createGrabberDispmanx(); createGrabberAmlogic(); createGrabberFramebuffer(); - createGrabberDispmanx(); #if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) - ErrorIf(_config.isMember("framegrabber"), _log, "No grabber can be instantiated, because all grabbers have been left out from the build"); + ErrorIf(_config.isMember("framegrabber"), _log, "No grabber can be instantiated, because all grabbers have been left out from the build"); #endif } @@ -106,54 +104,69 @@ void HyperionDaemon::loadConfig(const std::string & configFile) } -void HyperionDaemon::startBootsequence() +void HyperionDaemon::startInitialEffect() { Hyperion *hyperion = Hyperion::getInstance(); // create boot sequence if the configuration is present - if (_config.isMember("bootsequence")) + if (_config.isMember("initialEffect")) { - const Json::Value effectConfig = _config["bootsequence"]; - - // Get the parameters for the bootsequence - const std::string effectName = effectConfig["effect"].asString(); - const unsigned duration_ms = effectConfig["duration_ms"].asUInt(); - const int priority = (duration_ms != 0) ? 0 : effectConfig.get("priority",990).asInt(); - const int bootcolor_priority = (priority > 990) ? priority+1 : 990; + const Json::Value effectConfig = _config["initialEffect"]; + const int HIGHEST_PRIORITY = 0; + const int DURATION_INFINITY = 0; + const int LOWEST_PRIORITY = std::numeric_limits::max()-1; // clear the leds - ColorRgb boot_color = ColorRgb::BLACK; - hyperion->setColor(bootcolor_priority, boot_color, 0, false); + hyperion->setColor(HIGHEST_PRIORITY, ColorRgb::BLACK, DURATION_INFINITY, false); - // start boot effect - if ( ! effectName.empty() ) + // initial foreground effect/color + const Json::Value fgEffectConfig = effectConfig["foreground-effect"]; + int default_fg_duration_ms = 3000; + int fg_duration_ms = effectConfig.get("foreground-effect-duration_ms",default_fg_duration_ms).asUInt(); + if (fg_duration_ms == DURATION_INFINITY) { - int result; - std::cout << "INFO: Boot sequence '" << effectName << "' "; - if (effectConfig.isMember("args")) - { - std::cout << " (with user defined arguments) "; - const Json::Value effectConfigArgs = effectConfig["args"]; - result = hyperion->setEffect(effectName, effectConfigArgs, priority, duration_ms); - } - else - { - result = hyperion->setEffect(effectName, priority, duration_ms); - } - std::cout << ((result == 0) ? "started" : "failed") << std::endl; + fg_duration_ms = default_fg_duration_ms; + Warning(_log, "foreground effect duration 'infinity' is forbidden, set to default value %d ms",default_fg_duration_ms); } - - // static color - if ( ! effectConfig["color"].isNull() && effectConfig["color"].isArray() && effectConfig["color"].size() == 3 ) + if ( ! fgEffectConfig.isNull() && fgEffectConfig.isArray() && fgEffectConfig.size() == 3 ) { - boot_color = { - (uint8_t)effectConfig["color"][0].asUInt(), - (uint8_t)effectConfig["color"][1].asUInt(), - (uint8_t)effectConfig["color"][2].asUInt() + ColorRgb fg_color = { + (uint8_t)fgEffectConfig[0].asUInt(), + (uint8_t)fgEffectConfig[1].asUInt(), + (uint8_t)fgEffectConfig[2].asUInt() }; + hyperion->setColor(HIGHEST_PRIORITY, fg_color, fg_duration_ms, false); + Info(_log,"Inital foreground color set (%d %d %d)",fg_color.red,fg_color.green,fg_color.blue); + } + else if (! fgEffectConfig.isNull() && fgEffectConfig.isString()) + { + const std::string bgEffectName = fgEffectConfig.asString(); + int result = effectConfig.isMember("foreground-effect-args") + ? hyperion->setEffect(bgEffectName, effectConfig["foreground-effect-args"], HIGHEST_PRIORITY, fg_duration_ms) + : hyperion->setEffect(bgEffectName, HIGHEST_PRIORITY, fg_duration_ms); + Info(_log,"Inital foreground effect '%s' %s", bgEffectName.c_str(), ((result == 0) ? "started" : "failed")); } - hyperion->setColor(bootcolor_priority, boot_color, 0, false); + // initial background effect/color + const Json::Value bgEffectConfig = effectConfig["background-effect"]; + if ( ! bgEffectConfig.isNull() && bgEffectConfig.isArray() && bgEffectConfig.size() == 3 ) + { + ColorRgb bg_color = { + (uint8_t)bgEffectConfig[0].asUInt(), + (uint8_t)bgEffectConfig[1].asUInt(), + (uint8_t)bgEffectConfig[2].asUInt() + }; + hyperion->setColor(LOWEST_PRIORITY, bg_color, DURATION_INFINITY, false); + Info(_log,"Inital background color set (%d %d %d)",bg_color.red,bg_color.green,bg_color.blue); + } + else if (! bgEffectConfig.isNull() && bgEffectConfig.isString()) + { + const std::string bgEffectName = bgEffectConfig.asString(); + int result = effectConfig.isMember("background-effect-args") + ? hyperion->setEffect(bgEffectName, effectConfig["background-effect-args"], LOWEST_PRIORITY, DURATION_INFINITY) + : hyperion->setEffect(bgEffectName, LOWEST_PRIORITY, DURATION_INFINITY); + Info(_log,"Inital background effect '%s' %s", bgEffectName.c_str(), ((result == 0) ? "started" : "failed")); + } } } @@ -182,7 +195,6 @@ void HyperionDaemon::createXBMCVideoChecker() void HyperionDaemon::startNetworkServices() { - Hyperion *hyperion = Hyperion::getInstance(); XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance(); // Create Json server if configuration is present @@ -220,7 +232,7 @@ void HyperionDaemon::startNetworkServices() const Json::Value & boblightServerConfig = _config["boblightServer"]; if ( boblightServerConfig.get("enable", true).asBool() ) { - _boblightServer = new BoblightServer(hyperion, + _boblightServer = new BoblightServer( boblightServerConfig.get("priority",900).asInt(), boblightServerConfig["port"].asUInt() ); @@ -228,20 +240,20 @@ void HyperionDaemon::startNetworkServices() } } - // Create UDP listener if configuration is present - if (_config.isMember("udpListener")) - { - const Json::Value & udpListenerConfig = _config["udpListener"]; + // Create UDP listener if configuration is present + if (_config.isMember("udpListener")) + { + const Json::Value & udpListenerConfig = _config["udpListener"]; if ( udpListenerConfig.get("enable", true).asBool() ) { - _udpListener = new UDPListener(hyperion, + _udpListener = new UDPListener( udpListenerConfig.get("priority",700).asInt(), udpListenerConfig.get("timeout",10000).asInt(), udpListenerConfig.get("port", 2801).asUInt() ); Info(_log, "UDP listener created and started on port %d", _udpListener->getPort()); } - } + } // zeroconf description - $leddevicename@$hostname const Json::Value & deviceConfig = _config["device"]; @@ -275,7 +287,6 @@ void HyperionDaemon::startNetworkServices() _protoServer->getPort() ); Info(_log, "Proto mDNS responder started"); - } void HyperionDaemon::createGrabberDispmanx() diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index e05454d6..07f84d04 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -50,7 +50,7 @@ public: void loadConfig(const std::string & configFile); void run(); - void startBootsequence(); + void startInitialEffect(); void createXBMCVideoChecker(); void startNetworkServices(); diff --git a/src/hyperiond/main.cpp b/src/hyperiond/main.cpp index 183e349b..6a72c5e1 100644 --- a/src/hyperiond/main.cpp +++ b/src/hyperiond/main.cpp @@ -11,8 +11,7 @@ #include #include - - +#include #include "hyperiond.h" @@ -109,13 +108,24 @@ int main(int argc, char** argv) return 1; } - HyperionDaemon* hyperiond = new HyperionDaemon(configFiles[argvId], &app); - hyperiond->run(); + HyperionDaemon* hyperiond = nullptr; + try + { + hyperiond = new HyperionDaemon(configFiles[argvId], &app); + hyperiond->run(); + } + catch (...) + { + Error(log, "Hyperion Daemon aborted"); + } + WebConfig* webConfig = new WebConfig(&app); + // run the application int rc = app.exec(); Info(log, "INFO: Application closed with code %d", rc); + delete webConfig; delete hyperiond; return rc;