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
This commit is contained in:
redPanther 2016-06-20 23:41:07 +02:00 committed by brindosch
parent 3dab2ec405
commit eccd4e6637
7 changed files with 82 additions and 62 deletions

View File

@ -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();
///

View File

@ -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();
///

View File

@ -5,9 +5,9 @@
#include <boblightserver/BoblightServer.h>
#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)

View File

@ -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))

View File

@ -5,6 +5,8 @@
#include <QLocale>
#include <QFile>
#include <QHostInfo>
#include <cstdint>
#include <limits>
#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<int>::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()

View File

@ -50,7 +50,7 @@ public:
void loadConfig(const std::string & configFile);
void run();
void startBootsequence();
void startInitialEffect();
void createXBMCVideoChecker();
void startNetworkServices();

View File

@ -11,8 +11,7 @@
#include <getoptPlusPlus/getoptpp.h>
#include <utils/Logger.h>
#include <webconfig/WebConfig.h>
#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;