Threading and more

- webui remove restarts
- threading for LedDevice
This commit is contained in:
Paulchen-Panther 2019-01-01 19:47:07 +01:00
parent 7b6df922ea
commit 7352ff4d42
24 changed files with 482 additions and 282 deletions

View File

@ -1,5 +1,4 @@
$(document).ready( function() {
var uiLock = false;
loadContentTo("#container_connection_lost","connection_lost");
loadContentTo("#container_restart","restart");
@ -7,42 +6,26 @@ $(document).ready( function() {
$(hyperion).on("cmd-serverinfo",function(event){
serverInfo = event.response.info;
// protect components from serverinfo updates
if(!compsInited)
{
comps = event.response.info.components
compsInited = true;
}
// comps
comps = event.response.info.components
if(!priosInited)
{
priosInited = true;
}
$(hyperion).trigger("ready");
if (serverInfo.hyperion.config_modified)
$("#hyperion_reload_notify").fadeIn("fast");
else
$("#hyperion_reload_notify").fadeOut("fast");
comps.forEach( function(obj) {
if (obj.name == "ALL")
{
if(obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
});
if (serverInfo.hyperion.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
if (!serverInfo.hyperion.config_writeable)
{
showInfoDialog('uilock',$.i18n('InfoDialog_nowrite_title'),$.i18n('InfoDialog_nowrite_text'));
$('#wrapper').toggle(false);
uiLock = true;
}
else if (uiLock)
{
$("#modal_dialog").modal('hide');
$('#wrapper').toggle(true);
uiLock = false;
}
updateSessions();
}); // end cmd-serverinfo
@ -51,21 +34,21 @@ $(document).ready( function() {
updateSessions();
});
$(hyperion).one("cmd-sysinfo", function(event) {
$(hyperion).on("cmd-sysinfo", function(event) {
requestServerInfo();
sysInfo = event.response.info;
currentVersion = sysInfo.hyperion.version;
});
$(hyperion).one("cmd-config-getschema", function(event) {
$(hyperion).on("cmd-config-getschema", function(event) {
serverSchema = event.response.info;
requestServerConfig();
schema = serverSchema.properties;
});
$(hyperion).one("cmd-config-getconfig", function(event) {
$(hyperion).on("cmd-config-getconfig", function(event) {
serverConfig = event.response.info;
requestSysInfo();
@ -80,7 +63,7 @@ $(document).ready( function() {
requestServerConfigSchema();
});
$(hyperion).one("ready", function(event) {
$(hyperion).on("ready", function(event) {
loadContent();
});
@ -98,7 +81,7 @@ $(document).ready( function() {
// notfication in index
if (obj.name == "ALL")
{
if(obj.enable)
if(obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
@ -117,10 +100,6 @@ $(document).ready( function() {
serverInfo.effects = event.response.data.effects
});
$("#btn_hyperion_reload").on("click", function(){
initRestart();
});
$(".mnava").bind('click.menu', function(e){
loadContent(e);
window.scrollTo(0, 0);

View File

@ -203,6 +203,14 @@ $(document).ready(function() {
function updateComponents()
{
components = comps;
var hyperionEnabled = true;
components.forEach( function(obj) {
if (obj.name == "ALL")
{
hyperionEnabled = obj.enabled
}
});
// create buttons
$('#componentsbutton').html("");
for ( idx=0; idx<components.length;idx++)
@ -214,7 +222,7 @@ $(document).ready(function() {
enable_icon = (components[idx].enabled? "fa-play" : "fa-stop");
comp_name = components[idx].name;
comp_btn_id = "comp_btn_"+comp_name;
comp_goff = serverInfo.hyperion.enabled? "enabled" : "disabled";
comp_goff = hyperionEnabled? "enabled" : "disabled";
// create btn if not there
if ($("#"+comp_btn_id).length == 0)

View File

@ -25,14 +25,8 @@ var wSess = [];
var plugins_installed = {};
var plugins_available = {};
//comps serverinfo lock
//comps serverinfo
comps = [];
compsInited = false;
// prios serverinfo lock
priosInited = false;
// token list
tokenList = {}
function initRestart()
{

View File

@ -91,7 +91,7 @@ function getHashtag()
}
}
function loadContent(event)
function loadContent(event, forceRefresh)
{
var tag;
@ -104,7 +104,7 @@ function loadContent(event)
else
tag = getHashtag();
if(prevTag != tag)
if(forceRefresh || prevTag != tag)
{
prevTag = tag;
$("#page-content").off();

View File

@ -58,7 +58,7 @@
$('#wizp2_body').append('<div class="form-group"><label>'+$.i18n('wiz_rgb_switchevery')+'</label><div class="input-group" style="width:100px"><select id="wiz_switchtime_select" class="form-control"></select><div class="input-group-addon">'+$.i18n('edt_append_s')+'</div></div></div>');
$('#wizp2_body').append('<canvas id="wiz_canv_color" width="100" height="100" style="border-radius:60px;background-color:red; display:block; margin: 10px 0;border:4px solid grey;"></canvas><label>'+$.i18n('wiz_rgb_q')+'</label>');
$('#wizp2_body').append('<table class="table borderless" style="width:200px"><tbody><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qrend')+'</label></td><td class="itd"><select id="wiz_r_select" class="form-control wselect"></select></td></tr><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qgend')+'</label></td><td class="itd"><select id="wiz_g_select" class="form-control wselect"></select></td></tr></tbody></table>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saverestart')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_checkok" style="display:none" data-dismiss="modal"><i class="fa fa-fw fa-check"></i>'+$.i18n('general_btn_ok')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>')
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_checkok" style="display:none" data-dismiss="modal"><i class="fa fa-fw fa-check"></i>'+$.i18n('general_btn_ok')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>')
//open modal
$("#wizard_modal").modal({
@ -155,7 +155,6 @@
resetWizard();
serverConfig.device.colorOrder = new_rgb_order;
requestWriteConfig({"device" : serverConfig.device});
setTimeout(initRestart, 100);
});
}
@ -416,7 +415,7 @@
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('wiz_cc_title')+'</h4><p>'+$.i18n('wiz_cc_intro1')+'</p><label>'+$.i18n('wiz_cc_kwebs')+'</label><input class="form-control" style="width:170px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="'+kodiAddress+'" value="'+kodiAddress+'" /><span id="kodi_status"></span><span id="multi_cali"></span>');
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont" disabled="disabled"><i class="fa fa-fw fa-check"></i>'+$.i18n('general_btn_continue')+'</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
$('#wizp2_body').html('<div id="wiz_cc_desc" style="font-weight:bold"></div><div id="editor_container_wiz"></div>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back"><i class="fa fa-fw fa-chevron-left"></i>'+$.i18n('general_btn_back')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_next">'+$.i18n('general_btn_next')+'<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i></button><button type="button" class="btn btn-warning" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saverestart')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>')
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back"><i class="fa fa-fw fa-chevron-left"></i>'+$.i18n('general_btn_back')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_next">'+$.i18n('general_btn_next')+'<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i></button><button type="button" class="btn btn-warning" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>')
//open modal
$("#wizard_modal").modal({
@ -500,7 +499,6 @@
$('#btn_wiz_save').off().on('click',function() {
requestWriteConfig(wiz_editor.getValue());
resetWizard();
setTimeout(initRestart, 200);
});
wiz_editor.on("change", function(e){
@ -538,7 +536,7 @@
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold">'+$.i18n('wiz_hue_desc2')+'</p></div>');
createTable("lidsh", "lidsb", "hue_ids_t");
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lightid_title'),$.i18n('wiz_hue_pos'),$.i18n('wiz_hue_ident')], true));
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saverestart')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
$('#wizp3_body').html('<span>'+$.i18n('wiz_hue_press_link')+'</span> <br /><br /><center><span id="connectionTime"></span><br /><i class="fa fa-cog fa-spin" style="font-size:100px"></i></center>');
//open modal
@ -751,7 +749,7 @@
serverConfig.smoothing.enable = false;
requestWriteConfig(serverConfig, true);
setTimeout(initRestart,200);
resetWizard();
});
$('#btn_wiz_abort').off().on('click', resetWizard);

View File

@ -14,7 +14,7 @@
#include <utils/settings.h>
class Grabber;
class DispmanxFrameGrabber;
class GlobalSignals;
class QTimer;
///
@ -60,7 +60,6 @@ public:
return false;
}
public slots:
///
/// virtual method, should perform single frame grab and computes the led-colors

View File

@ -5,7 +5,7 @@
#include <QMap>
// QT includes
#include <QObject>
//#include <QObject>
#include <QString>
#include <QStringList>
#include <QSize>
@ -37,11 +37,9 @@
// Forward class declaration
class QTimer;
class HyperionDaemon;
class ImageProcessor;
class MessageForwarder;
class LedDevice;
class LinearColorSmoothing;
class EffectEngine;
class MultiColorAdjustment;
@ -50,6 +48,7 @@ class SettingsManager;
class BGEffectHandler;
class CaptureCont;
class BoblightServer;
class LedDeviceWrapper;
///
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
@ -228,6 +227,13 @@ public:
/// @return the state
bool sourceAutoSelectEnabled();
///
/// @brief Called from components to update their current state. DO NOT CALL FROM USERS
/// @param[in] component The component from enum
/// @param[in] state The state of the component [true | false]
///
void setNewComponentState(const hyperion::Components& component, const bool& state);
///
/// @brief Enable/Disable components during runtime, called from external API (requests)
///
@ -432,13 +438,9 @@ signals:
void effectListUpdated();
///
/// @brief systemImage from the parent HyperionDaemon SystemCapture
/// @brief Emits whenever new data should be pushed to the LedDeviceWrapper which forwards it to the threaded LedDevice
///
void systemImage(const Image<ColorRgb>& image);
///
/// @brief v4lImage from the parent HyperionDaemon V4lCapture
///
void v4lImage(const Image<ColorRgb> & image);
void ledDeviceData(const std::vector<ColorRgb>& ledValues);
///
/// @brief Emits whenever new untransformed ledColos data is available, reflects the current visible device
@ -504,8 +506,8 @@ private:
/// The adjustment from raw colors to led colors
MultiColorAdjustment * _raw2ledAdjustment;
/// The actual LedDevice
LedDevice * _device;
/// The actual LedDeviceWrapper
LedDeviceWrapper* _ledDeviceWrapper;
/// The smoothing LedDevice
LinearColorSmoothing * _deviceSmooth;
@ -513,7 +515,7 @@ private:
/// Effect engine
EffectEngine * _effectEngine;
// proto and json Message forwarder
// Message forwarder
MessageForwarder * _messageForwarder;
/// the name of config file

View File

@ -34,11 +34,8 @@ class LedDevice : public QObject
Q_OBJECT
public:
LedDevice();
///
/// Empty virtual destructor for pure virtual base class
///
virtual ~LedDevice() {}
LedDevice(const QJsonObject& config = QJsonObject(), QObject* parent = nullptr);
virtual ~LedDevice();
/// Switch the leds off (led hardware disable)
virtual int switchOff();
@ -48,33 +45,38 @@ public:
virtual int setLedValues(const std::vector<ColorRgb>& ledValues);
///
/// Opens and configures the output device
///
/// @return Zero on succes else negative
///
virtual int open();
///
/// @brief Get color order of device
/// @return The color order
///
const QString & getColorOrder() { return _colorOrder; };
static int addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr);
static const LedDeviceRegistry& getDeviceMap();
void setActiveDevice(QString dev);
const QString & getActiveDevice() { return _activeDevice; };
static QJsonObject getLedDeviceSchemas();
void setLedCount(int ledCount);
int getLedCount() { return _ledCount; }
void setEnable(bool enable);
bool enabled() { return _enabled; };
int getLatchTime() { return _latchTime_ms; };
const int getLatchTime() { return _latchTime_ms; };
inline bool componentState() { return enabled(); };
public slots:
///
/// Is called on thread start, all construction tasks and init should run here
///
virtual void start() { _deviceReady = open(); };
///
/// Writes the RGB-Color values to the leds.
///
/// @param[in] ledValues The RGB-color per led
///
/// @return Zero on success else negative
///
virtual int write(const std::vector<ColorRgb>& ledValues) = 0;
signals:
///
/// Emits whenever the led device switches between on/off
@ -83,16 +85,18 @@ signals:
void enableStateChanged(bool newState);
protected:
///
/// Writes the RGB-Color values to the leds.
///
/// @param[in] ledValues The RGB-color per led
///
/// @return Zero on success else negative
///
virtual int write(const std::vector<ColorRgb>& ledValues) = 0;
virtual bool init(const QJsonObject &deviceConfig);
///
/// Opens and configures the output device
///
/// @return Zero on succes else negative
///
virtual int open();
// Helper to pipe device config from constructor to start()
QJsonObject _devConfig;
/// The common Logger instance for all LedDevices
Logger * _log;
@ -102,7 +106,6 @@ protected:
bool _deviceReady;
QString _activeDevice;
static LedDeviceRegistry _ledDeviceMap;
int _ledCount;
int _ledRGBCount;

View File

@ -0,0 +1,111 @@
#pragma once
// util
#include <utils/Logger.h>
#include <utils/ColorRgb.h>
#include <utils/Components.h>
class LedDevice;
class Hyperion;
typedef LedDevice* ( *LedDeviceCreateFuncType ) ( const QJsonObject& );
typedef std::map<QString,LedDeviceCreateFuncType> LedDeviceRegistry;
///
/// @brief Creates and destroys LedDevice instances with LedDeviceFactory and moves the device to a thread. Pipes all signal/slots and methods to LedDevice instance
///
class LedDeviceWrapper : public QObject
{
Q_OBJECT
public:
LedDeviceWrapper(Hyperion* hyperion);
~LedDeviceWrapper();
///
/// @brief Contructs a new LedDevice, moves to thread and starts
/// @param config With the given config
///
void createLedDevice(const QJsonObject& config);
///
/// @brief Get all available device schemas
/// @return device schemas
///
static const QJsonObject getLedDeviceSchemas();
///
/// @brief add all device constrcutors to the map
///
static int addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr);
///
/// @brief Return all available device contructors
/// @return device constrcutors
///
static const LedDeviceRegistry& getDeviceMap();
///
/// @brief Get the current latchtime of the ledDevice
/// @ return latchtime in ms
///
int getLatchTime();
///
/// @brief Get the current active ledDevice
///
const QString & getActiveDevice();
///
/// @brief Return the last enable state
///
const bool & enabled() { return _enabled; };
///
/// @brief Get the current colorOrder from device
///
const QString & getColorOrder();
public slots:
///
/// @brief Handle new component state request
/// @apram component The comp from enum
/// @param state The new state
///
void handleComponentState(const hyperion::Components component, const bool state);
signals:
///
/// PIPER signal for Hyperion -> LedDevice
///
/// @param[in] ledValues The RGB-color per led
///
/// @return Zero on success else negative
///
int write(const std::vector<ColorRgb>& ledValues);
private slots:
///
/// @brief Is called whenever the led device switches between on/off. The led device can disable it's component state
/// The signal comes from the LedDevice
/// @param newState The new state of the device
///
void handleInternalEnableState(bool newState);
protected:
/// contains all available led device constrcutors
static LedDeviceRegistry _ledDeviceMap;
private:
///
/// @brief switchOff() the device and Stops the device thread
///
void stopDeviceThread();
private:
// parent Hyperion
Hyperion* _hyperion;
// Pointer of current led device
LedDevice* _ledDevice;
// the enable state
bool _enabled;
};

View File

@ -0,0 +1,41 @@
#pragma once
// util
#include <utils/Image.h>
#include <utils/ColorRgb.h>
// qt
#include <QObject>
///
/// Singleton instance for simple signal sharing across threads, should be never used with Qt:DirectConnection!
///
class GlobalSignals : public QObject
{
Q_OBJECT
public:
static GlobalSignals* getInstance()
{
static GlobalSignals instance;
return & instance;
}
private:
GlobalSignals() {}
public:
GlobalSignals(GlobalSignals const&) = delete;
void operator=(GlobalSignals const&) = delete;
signals:
///
/// @brief PIPE SystemCapture images from GrabberWrapper to Hyperion class
/// @param image The prepared image
///
void setSystemImage(const Image<ColorRgb>& image);
///
/// @brief PIPE v4lCapture images from v4lCapture over HyperionDaemon to Hyperion class
/// @param image The prepared image
///
void setV4lImage(const Image<ColorRgb> & image);
};

View File

@ -22,7 +22,7 @@
#include <utils/SysInfo.h>
#include <HyperionConfig.h>
#include <utils/ColorSys.h>
#include <leddevice/LedDevice.h>
#include <leddevice/LedDeviceWrapper.h>
#include <hyperion/GrabberWrapper.h>
#include <utils/Process.h>
#include <utils/JsonUtils.h>
@ -50,6 +50,8 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, QObject* parent, bool noListe
, _image_stream_timeout(0)
, _led_stream_timeout(0)
{
Q_INIT_RESOURCE(JSONRPC_schemas);
// the JsonCB creates json messages you can subscribe to e.g. data change events; forward them to the parent client
connect(_jsonCB, &JsonCB::newCallback, this, &JsonAPI::callbackMessage);
@ -63,7 +65,6 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, QObject* parent, bool noListe
void JsonAPI::handleMessage(const QString& messageString)
{
const QString ident = "JsonRpc@"+_peerAddress;
Q_INIT_RESOURCE(JSONRPC_schemas);
QJsonObject message;
// parse the message
if(!JsonUtils::parse(ident, messageString, message, _log))
@ -408,7 +409,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
QJsonObject ledDevices;
ledDevices["active"] = _hyperion->getActiveDevice();
QJsonArray availableLedDevices;
for (auto dev: LedDevice::getDeviceMap())
for (auto dev: LedDeviceWrapper::getDeviceMap())
{
availableLedDevices.append(dev.first);
}
@ -696,7 +697,7 @@ void JsonAPI::handleSchemaGetCommand(const QJsonObject& message, const QString&
// collect all LED Devices
properties = schemaJson["properties"].toObject();
alldevices = LedDevice::getLedDeviceSchemas();
alldevices = LedDeviceWrapper::getLedDeviceSchemas();
properties.insert("alldevices", alldevices);
// collect all available effect schemas

View File

@ -1,6 +1,12 @@
#include <hyperion/CaptureCont.h>
// hyperion includes
#include <hyperion/Hyperion.h>
// utils includes
#include <utils/GlobalSignals.h>
// qt includes
#include <QTimer>
CaptureCont::CaptureCont(Hyperion* hyperion)
@ -56,11 +62,11 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable)
if(enable)
{
_hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER);
connect(_hyperion, &Hyperion::systemImage, this, &CaptureCont::handleSystemImage);
connect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, this, &CaptureCont::handleSystemImage);
}
else
{
disconnect(_hyperion, &Hyperion::systemImage, this, &CaptureCont::handleSystemImage);
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, 0, 0);
_hyperion->clear(_systemCaptPrio);
}
_systemCaptEnabled = enable;
@ -75,11 +81,11 @@ void CaptureCont::setV4LCaptureEnable(const bool& enable)
if(enable)
{
_hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L);
connect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage);
connect(GlobalSignals::getInstance(), &GlobalSignals::setV4lImage, this, &CaptureCont::handleV4lImage);
}
else
{
disconnect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage);
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setV4lImage, 0, 0);
_hyperion->clear(_v4lCaptPrio);
_v4lInactiveTimer->stop();
}

View File

@ -3,6 +3,9 @@
#include <hyperion/Grabber.h>
#include <HyperionConfig.h>
// utils includes
#include <utils/GlobalSignals.h>
// qt
#include <QTimer>
@ -20,6 +23,11 @@ GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned
_image.resize(width, height);
connect(_timer, &QTimer::timeout, this, &GrabberWrapper::action);
// connect the image forwarding
_grabberName.startsWith("V4L")
? connect(this, &GrabberWrapper::systemImage, GlobalSignals::getInstance(), &GlobalSignals::setV4lImage)
: connect(this, &GrabberWrapper::systemImage, GlobalSignals::getInstance(), &GlobalSignals::setSystemImage);
}
GrabberWrapper::~GrabberWrapper()

View File

@ -26,8 +26,7 @@
#include <utils/hyperion.h>
// Leddevice includes
#include <leddevice/LedDevice.h>
#include <leddevice/LedDeviceFactory.h>
#include <leddevice/LedDeviceWrapper.h>
#include <hyperion/MultiColorAdjustment.h>
#include "LinearColorSmoothing.h"
@ -127,22 +126,23 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString
QJsonObject ledDevice = getSetting(settings::DEVICE).object();
ledDevice["currentLedCount"] = int(_hwLedCount); // Inject led count info
_device = LedDeviceFactory::construct(ledDevice);
_deviceSmooth = new LinearColorSmoothing(_device, getSetting(settings::SMOOTHING), this);
_ledDeviceWrapper = new LedDeviceWrapper(this);
connect(this, &Hyperion::componentStateChanged, _ledDeviceWrapper, &LedDeviceWrapper::handleComponentState);
connect(this, &Hyperion::ledDeviceData, _ledDeviceWrapper, &LedDeviceWrapper::write);
_ledDeviceWrapper->createLedDevice(ledDevice);
// smoothing
_deviceSmooth = new LinearColorSmoothing(getSetting(settings::SMOOTHING), this);
connect(this, &Hyperion::settingsChanged, _deviceSmooth, &LinearColorSmoothing::handleSettingsUpdate);
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
// create the effect engine and pipe the updateEmit; must be initialized after smoothing!
// create the effect engine; needs to be initialized after smoothing!
_effectEngine = new EffectEngine(this);
connect(_effectEngine, &EffectEngine::effectListUpdated, this, &Hyperion::effectListUpdated);
// setup config state checks and initial shot
checkConfigState();
if(_fsWatcher.addPath(_configFile))
{
QObject::connect(&_fsWatcher, &QFileSystemWatcher::fileChanged, this, &Hyperion::checkConfigState);
}
else
{
_cTimer = new QTimer(this);
@ -153,6 +153,7 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString
// initial startup effect
hyperion::handleInitialEffect(this, getSetting(settings::FGEFFECT).object());
// handle background effect
_BGEffectHandler = new BGEffectHandler(this);
@ -163,7 +164,6 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString
update();
// boblight, can't live in global scope as it depends on layout
_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER));
connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate);
}
@ -188,10 +188,10 @@ void Hyperion::freeObjects(bool emitCloseSignal)
delete _captureCont;
delete _effectEngine;
//delete _deviceSmooth;
delete _device;
delete _raw2ledAdjustment;
delete _messageForwarder;
delete _settingsManager;
delete _ledDeviceWrapper;
}
void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
@ -241,7 +241,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
_hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount());
// update led count in device
_device->setLedCount(_hwLedCount);
//_ledDeviceWrapper->setLedCount(_hwLedCount);
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment;
@ -262,7 +262,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
_hwLedCount = qMax(unsigned(dev["hardwareLedCount"].toInt(getLedCount())), getLedCount());
// force ledString update, if device ByteOrder changed
if(_device->getColorOrder() != dev["colorOrder"].toString("rgb"))
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))
{
_ledString = hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
_ledStringClone = hyperion::createLedStringClone(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
@ -276,16 +276,9 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
// update led count
_device->setLedCount(_hwLedCount);
*/
// do always reinit
// TODO segfaulting in LinearColorSmoothing::queueColor triggert from QTimer because of device->setLEdValues (results from gdb debugging and testing)
bool wasEnabled = _deviceSmooth->enabled();
_deviceSmooth->stopTimer();
delete _device;
// do always reinit until the led devices can handle dynamic changes
dev["currentLedCount"] = int(_hwLedCount); // Inject led count info
_device = LedDeviceFactory::construct(dev);
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
if(wasEnabled)
_deviceSmooth->startTimerDelayed();
_ledDeviceWrapper->createLedDevice(dev);
_lockUpdate = false;
}
// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
@ -310,7 +303,7 @@ QString Hyperion::getConfigFileName() const
int Hyperion::getLatchTime() const
{
return _device->getLatchTime();
return _ledDeviceWrapper->getLatchTime();
}
unsigned Hyperion::addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
@ -373,18 +366,14 @@ bool Hyperion::sourceAutoSelectEnabled()
return _muxer.isSourceAutoSelectEnabled();
}
void Hyperion::setNewComponentState(const hyperion::Components& component, const bool& state)
{
_componentRegister.componentStateChanged(component, state);
}
void Hyperion::setComponentState(const hyperion::Components component, const bool state)
{
switch (component)
{
case hyperion::COMP_LEDDEVICE:
_device->setEnable(state);
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
break;
default:
emit componentStateChanged(component, state);
}
emit componentStateChanged(component, state);
}
void Hyperion::registerInput(const int priority, const hyperion::Components& component, const QString& origin, const QString& owner, unsigned smooth_cfg)
@ -571,7 +560,7 @@ const VideoMode & Hyperion::getCurrentVideoMode()
const QString & Hyperion::getActiveDevice()
{
return _device->getActiveDevice();
return _ledDeviceWrapper->getActiveDevice();
}
void Hyperion::updatedComponentState(const hyperion::Components comp, const bool state)
@ -681,7 +670,7 @@ void Hyperion::update()
}
// Write the data to the device
if (_device->enabled())
if (_ledDeviceWrapper->enabled())
{
_deviceSmooth->selectConfig(priorityInfo.smooth_cfg);
@ -690,6 +679,6 @@ void Hyperion::update()
_deviceSmooth->setLedValues(_ledBuffer);
if (! _deviceSmooth->enabled())
_device->setLedValues(_ledBuffer);
emit ledDeviceData(_ledBuffer);
}
}

View File

@ -9,9 +9,8 @@
using namespace hyperion;
LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, const QJsonDocument& config, Hyperion* hyperion)
: LedDevice()
, _ledDevice(ledDevice)
LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument& config, Hyperion* hyperion)
: LedDevice(QJsonObject(), hyperion)
, _log(Logger::getInstance("SMOOTHING"))
, _hyperion(hyperion)
, _updateInterval(1000)
@ -42,8 +41,7 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, const QJsonDo
LinearColorSmoothing::~LinearColorSmoothing()
{
// Make sure to switch off the underlying led-device (because switchOff is no longer forwarded)
_ledDevice->switchOff();
}
void LinearColorSmoothing::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
@ -148,7 +146,8 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
{
// No output delay => immediate write
if ( _writeToLedsEnable && !_pause)
_ledDevice->setLedValues(ledColors);
emit _hyperion->ledDeviceData(ledColors);
}
else
{
@ -163,7 +162,7 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
{
if (!_pause)
{
_ledDevice->setLedValues(_outputQueue.front());
emit _hyperion->ledDeviceData(_outputQueue.front());
}
_outputQueue.pop_front();
}
@ -235,18 +234,3 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, const bool& force)
_currentConfigId = 0;
return false;
}
void LinearColorSmoothing::startTimerDelayed()
{
QTimer::singleShot(500, this, SLOT(delayStartTimer()));
}
void LinearColorSmoothing::stopTimer()
{
_timer->stop();
}
void LinearColorSmoothing::delayStartTimer()
{
_timer->start();
}

View File

@ -28,11 +28,10 @@ class LinearColorSmoothing : public LedDevice
public:
/// Constructor
/// @param LedDevice the led device
/// @param config The configuration document smoothing
/// @param hyperion The hyperion parent instance
///
LinearColorSmoothing(LedDevice *ledDevice, const QJsonDocument& config, Hyperion* hyperion);
LinearColorSmoothing(const QJsonDocument& config, Hyperion* hyperion);
/// Destructor
virtual ~LinearColorSmoothing();
@ -71,12 +70,6 @@ public:
///
bool selectConfig(unsigned cfg, const bool& force = false);
///
/// @ Helper methods to start the timer with delay (see delayStartSmooth())
///
void startTimerDelayed();
void stopTimer();
public slots:
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
@ -89,9 +82,6 @@ private slots:
/// Timer callback which writes updated led values to the led device
void updateLeds();
/// Delay timer slot to workaround the leddevice reconstruction segfault (dangling pointer)
void delayStartTimer();
///
/// @brief Handle component state changes
/// @param component The component
@ -107,9 +97,6 @@ private:
*/
void queueColors(const std::vector<ColorRgb> & ledColors);
/// The led device
LedDevice * _ledDevice;
/// Logger instance
Logger* _log;

View File

@ -10,10 +10,9 @@
#include "hyperion/Hyperion.h"
#include <utils/JsonUtils.h>
LedDeviceRegistry LedDevice::_ledDeviceMap = LedDeviceRegistry();
LedDevice::LedDevice()
: QObject()
LedDevice::LedDevice(const QJsonObject& config, QObject* parent)
: QObject(parent)
, _devConfig(config)
, _log(Logger::getInstance("LEDDEVICE"))
, _ledBuffer(0)
, _deviceReady(true)
@ -24,15 +23,16 @@ LedDevice::LedDevice()
, _componentRegistered(false)
, _enabled(true)
{
LedDevice::getLedDeviceSchemas();
qRegisterMetaType<hyperion::Components>("hyperion::Components");
// setup timer
_refresh_timer.setSingleShot(false);
_refresh_timer.setInterval(0);
connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds()));
}
LedDevice::~LedDevice()
{
}
// dummy implemention
int LedDevice::open()
{
@ -55,17 +55,6 @@ void LedDevice::setEnable(bool enable)
_enabled = enable;
}
int LedDevice::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr)
{
_ledDeviceMap.emplace(name,funcPtr);
return 0;
}
const LedDeviceRegistry& LedDevice::getDeviceMap()
{
return _ledDeviceMap;
}
void LedDevice::setActiveDevice(QString dev)
{
_activeDevice = dev;
@ -88,42 +77,6 @@ bool LedDevice::init(const QJsonObject &deviceConfig)
return true;
}
QJsonObject LedDevice::getLedDeviceSchemas()
{
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE(LedDeviceSchemas);
// read the json schema from the resource
QDir d(":/leddevices/");
QStringList l = d.entryList();
QJsonObject result, schemaJson;
for(QString &item : l)
{
QString schemaPath(QString(":/leddevices/")+item);
QString devName = item.remove("schema-");
QString data;
if(!FileUtils::readFile(schemaPath, data, Logger::getInstance("LedDevice")))
{
throw std::runtime_error("ERROR: Schema not found: " + item.toStdString());
}
QJsonObject schema;
if(!JsonUtils::parse(schemaPath, data, schema, Logger::getInstance("LedDevice")))
{
throw std::runtime_error("ERROR: Json schema wrong of file: " + item.toStdString());
}
schemaJson = schema;
schemaJson["title"] = QString("edt_dev_spec_header_title");
result[devName] = schemaJson;
}
return result;
}
int LedDevice::setLedValues(const std::vector<ColorRgb>& ledValues)
{
int retval = 0;

View File

@ -7,10 +7,11 @@
// Leddevice includes
#include <leddevice/LedDeviceFactory.h>
#include <leddevice/LedDeviceWrapper.h>
#include <utils/Logger.h>
#include <leddevice/LedDevice.h>
// following file is auto generated by cmake! it contains all available leddevice headers
// autogen
#include "LedDevice_headers.h"
LedDevice * LedDeviceFactory::construct(const QJsonObject & deviceConfig)
@ -21,14 +22,7 @@ LedDevice * LedDeviceFactory::construct(const QJsonObject & deviceConfig)
QString type = deviceConfig["type"].toString("UNSPECIFIED").toLower();
#define REGISTER(className) LedDevice::addToDeviceMap(QString(#className).toLower(), LedDevice##className::construct);
// the REGISTER() calls are autogenerated by cmake.
#include "LedDevice_register.cpp"
#undef REGISTER
const LedDeviceRegistry& devList = LedDevice::getDeviceMap();
const LedDeviceRegistry& devList = LedDeviceWrapper::getDeviceMap();
LedDevice* device = nullptr;
try
{
@ -56,7 +50,5 @@ LedDevice * LedDeviceFactory::construct(const QJsonObject & deviceConfig)
device = LedDeviceFile::construct(QJsonObject());
}
device->open();
return device;
}

View File

@ -0,0 +1,148 @@
#include <leddevice/LedDeviceWrapper.h>
#include <leddevice/LedDevice.h>
#include <leddevice/LedDeviceFactory.h>
// following file is auto generated by cmake! it contains all available leddevice headers
#include "LedDevice_headers.h"
// util
#include <hyperion/Hyperion.h>
#include <utils/JsonUtils.h>
// qt
#include <QThread>
#include <QDir>
LedDeviceRegistry LedDeviceWrapper::_ledDeviceMap = LedDeviceRegistry();
LedDeviceWrapper::LedDeviceWrapper(Hyperion* hyperion)
: QObject(hyperion)
, _hyperion(hyperion)
, _ledDevice(nullptr)
{
// prepare the device constrcutor map
#define REGISTER(className) LedDeviceWrapper::addToDeviceMap(QString(#className).toLower(), LedDevice##className::construct);
// the REGISTER() calls are autogenerated by cmake.
#include "LedDevice_register.cpp"
#undef REGISTER
_hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, true);
}
LedDeviceWrapper::~LedDeviceWrapper()
{
stopDeviceThread();
}
void LedDeviceWrapper::createLedDevice(const QJsonObject& config)
{
if(_ledDevice != nullptr)
{
stopDeviceThread();
}
// create thread and device
QThread* thread = new QThread(this);
_ledDevice = LedDeviceFactory::construct(config);
_ledDevice->moveToThread(thread);
// setup thread management
connect(thread, &QThread::started, _ledDevice, &LedDevice::start);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(thread, &QThread::finished, _ledDevice, &QObject::deleteLater);
// further signals
connect(this, &LedDeviceWrapper::write, _ledDevice, &LedDevice::write);
connect(_ledDevice, &LedDevice::enableStateChanged, this, &LedDeviceWrapper::handleInternalEnableState);
// start the thread
thread->start();
}
const QJsonObject LedDeviceWrapper::getLedDeviceSchemas()
{
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE(LedDeviceSchemas);
// read the json schema from the resource
QDir d(":/leddevices/");
QStringList l = d.entryList();
QJsonObject result, schemaJson;
for(QString &item : l)
{
QString schemaPath(QString(":/leddevices/")+item);
QString devName = item.remove("schema-");
QString data;
if(!FileUtils::readFile(schemaPath, data, Logger::getInstance("LedDevice")))
{
throw std::runtime_error("ERROR: Schema not found: " + item.toStdString());
}
QJsonObject schema;
if(!JsonUtils::parse(schemaPath, data, schema, Logger::getInstance("LedDevice")))
{
throw std::runtime_error("ERROR: Json schema wrong of file: " + item.toStdString());
}
schemaJson = schema;
schemaJson["title"] = QString("edt_dev_spec_header_title");
result[devName] = schemaJson;
}
return result;
}
int LedDeviceWrapper::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr)
{
_ledDeviceMap.emplace(name,funcPtr);
return 0;
}
const LedDeviceRegistry& LedDeviceWrapper::getDeviceMap()
{
return _ledDeviceMap;
}
int LedDeviceWrapper::getLatchTime()
{
return _ledDevice->getLatchTime();
}
const QString & LedDeviceWrapper::getActiveDevice()
{
return _ledDevice->getActiveDevice();
}
const QString & LedDeviceWrapper::getColorOrder()
{
return _ledDevice->getColorOrder();
}
void LedDeviceWrapper::handleComponentState(const hyperion::Components component, const bool state)
{
if(component == hyperion::COMP_LEDDEVICE)
{
_ledDevice->setEnable(state);
_hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, _ledDevice->componentState());
_enabled = state;
}
}
void LedDeviceWrapper::handleInternalEnableState(bool newState)
{
_hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, newState);
_enabled = newState;
}
void LedDeviceWrapper::stopDeviceThread()
{
_ledDevice->switchOff();
QThread* oldThread = _ledDevice->thread();
delete _ledDevice; // fast desctruction
oldThread->quit(); // non blocking
}

