2013-07-26 22:38:34 +02:00
2013-11-11 10:00:37 +01:00
// STL includes
2016-06-17 01:25:40 +02:00
# include <exception>
2016-07-01 23:20:41 +02:00
# include <sstream>
2017-03-21 17:55:46 +01:00
# include <unistd.h>
2013-11-11 10:00:37 +01:00
2013-08-21 16:25:27 +02:00
// QT includes
2013-08-14 17:02:09 +02:00
# include <QDateTime>
2013-11-29 23:22:49 +01:00
# include <QThread>
2013-11-22 11:48:10 +01:00
# include <QRegExp>
# include <QString>
# include <QStringList>
2016-09-14 13:51:28 +02:00
# include <QCryptographicHash>
2018-12-27 23:11:32 +01:00
# include <QTimer>
2016-09-14 13:51:28 +02:00
# include <QFile>
2016-12-14 22:45:00 +01:00
# include <QFileInfo>
2017-03-21 17:55:46 +01:00
# include <QHostInfo>
2019-06-05 18:19:08 +02:00
# include <QCryptographicHash>
2013-08-14 17:02:09 +02:00
2013-07-26 22:38:34 +02:00
// hyperion include
# include <hyperion/Hyperion.h>
2018-12-27 23:11:32 +01:00
# include <hyperion/MessageForwarder.h>
2016-12-19 23:59:50 +01:00
# include <hyperion/ImageProcessor.h>
2016-04-02 00:04:11 +02:00
# include <hyperion/ColorAdjustment.h>
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
// utils
# include <utils/hyperion.h>
2013-12-17 19:50:15 +01:00
// Leddevice includes
2019-01-01 19:47:07 +01:00
# include <leddevice/LedDeviceWrapper.h>
2013-08-13 11:10:45 +02:00
2018-12-27 23:11:32 +01:00
# include <hyperion/MultiColorAdjustment.h>
2013-10-27 18:04:37 +01:00
# include "LinearColorSmoothing.h"
2013-11-24 16:10:48 +01:00
// effect engine includes
# include <effectengine/EffectEngine.h>
2018-12-27 23:11:32 +01:00
// Hyperion Daemon
# include <../src/hyperiond/hyperiond.h>
// settingsManagaer
# include <hyperion/SettingsManager.h>
// BGEffectHandler
# include <hyperion/BGEffectHandler.h>
// CaptureControl (Daemon capture)
# include <hyperion/CaptureCont.h>
2017-01-10 19:58:41 +01:00
2018-12-28 18:12:45 +01:00
// Boblight
# include <boblightserver/BoblightServer.h>
2016-06-17 01:25:40 +02:00
Hyperion * Hyperion : : _hyperion = nullptr ;
2018-12-27 23:11:32 +01:00
Hyperion * Hyperion : : initInstance ( HyperionDaemon * daemon , const quint8 & instance , const QString configFile , const QString rootPath )
2016-06-17 01:25:40 +02:00
{
if ( Hyperion : : _hyperion ! = nullptr )
throw std : : runtime_error ( " Hyperion::initInstance can be called only one time " ) ;
2018-12-27 23:11:32 +01:00
Hyperion : : _hyperion = new Hyperion ( daemon , instance , configFile , rootPath ) ;
2016-06-17 01:25:40 +02:00
return Hyperion : : _hyperion ;
}
Hyperion * Hyperion : : getInstance ( )
{
if ( Hyperion : : _hyperion = = nullptr )
throw std : : runtime_error ( " Hyperion::getInstance used without call of Hyperion::initInstance before " ) ;
2017-06-24 11:52:22 +02:00
2016-06-17 01:25:40 +02:00
return Hyperion : : _hyperion ;
}
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
Hyperion : : Hyperion ( HyperionDaemon * daemon , const quint8 & instance , const QString configFile , const QString rootPath )
: _daemon ( daemon )
, _settingsManager ( new SettingsManager ( this , instance , configFile ) )
, _componentRegister ( this )
, _ledString ( hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) )
, _ledStringClone ( hyperion : : createLedStringClone ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) )
, _imageProcessor ( new ImageProcessor ( _ledString , this ) )
2016-07-15 23:08:55 +02:00
, _muxer ( _ledString . leds ( ) . size ( ) )
2018-12-27 23:11:32 +01:00
, _raw2ledAdjustment ( hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , getSetting ( settings : : COLOR ) . object ( ) ) )
2016-07-15 23:08:55 +02:00
, _effectEngine ( nullptr )
2019-02-03 14:36:57 +01:00
, _messageForwarder ( new MessageForwarder ( this ) )
2016-07-15 23:08:55 +02:00
, _configFile ( configFile )
2017-10-12 11:55:03 +02:00
, _rootPath ( rootPath )
2018-12-27 23:11:32 +01:00
, _log ( Logger : : getInstance ( " HYPERION " ) )
, _hwLedCount ( )
2016-09-14 13:51:28 +02:00
, _configHash ( )
2018-12-27 23:11:32 +01:00
, _ledGridSize ( hyperion : : getLedLayoutGridSize ( getSetting ( settings : : LEDS ) . array ( ) ) )
2017-02-11 22:52:47 +01:00
, _prevCompId ( hyperion : : COMP_INVALID )
2018-12-27 23:11:32 +01:00
, _ledBuffer ( _ledString . leds ( ) . size ( ) , ColorRgb : : BLACK )
2013-07-26 22:38:34 +02:00
{
2016-04-02 00:04:11 +02:00
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
2018-12-27 23:11:32 +01:00
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
2017-03-21 17:55:46 +01:00
2018-12-27 23:11:32 +01:00
// handle hwLedCount
_hwLedCount = qMax ( unsigned ( getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
2017-06-24 11:52:22 +02:00
2018-12-27 23:11:32 +01:00
// init colororder vector
for ( Led & led : _ledString . leds ( ) )
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
2018-12-31 15:48:29 +01:00
2018-12-27 23:11:32 +01:00
for ( Led & led : _ledStringClone . leds ( ) )
{
_ledStringColorOrder . insert ( _ledStringColorOrder . begin ( ) + led . index , led . colorOrder ) ;
}
2017-06-24 11:52:22 +02:00
2018-12-27 23:11:32 +01:00
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent
connect ( & _muxer , & PriorityMuxer : : visiblePriorityChanged , this , & Hyperion : : update ) ;
2016-09-08 16:32:42 +02:00
2018-12-27 23:11:32 +01:00
// listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions
connect ( & _componentRegister , & ComponentRegister : : updatedComponentState , this , & Hyperion : : updatedComponentState ) ;
2013-10-27 18:04:37 +01:00
2018-12-27 23:11:32 +01:00
// listen for settings updates of this instance (LEDS & COLOR)
connect ( _settingsManager , & SettingsManager : : settingsChanged , this , & Hyperion : : handleSettingsUpdate ) ;
2017-08-04 12:01:45 +02:00
2018-12-27 23:11:32 +01:00
// set color correction activity state
const QJsonObject color = getSetting ( settings : : COLOR ) . object ( ) ;
2013-08-14 17:02:09 +02:00
2018-12-27 23:11:32 +01:00
// initialize leddevices
2018-12-28 18:12:45 +01:00
QJsonObject ledDevice = getSetting ( settings : : DEVICE ) . object ( ) ;
2018-12-27 23:11:32 +01:00
ledDevice [ " currentLedCount " ] = int ( _hwLedCount ) ; // Inject led count info
2017-03-21 17:55:46 +01:00
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper = new LedDeviceWrapper ( this ) ;
connect ( this , & Hyperion : : componentStateChanged , _ledDeviceWrapper , & LedDeviceWrapper : : handleComponentState ) ;
connect ( this , & Hyperion : : ledDeviceData , _ledDeviceWrapper , & LedDeviceWrapper : : write ) ;
_ledDeviceWrapper - > createLedDevice ( ledDevice ) ;
2017-06-24 11:52:22 +02:00
2019-01-01 19:47:07 +01:00
// smoothing
_deviceSmooth = new LinearColorSmoothing ( getSetting ( settings : : SMOOTHING ) , this ) ;
connect ( this , & Hyperion : : settingsChanged , _deviceSmooth , & LinearColorSmoothing : : handleSettingsUpdate ) ;
2018-12-27 23:11:32 +01:00
2019-01-01 19:47:07 +01:00
// create the effect engine; needs to be initialized after smoothing!
2018-12-31 15:48:29 +01:00
_effectEngine = new EffectEngine ( this ) ;
2018-12-27 23:11:32 +01:00
connect ( _effectEngine , & EffectEngine : : effectListUpdated , this , & Hyperion : : effectListUpdated ) ;
2013-11-24 16:10:48 +01:00
2017-07-30 14:36:23 +02:00
// setup config state checks and initial shot
2017-06-17 23:29:04 +02:00
checkConfigState ( ) ;
2017-07-30 14:36:23 +02:00
if ( _fsWatcher . addPath ( _configFile ) )
QObject : : connect ( & _fsWatcher , & QFileSystemWatcher : : fileChanged , this , & Hyperion : : checkConfigState ) ;
else
{
2018-12-27 23:11:32 +01:00
_cTimer = new QTimer ( this ) ;
2017-07-30 14:36:23 +02:00
Warning ( _log , " Filesystem Observer failed for file: %s, use fallback timer " , _configFile . toStdString ( ) . c_str ( ) ) ;
2018-12-27 23:11:32 +01:00
connect ( _cTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( checkConfigState ( ) ) ) ;
_cTimer - > start ( 2000 ) ;
2017-07-30 14:36:23 +02:00
}
2017-06-17 23:29:04 +02:00
2018-12-27 23:11:32 +01:00
// initial startup effect
hyperion : : handleInitialEffect ( this , getSetting ( settings : : FGEFFECT ) . object ( ) ) ;
2019-01-01 19:47:07 +01:00
2018-12-27 23:11:32 +01:00
// handle background effect
_BGEffectHandler = new BGEffectHandler ( this ) ;
2016-09-14 13:51:28 +02:00
2018-12-27 23:11:32 +01:00
// create the Daemon capture interface
_captureCont = new CaptureCont ( this ) ;
2017-06-24 11:52:22 +02:00
2018-12-27 23:11:32 +01:00
// if there is no startup / background eff and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a prioritiy change)
2013-08-18 13:33:56 +02:00
update ( ) ;
2018-12-28 18:12:45 +01:00
// 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 ) ;
2019-06-05 18:19:08 +02:00
// set unique id
_id = QString ( QCryptographicHash : : hash ( getConfigFileName ( ) . toLocal8Bit ( ) , QCryptographicHash : : Sha1 ) . toHex ( ) ) ;
2013-07-26 22:38:34 +02:00
}
2018-12-27 23:11:32 +01:00
Hyperion : : ~ Hyperion ( )
2017-08-04 12:01:45 +02:00
{
2018-12-27 23:11:32 +01:00
freeObjects ( false ) ;
2017-08-04 12:01:45 +02:00
}
2017-01-22 19:36:52 +01:00
void Hyperion : : freeObjects ( bool emitCloseSignal )
2013-07-26 22:38:34 +02:00
{
2017-08-12 07:55:32 +02:00
// switch off all leds
clearall ( true ) ;
2017-01-22 19:36:52 +01:00
if ( emitCloseSignal )
{
emit closing ( ) ;
}
2017-01-22 14:31:11 +01:00
2016-07-01 23:20:41 +02:00
// delete components on exit of hyperion core
2018-12-28 18:12:45 +01:00
delete _boblightServer ;
2018-12-27 23:11:32 +01:00
delete _captureCont ;
2013-11-24 16:10:48 +01:00
delete _effectEngine ;
2018-12-27 23:11:32 +01:00
//delete _deviceSmooth;
2016-04-02 00:04:11 +02:00
delete _raw2ledAdjustment ;
2016-03-09 19:45:00 +01:00
delete _messageForwarder ;
2018-12-27 23:11:32 +01:00
delete _settingsManager ;
2019-01-01 19:47:07 +01:00
delete _ledDeviceWrapper ;
2013-07-26 22:38:34 +02:00
}
2018-12-27 23:11:32 +01:00
void Hyperion : : handleSettingsUpdate ( const settings : : type & type , const QJsonDocument & config )
2016-10-10 23:08:01 +02:00
{
2018-12-27 23:11:32 +01:00
if ( type = = settings : : COLOR )
{
const QJsonObject obj = config . object ( ) ;
// change in color recreate ledAdjustments
delete _raw2ledAdjustment ;
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , obj ) ;
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
{
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
}
}
else if ( type = = settings : : LEDS )
{
const QJsonArray leds = config . array ( ) ;
// lock update()
_lockUpdate = true ;
// stop and cache all running effects, as effects depend heavily on ledlayout
_effectEngine - > cacheRunningEffects ( ) ;
// ledstring, clone, img processor, muxer, ledGridSize (eff engine image based effects), _ledBuffer and ByteOrder of ledstring
_ledString = hyperion : : createLedString ( leds , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) ;
_ledStringClone = hyperion : : createLedStringClone ( leds , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
_muxer . updateLedColorsLength ( _ledString . leds ( ) . size ( ) ) ;
_ledGridSize = hyperion : : getLedLayoutGridSize ( leds ) ;
std : : vector < ColorRgb > color ( _ledString . leds ( ) . size ( ) , ColorRgb { 0 , 0 , 0 } ) ;
_ledBuffer = color ;
_ledStringColorOrder . clear ( ) ;
for ( Led & led : _ledString . leds ( ) )
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
for ( Led & led : _ledStringClone . leds ( ) )
{
_ledStringColorOrder . insert ( _ledStringColorOrder . begin ( ) + led . index , led . colorOrder ) ;
}
// handle hwLedCount update
_hwLedCount = qMax ( unsigned ( getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
// update led count in device
2019-01-01 19:47:07 +01:00
//_ledDeviceWrapper->setLedCount(_hwLedCount);
2018-12-27 23:11:32 +01:00
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment ;
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , getSetting ( settings : : COLOR ) . object ( ) ) ;
// start cached effects
_effectEngine - > startCachedEffects ( ) ;
// unlock
_lockUpdate = false ;
}
else if ( type = = settings : : DEVICE )
{
_lockUpdate = true ;
2018-12-28 18:12:45 +01:00
QJsonObject dev = config . object ( ) ;
2018-12-27 23:11:32 +01:00
// handle hwLedCount update
_hwLedCount = qMax ( unsigned ( dev [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
// force ledString update, if device ByteOrder changed
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > getColorOrder ( ) ! = dev [ " colorOrder " ] . toString ( " rgb " ) )
2018-12-27 23:11:32 +01:00
{
_ledString = hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( dev ) ) ;
_ledStringClone = hyperion : : createLedStringClone ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( dev ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
}
/* // reinit led device type on change
if ( _device - > getActiveDevice ( ) ! = dev [ " type " ] . toString ( " file " ) . toLower ( ) )
{
}
// update led count
_device - > setLedCount ( _hwLedCount ) ;
*/
2019-01-01 19:47:07 +01:00
// do always reinit until the led devices can handle dynamic changes
2018-12-27 23:11:32 +01:00
dev [ " currentLedCount " ] = int ( _hwLedCount ) ; // Inject led count info
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper - > createLedDevice ( dev ) ;
2018-12-27 23:11:32 +01:00
_lockUpdate = false ;
}
2018-12-28 18:12:45 +01:00
// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
2018-12-27 23:11:32 +01:00
update ( ) ;
2016-10-10 23:08:01 +02:00
}
2018-12-27 23:11:32 +01:00
QJsonDocument Hyperion : : getSetting ( const settings : : type & type )
2013-08-14 10:54:49 +02:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > getSetting ( type ) ;
2013-08-14 10:54:49 +02:00
}
2018-12-27 23:11:32 +01:00
bool Hyperion : : saveSettings ( QJsonObject config , const bool & correct )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > saveSettings ( config , correct ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
QString Hyperion : : getConfigFileName ( ) const
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
QFileInfo cF ( _configFile ) ;
return cF . fileName ( ) ;
}
2017-06-17 23:29:04 +02:00
2018-12-27 23:11:32 +01:00
int Hyperion : : getLatchTime ( ) const
{
2019-01-01 19:47:07 +01:00
return _ledDeviceWrapper - > getLatchTime ( ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
unsigned Hyperion : : addSmoothingConfig ( int settlingTime_ms , double ledUpdateFrequency_hz , unsigned updateDelay )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _deviceSmooth - > addConfig ( settlingTime_ms , ledUpdateFrequency_hz , updateDelay ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
unsigned Hyperion : : getLedCount ( ) const
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _ledString . leds ( ) . size ( ) ;
2017-03-21 17:55:46 +01:00
}
2016-09-14 13:51:28 +02:00
2017-07-30 14:36:23 +02:00
void Hyperion : : checkConfigState ( QString cfile )
2016-09-14 13:51:28 +02:00
{
2017-06-24 11:52:22 +02:00
// Check config modifications
2016-12-14 22:45:00 +01:00
QFile f ( _configFile ) ;
2016-09-14 13:51:28 +02:00
if ( f . open ( QFile : : ReadOnly ) )
{
QCryptographicHash hash ( QCryptographicHash : : Sha1 ) ;
2016-09-15 20:42:58 +02:00
if ( hash . addData ( & f ) )
{
if ( _configHash . size ( ) = = 0 )
2016-09-14 13:51:28 +02:00
{
2016-09-15 20:42:58 +02:00
_configHash = hash . result ( ) ;
2016-09-14 13:51:28 +02:00
}
2017-06-17 23:29:04 +02:00
_configMod = _configHash ! = hash . result ( ) ? true : false ;
2016-09-15 20:42:58 +02:00
}
2016-09-14 13:51:28 +02:00
}
f . close ( ) ;
2017-06-17 23:29:04 +02:00
if ( _prevConfigMod ! = _configMod )
{
_prevConfigMod = _configMod ;
}
2016-09-14 13:51:28 +02:00
2017-06-17 23:29:04 +02:00
// Check config writeable
2016-12-14 22:45:00 +01:00
QFile file ( _configFile ) ;
QFileInfo fileInfo ( file ) ;
2017-06-17 23:29:04 +02:00
_configWrite = fileInfo . isWritable ( ) & & fileInfo . isReadable ( ) ? true : false ;
2017-06-24 11:52:22 +02:00
2017-06-17 23:29:04 +02:00
if ( _prevConfigWrite ! = _configWrite )
2017-06-24 11:52:22 +02:00
{
2017-06-17 23:29:04 +02:00
_prevConfigWrite = _configWrite ;
}
2016-12-14 22:45:00 +01:00
}
2016-07-31 22:21:35 +02:00
void Hyperion : : setSourceAutoSelectEnabled ( bool enabled )
{
2018-12-27 23:11:32 +01:00
if ( _muxer . setSourceAutoSelectEnabled ( enabled ) )
update ( ) ;
2016-07-31 22:21:35 +02:00
}
bool Hyperion : : setCurrentSourcePriority ( int priority )
{
2018-12-27 23:11:32 +01:00
return _muxer . setPriority ( priority ) ;
}
2016-07-31 22:21:35 +02:00
2018-12-27 23:11:32 +01:00
bool Hyperion : : sourceAutoSelectEnabled ( )
{
return _muxer . isSourceAutoSelectEnabled ( ) ;
2016-07-31 22:21:35 +02:00
}
2019-01-01 19:47:07 +01:00
void Hyperion : : setNewComponentState ( const hyperion : : Components & component , const bool & state )
2016-08-04 13:10:53 +02:00
{
2019-01-01 19:47:07 +01:00
_componentRegister . componentStateChanged ( component , state ) ;
}
2017-03-21 17:55:46 +01:00
2019-01-01 19:47:07 +01:00
void Hyperion : : setComponentState ( const hyperion : : Components component , const bool state )
{
emit componentStateChanged ( component , state ) ;
2016-08-04 13:10:53 +02:00
}
2016-07-15 23:08:55 +02:00
2018-12-27 23:11:32 +01:00
void Hyperion : : registerInput ( const int priority , const hyperion : : Components & component , const QString & origin , const QString & owner , unsigned smooth_cfg )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
_muxer . registerInput ( priority , component , origin , owner , smooth_cfg ) ;
2013-08-18 13:33:56 +02:00
}
2013-07-26 22:38:34 +02:00
2019-06-05 18:19:08 +02:00
bool Hyperion : : setInput ( const int priority , const std : : vector < ColorRgb > & ledColors , int timeout_ms , const bool & clearEffect )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
if ( _muxer . setInput ( priority , ledColors , timeout_ms ) )
2013-12-08 17:45:26 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
_effectEngine - > channelCleared ( priority ) ;
2013-12-08 17:45:26 +01:00
2018-12-27 23:11:32 +01:00
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
update ( ) ;
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
return true ;
2013-08-14 17:02:09 +02:00
}
2018-12-27 23:11:32 +01:00
return false ;
2013-08-14 17:02:09 +02:00
}
2019-06-05 18:19:08 +02:00
bool Hyperion : : setInputImage ( const int priority , const Image < ColorRgb > & image , int64_t timeout_ms , const bool & clearEffect )
2016-12-18 19:00:14 +01:00
{
2018-12-27 23:11:32 +01:00
if ( _muxer . setInputImage ( priority , image , timeout_ms ) )
2016-12-18 19:00:14 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
_effectEngine - > channelCleared ( priority ) ;
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
update ( ) ;
return true ;
2016-12-18 19:00:14 +01:00
}
2018-12-27 23:11:32 +01:00
return false ;
}
2019-06-05 18:19:08 +02:00
bool Hyperion : : setInputInactive ( const quint8 & priority )
2018-12-28 18:12:45 +01:00
{
return _muxer . setInputInactive ( priority ) ;
}
2018-12-27 23:11:32 +01:00
void Hyperion : : setColor ( int priority , const ColorRgb & color , const int timeout_ms , const QString & origin , bool clearEffects )
{
// clear effect if this call does not come from an effect
if ( clearEffects )
_effectEngine - > channelCleared ( priority ) ;
// create led vector from single color
std : : vector < ColorRgb > ledColors ( _ledString . leds ( ) . size ( ) , color ) ;
// register color
registerInput ( priority , hyperion : : COMP_COLOR , origin ) ;
// write color to muxer
setInput ( priority , ledColors , timeout_ms ) ;
2016-12-18 19:00:14 +01:00
}
2017-03-04 22:17:42 +01:00
const QStringList & Hyperion : : getAdjustmentIds ( ) const
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustmentIds ( ) ;
}
2017-03-04 22:17:42 +01:00
ColorAdjustment * Hyperion : : getAdjustment ( const QString & id )
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustment ( id ) ;
}
void Hyperion : : adjustmentsUpdated ( )
{
2018-12-27 23:11:32 +01:00
emit adjustmentChanged ( ) ;
2016-04-02 00:04:11 +02:00
update ( ) ;
}
2019-06-05 18:19:08 +02:00
bool Hyperion : : clear ( int priority )
2013-08-18 13:33:56 +02:00
{
2013-11-29 23:22:49 +01:00
// 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 ) ;
2018-12-27 23:11:32 +01:00
if ( _muxer . clearInput ( priority ) )
return true ;
return false ;
2013-08-18 13:33:56 +02:00
}
2017-08-12 07:55:32 +02:00
void Hyperion : : clearall ( bool forceClearAll )
2013-08-18 13:33:56 +02:00
{
2017-08-12 07:55:32 +02:00
_muxer . clearAll ( forceClearAll ) ;
2013-11-24 16:10:48 +01:00
// send clearall signal to the effect engine
_effectEngine - > allChannelsCleared ( ) ;
2013-08-18 13:33:56 +02:00
}
2016-05-30 22:39:12 +02:00
int Hyperion : : getCurrentPriority ( ) const
{
2018-12-27 23:11:32 +01:00
return _muxer . getCurrentPriority ( ) ;
2016-05-30 22:39:12 +02:00
}
2017-09-01 08:50:37 +02:00
bool Hyperion : : isCurrentPriority ( const int priority ) const
{
return getCurrentPriority ( ) = = priority ;
}
2013-08-19 20:33:36 +02:00
QList < int > Hyperion : : getActivePriorities ( ) const
{
return _muxer . getPriorities ( ) ;
}
2018-12-27 23:11:32 +01:00
const Hyperion : : InputInfo Hyperion : : getPriorityInfo ( const int priority ) const
2013-08-19 20:33:36 +02:00
{
return _muxer . getInputInfo ( priority ) ;
}
2019-06-05 18:19:08 +02:00
bool Hyperion : : saveEffect ( const QJsonObject & obj , QString & resultMsg )
2018-12-31 15:48:29 +01:00
{
return _effectEngine - > saveEffect ( obj , resultMsg ) ;
}
2019-06-05 18:19:08 +02:00
bool Hyperion : : deleteEffect ( const QString & effectName , QString & resultMsg )
2016-11-20 18:41:10 +01:00
{
2018-12-31 15:48:29 +01:00
return _effectEngine - > deleteEffect ( effectName , resultMsg ) ;
2016-11-20 18:41:10 +01:00
}
2013-12-01 14:09:01 +01:00
const std : : list < EffectDefinition > & Hyperion : : getEffects ( ) const
2013-11-24 16:10:48 +01:00
{
return _effectEngine - > getEffects ( ) ;
}
2016-04-24 17:07:31 +02:00
const std : : list < ActiveEffectDefinition > & Hyperion : : getActiveEffects ( )
{
return _effectEngine - > getActiveEffects ( ) ;
}
2016-10-24 23:52:53 +02:00
const std : : list < EffectSchema > & Hyperion : : getEffectSchemas ( )
{
return _effectEngine - > getEffectSchemas ( ) ;
}
2018-12-27 23:11:32 +01:00
const QJsonObject & Hyperion : : getQJsonConfig ( )
{
return _settingsManager - > getSettings ( ) ;
}
2017-03-01 15:23:53 +01:00
int Hyperion : : setEffect ( const QString & effectName , int priority , int timeout , const QString & origin )
2013-11-24 16:10:48 +01:00
{
2017-03-01 15:23:53 +01:00
return _effectEngine - > runEffect ( effectName , priority , timeout , origin ) ;
2013-11-24 16:10:48 +01:00
}
2019-01-06 19:49:56 +01:00
int Hyperion : : setEffect ( const QString & effectName , const QJsonObject & args , int priority , int timeout , const QString & pythonScript , const QString & origin , const QString & imageData )
2013-12-01 14:09:01 +01:00
{
2019-01-06 19:49:56 +01:00
return _effectEngine - > runEffect ( effectName , args , priority , timeout , pythonScript , origin , 0 , imageData ) ;
2013-12-01 14:09:01 +01:00
}
2018-12-27 23:11:32 +01:00
void Hyperion : : setLedMappingType ( const int & mappingType )
{
if ( mappingType ! = _imageProcessor - > getUserLedMappingType ( ) )
{
_imageProcessor - > setLedMappingType ( mappingType ) ;
emit imageToLedsMappingChanged ( mappingType ) ;
}
}
const int & Hyperion : : getLedMappingType ( )
2016-12-19 23:59:50 +01:00
{
2018-12-27 23:11:32 +01:00
return _imageProcessor - > getUserLedMappingType ( ) ;
2016-12-19 23:59:50 +01:00
}
2018-12-27 23:11:32 +01:00
void Hyperion : : setVideoMode ( const VideoMode & mode )
2017-08-04 23:08:15 +02:00
{
emit videoMode ( mode ) ;
}
2018-12-27 23:11:32 +01:00
const VideoMode & Hyperion : : getCurrentVideoMode ( )
{
return _daemon - > getVideoMode ( ) ;
}
2017-08-04 23:08:15 +02:00
2018-12-27 23:11:32 +01:00
const QString & Hyperion : : getActiveDevice ( )
2017-06-24 11:52:22 +02:00
{
2019-01-01 19:47:07 +01:00
return _ledDeviceWrapper - > getActiveDevice ( ) ;
2018-12-27 23:11:32 +01:00
}
void Hyperion : : updatedComponentState ( const hyperion : : Components comp , const bool state )
{
if ( comp = = hyperion : : COMP_ALL )
2017-06-24 11:52:22 +02:00
{
2018-12-27 23:11:32 +01:00
if ( state )
{
// first muxer to update all inputs
_muxer . setEnable ( state ) ;
}
else
{
_muxer . setEnable ( state ) ;
}
2017-06-24 11:52:22 +02:00
}
}
2013-08-14 17:02:09 +02:00
void Hyperion : : update ( )
{
2018-12-27 23:11:32 +01:00
if ( _lockUpdate )
return ;
2013-08-14 17:02:09 +02:00
2018-12-27 23:11:32 +01:00
// the ledbuffer resize for hwledcount needs to be reverted
if ( _hwLedCount > _ledBuffer . size ( ) )
_ledBuffer . resize ( getLedCount ( ) ) ;
2016-07-01 23:20:41 +02:00
2018-12-27 23:11:32 +01:00
// Obtain the current priority channel
int priority = _muxer . getCurrentPriority ( ) ;
const PriorityMuxer : : InputInfo priorityInfo = _muxer . getInputInfo ( priority ) ;
2018-12-20 15:12:45 +01:00
2018-12-27 23:11:32 +01:00
// eval comp change
bool compChanged = false ;
2017-03-24 10:17:36 +01:00
if ( priorityInfo . componentId ! = _prevCompId )
2016-10-10 18:29:54 +02:00
{
2018-12-27 23:11:32 +01:00
compChanged = true ;
2017-03-24 10:17:36 +01:00
_prevCompId = priorityInfo . componentId ;
2016-10-10 18:29:54 +02:00
}
2016-07-01 23:20:41 +02:00
2018-12-27 23:11:32 +01:00
// copy image & process OR copy ledColors from muxer
Image < ColorRgb > image = priorityInfo . image ;
if ( image . size ( ) > 3 )
2016-08-08 00:17:00 +02:00
{
2018-12-27 23:11:32 +01:00
emit currentImage ( image ) ;
// disable the black border detector for effects and ledmapping to 0
if ( compChanged )
2016-08-08 00:17:00 +02:00
{
2018-12-28 18:12:45 +01:00
_imageProcessor - > setBlackbarDetectDisable ( ( _prevCompId = = hyperion : : COMP_EFFECT ) ) ;
2018-12-27 23:11:32 +01:00
_imageProcessor - > setHardLedMappingType ( ( _prevCompId = = hyperion : : COMP_EFFECT ) ? 0 : - 1 ) ;
2016-08-08 00:17:00 +02:00
}
2018-12-27 23:11:32 +01:00
_imageProcessor - > process ( image , _ledBuffer ) ;
2016-08-08 00:17:00 +02:00
}
2018-12-27 23:11:32 +01:00
else
{
_ledBuffer = priorityInfo . ledColors ;
}
2018-12-31 15:48:29 +01:00
// emit rawLedColors before transform
emit rawLedColors ( _ledBuffer ) ;
2018-12-27 23:11:32 +01:00
// apply adjustments
if ( compChanged )
_raw2ledAdjustment - > setBacklightEnabled ( ( _prevCompId ! = hyperion : : COMP_COLOR & & _prevCompId ! = hyperion : : COMP_EFFECT ) ) ;
2018-12-31 15:48:29 +01:00
2018-12-27 23:11:32 +01:00
_raw2ledAdjustment - > applyAdjustment ( _ledBuffer ) ;
2017-06-24 11:52:22 +02:00
2016-08-08 00:17:00 +02:00
// insert cloned leds into buffer
for ( Led & led : _ledStringClone . leds ( ) )
{
_ledBuffer . insert ( _ledBuffer . begin ( ) + led . index , _ledBuffer . at ( led . clone ) ) ;
}
2017-06-24 11:52:22 +02:00
2015-01-01 19:31:04 +01:00
int i = 0 ;
2016-07-01 23:20:41 +02:00
for ( ColorRgb & color : _ledBuffer )
2013-08-21 21:50:17 +02:00
{
2013-11-04 20:52:57 +01:00
// correct the color byte order
2016-08-08 00:17:00 +02:00
switch ( _ledStringColorOrder . at ( i ) )
2013-10-27 10:18:31 +01:00
{
2013-11-04 20:52:57 +01:00
case ORDER_RGB :
// leave as it is
break ;
case ORDER_BGR :
2013-10-27 10:18:31 +01:00
std : : swap ( color . red , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
case ORDER_RBG :
std : : swap ( color . green , color . blue ) ;
break ;
case ORDER_GRB :
std : : swap ( color . red , color . green ) ;
break ;
case ORDER_GBR :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . green ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
2017-01-10 19:58:41 +01:00
2013-11-04 20:52:57 +01:00
case ORDER_BRG :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . blue ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
}
2015-01-01 19:31:04 +01:00
i + + ;
2013-08-21 21:50:17 +02:00
}
2018-12-27 23:11:32 +01:00
// fill aditional hw leds with black
2016-07-01 23:20:41 +02:00
if ( _hwLedCount > _ledBuffer . size ( ) )
{
_ledBuffer . resize ( _hwLedCount , ColorRgb : : BLACK ) ;
}
2017-06-24 11:52:22 +02:00
2013-08-14 17:02:09 +02:00
// Write the data to the device
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > enabled ( ) )
2017-03-21 17:55:46 +01:00
{
2017-08-04 12:01:45 +02:00
_deviceSmooth - > selectConfig ( priorityInfo . smooth_cfg ) ;
2017-03-30 06:20:20 +02:00
// feed smoothing in pause mode to maintain a smooth transistion back to smoth mode
if ( _deviceSmooth - > enabled ( ) | | _deviceSmooth - > pause ( ) )
2017-03-21 17:55:46 +01:00
_deviceSmooth - > setLedValues ( _ledBuffer ) ;
2017-06-24 11:52:22 +02:00
2017-03-30 06:20:20 +02:00
if ( ! _deviceSmooth - > enabled ( ) )
2019-01-01 19:47:07 +01:00
emit ledDeviceData ( _ledBuffer ) ;
2017-03-21 17:55:46 +01:00
}
2013-07-26 22:38:34 +02:00
}