View File

@ -201,7 +201,7 @@ void PhilipsHueBridge::resolveReply(QNetworkReply* reply)
void PhilipsHueBridge::post(QString route, QString content)
{
Debug(log, "Post %s: %s", QSTRING_CSTR(QString("http://IP/api/USR/%1").arg(route)), QSTRING_CSTR(content));
//Debug(log, "Post %s: %s", QSTRING_CSTR(QString("http://IP/api/USR/%1").arg(route)), QSTRING_CSTR(content));
QNetworkRequest request(QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route));
manager.put(request, content.toLatin1());
@ -214,7 +214,7 @@ const std::set<QString> PhilipsHueLight::GAMUT_B_MODEL_IDS =
const std::set<QString> PhilipsHueLight::GAMUT_C_MODEL_IDS =
{ "LLC020", "LST002", "LCT011", "LCT012", "LCT010", "LCT014" };
PhilipsHueLight::PhilipsHueLight(Logger* log, PhilipsHueBridge& bridge, unsigned int id, QJsonObject values)
PhilipsHueLight::PhilipsHueLight(Logger* log, PhilipsHueBridge* bridge, unsigned int id, QJsonObject values)
: log(log)
, bridge(bridge)
, id(id)
@ -297,7 +297,7 @@ PhilipsHueLight::~PhilipsHueLight()
void PhilipsHueLight::set(QString state)
{
bridge.post(QString("lights/%1/state").arg(id), state);
bridge->post(QString("lights/%1/state").arg(id), state);
}
void PhilipsHueLight::setOn(bool on)
@ -345,18 +345,25 @@ LedDevice* LedDevicePhilipsHue::construct(const QJsonObject &deviceConfig)
}
LedDevicePhilipsHue::LedDevicePhilipsHue(const QJsonObject& deviceConfig)
: LedDevice()
, bridge(_log, deviceConfig["output"].toString(), deviceConfig["username"].toString())
: LedDevice(deviceConfig)
, _bridge(nullptr)
{
_deviceReady = init(deviceConfig);
connect(&bridge, &PhilipsHueBridge::newLights, this, &LedDevicePhilipsHue::newLights);
connect(this, &LedDevice::enableStateChanged, this, &LedDevicePhilipsHue::stateChanged);
}
LedDevicePhilipsHue::~LedDevicePhilipsHue()
{
switchOff();
delete _bridge;
}
void LedDevicePhilipsHue::start()
{
_bridge = new PhilipsHueBridge(_log, _devConfig["output"].toString(), _devConfig["username"].toString());
_deviceReady = init(_devConfig);
connect(_bridge, &PhilipsHueBridge::newLights, this, &LedDevicePhilipsHue::newLights);
connect(this, &LedDevice::enableStateChanged, this, &LedDevicePhilipsHue::stateChanged);
}
bool LedDevicePhilipsHue::init(const QJsonObject &deviceConfig)
@ -374,7 +381,7 @@ bool LedDevicePhilipsHue::init(const QJsonObject &deviceConfig)
lightIds.push_back(i.toInt());
}
// get light info from bridge
bridge.bConnect();
_bridge->bConnect();
// adapt latchTime to count of user lightIds (bridge 10Hz max overall)
newDC.insert("latchTime",QJsonValue(100*(int)lightIds.size()));
@ -399,7 +406,7 @@ void LedDevicePhilipsHue::newLights(QMap<quint16, QJsonObject> map)
{
if (map.contains(id))
{
lights.push_back(PhilipsHueLight(_log, bridge, id, map.value(id)));
lights.push_back(PhilipsHueLight(_log, _bridge, id, map.value(id)));
}
else
{
@ -427,7 +434,6 @@ int LedDevicePhilipsHue::write(const std::vector<ColorRgb> & ledValues)
{
// Get color.
ColorRgb color = ledValues.at(idx);
// Scale colors from [0, 255] to [0, 1] and convert to xy space.
CiColor xy = CiColor::rgbToCiColor(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f,
light.getColorSpace());
@ -453,7 +459,7 @@ int LedDevicePhilipsHue::write(const std::vector<ColorRgb> & ledValues)
void LedDevicePhilipsHue::stateChanged(bool newState)
{
if(newState)
bridge.bConnect();
_bridge->bConnect();
else
lights.clear();
}

View File

@ -139,7 +139,7 @@ class PhilipsHueLight
{
private:
Logger* log;
PhilipsHueBridge& bridge;
PhilipsHueBridge* bridge;
/// light id
unsigned int id;
bool on;
@ -172,7 +172,7 @@ public:
/// @param bridge the bridge
/// @param id the light id
///
PhilipsHueLight(Logger* log, PhilipsHueBridge& bridge, unsigned int id, QJsonObject values);
PhilipsHueLight(Logger* log, PhilipsHueBridge* bridge, unsigned int id, QJsonObject values);
~PhilipsHueLight();
///
@ -227,6 +227,10 @@ public:
/// constructs leddevice
static LedDevice* construct(const QJsonObject &deviceConfig);
public slots:
/// thread start
virtual void start();
private slots:
/// creates new PhilipsHueLight(s) based on user lightid with bridge feedback
///
@ -249,7 +253,7 @@ protected:
private:
/// bridge class
PhilipsHueBridge bridge;
PhilipsHueBridge* _bridge;
///
bool switchOffOnBlack;

View File

@ -40,7 +40,7 @@ bool LedDeviceTinkerforge::init(const QJsonObject &deviceConfig)
_uid = deviceConfig["uid"].toString();
_interval = deviceConfig["rate"].toInt();
if ((unsigned)_ledCount > MAX_NUM_LEDS)
if ((unsigned)_ledCount > MAX_NUM_LEDS)
{
Error(_log,"Invalid attempt to write led values. Not more than %d leds are allowed.", MAX_NUM_LEDS);
return -1;
@ -68,7 +68,7 @@ int LedDeviceTinkerforge::open()
if (_ipConnection != nullptr)
{
Error(_log, "Attempt to open existing connection; close before opening");
return -1;
return 0;
}
// Initialise a new connection
@ -76,10 +76,10 @@ int LedDeviceTinkerforge::open()
ipcon_create(_ipConnection);
int connectionStatus = ipcon_connect(_ipConnection, QSTRING_CSTR(_host), _port);
if (connectionStatus < 0)
if (connectionStatus < 0)
{
Warning(_log, "Attempt to connect to master brick (%s:%d) failed with status %d", QSTRING_CSTR(_host), _port, connectionStatus);
return -1;
Error(_log, "Attempt to connect to master brick (%s:%d) failed with status %d", QSTRING_CSTR(_host), _port, connectionStatus);
return 0;
}
// Create the 'LedStrip'
@ -87,17 +87,20 @@ int LedDeviceTinkerforge::open()
led_strip_create(_ledStrip, QSTRING_CSTR(_uid), _ipConnection);
int frameStatus = led_strip_set_frame_duration(_ledStrip, _interval);
if (frameStatus < 0)
if (frameStatus < 0)
{
Error(_log,"Attempt to connect to led strip bricklet (led_strip_set_frame_duration()) failed with status %d", frameStatus);
return -1;
return 0;
}
return 0;
return 1;
}
int LedDeviceTinkerforge::write(const std::vector<ColorRgb> &ledValues)
{
if(!_deviceReady)
return 0;
auto redIt = _redChannel.begin();
auto greenIt = _greenChannel.begin();
auto blueIt = _blueChannel.begin();
@ -115,7 +118,7 @@ int LedDeviceTinkerforge::write(const std::vector<ColorRgb> &ledValues)
return transferLedData(_ledStrip, 0, _colorChannelSize, _redChannel.data(), _greenChannel.data(), _blueChannel.data());
}
int LedDeviceTinkerforge::transferLedData(LEDStrip *ledStrip, unsigned index, unsigned length, uint8_t *redChannel, uint8_t *greenChannel, uint8_t *blueChannel)
int LedDeviceTinkerforge::transferLedData(LEDStrip *ledStrip, unsigned index, unsigned length, uint8_t *redChannel, uint8_t *greenChannel, uint8_t *blueChannel)
{
if (length == 0 || index >= length || length > MAX_NUM_LEDS)
{

View File

@ -90,14 +90,13 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
Info(_log, "Hyperion initialized");
connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects()));
//connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects())); for app restart refactor required
// listen for setting changes
connect(_hyperion, &Hyperion::settingsChanged, this, &HyperionDaemon::settingsChanged);
// listen for setting changes of framegrabber and v4l2
connect(this, &HyperionDaemon::settingsChanged, this, &HyperionDaemon::handleSettingsUpdate);
// forward system and v4l images to Hyperion
connect(this, &HyperionDaemon::systemImage, _hyperion, &Hyperion::systemImage);
connect(this, &HyperionDaemon::v4lImage, _hyperion, &Hyperion::v4lImage);
// forward videoModes from Hyperion to Daemon evaluation
connect(_hyperion, &Hyperion::videoMode, this, &HyperionDaemon::setVideoMode);
// forward videoMode changes from Daemon to Hyperion
@ -107,6 +106,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_AMLOGIC)
Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build");
#endif
// init system capture (framegrabber)
handleSettingsUpdate(settings::SYSTEMCAPTURE, getSetting(settings::SYSTEMCAPTURE));
// init v4l2 capture
@ -379,7 +379,6 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
Debug(_log, "V4L2 grabber created");
// connect to HyperionDaemon signal
connect(grabber, &V4L2Wrapper::systemImage, this, &HyperionDaemon::v4lImage);
connect(this, &HyperionDaemon::videoMode, grabber, &V4L2Wrapper::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate);
@ -399,7 +398,6 @@ void HyperionDaemon::createGrabberDispmanx()
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _dispmanx, &DispmanxWrapper::setVideoMode);
connect(_dispmanx, &DispmanxWrapper::systemImage, this, &HyperionDaemon::systemImage);
connect(this, &HyperionDaemon::settingsChanged, _dispmanx, &DispmanxWrapper::handleSettingsUpdate);
_dispmanx->start();
@ -419,7 +417,6 @@ void HyperionDaemon::createGrabberAmlogic()
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _amlGrabber, &AmlogicWrapper::setVideoMode);
connect(_amlGrabber, &AmlogicWrapper::systemImage, this, &HyperionDaemon::systemImage);
connect(this, &HyperionDaemon::settingsChanged, _amlGrabber, &AmlogicWrapper::handleSettingsUpdate);
_amlGrabber->start();
@ -440,7 +437,6 @@ void HyperionDaemon::createGrabberX11(const QJsonObject & grabberConfig)
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _x11Grabber, &X11Wrapper::setVideoMode);
connect(_x11Grabber, &X11Wrapper::systemImage, this, &HyperionDaemon::systemImage);
connect(this, &HyperionDaemon::settingsChanged, _x11Grabber, &X11Wrapper::handleSettingsUpdate);
_x11Grabber->start();
@ -461,7 +457,6 @@ void HyperionDaemon::createGrabberFramebuffer(const QJsonObject & grabberConfig)
_fbGrabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom);
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _fbGrabber, &FramebufferWrapper::setVideoMode);
connect(_fbGrabber, &FramebufferWrapper::systemImage, this, &HyperionDaemon::systemImage);
connect(this, &HyperionDaemon::settingsChanged, _fbGrabber, &FramebufferWrapper::handleSettingsUpdate);
_fbGrabber->start();
@ -482,7 +477,6 @@ void HyperionDaemon::createGrabberOsx(const QJsonObject & grabberConfig)
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _osxGrabber, &OsxWrapper::setVideoMode);
connect(_osxGrabber, &OsxWrapper::systemImage, this, &HyperionDaemon::systemImage);
connect(this, &HyperionDaemon::settingsChanged, _osxGrabber, &OsxWrapper::handleSettingsUpdate);
_osxGrabber->start();

View File

@ -97,16 +97,6 @@ signals:
///
void settingsChanged(const settings::type& type, const QJsonDocument& data);
///
/// @brief PIPE SystemCapture images from SystemCapture over HyperionDaemon to Hyperion class
///
void systemImage(const Image<ColorRgb>& image);
///
/// @brief PIPE v4lCapture images from v4lCapture over HyperionDaemon to Hyperion class
///
void v4lImage(const Image<ColorRgb> & image);
///
/// @brief After eval of setVideoMode this signal emits with a new one on change
///