2019-07-14 22:43:22 +02:00
# include <hyperion/HyperionIManager.h>
// hyperion
# include <hyperion/Hyperion.h>
# include <db/InstanceTable.h>
// qt
# include <QThread>
HyperionIManager * HyperionIManager : : HIMinstance ;
2020-11-01 19:47:30 +01:00
HyperionIManager : : HyperionIManager ( const QString & rootPath , QObject * parent , bool readonlyMode )
2019-07-14 22:43:22 +02:00
: QObject ( parent )
2022-01-22 17:48:03 +01:00
, _log ( Logger : : getInstance ( " HYPERION-INSTMGR " ) )
2020-11-01 19:47:30 +01:00
, _instanceTable ( new InstanceTable ( rootPath , this , readonlyMode ) )
2019-07-14 22:43:22 +02:00
, _rootPath ( rootPath )
2020-11-01 19:47:30 +01:00
, _readonlyMode ( readonlyMode )
2019-07-14 22:43:22 +02:00
{
HIMinstance = this ;
2020-07-12 09:19:59 +02:00
qRegisterMetaType < InstanceState > ( " InstanceState " ) ;
2019-07-14 22:43:22 +02:00
}
2020-08-08 13:09:15 +02:00
Hyperion * HyperionIManager : : getHyperionInstance ( quint8 instance )
2019-07-14 22:43:22 +02:00
{
mDNS Support (#1452)
* Allow build, if no grabbers are enabled
* Align available functions to right Qt version
* Update to next development version
* Align available functions to right Qt version
* fix workflows (apt/nightly)
* Disable QNetworkConfigurationManager deprecation warnings
* Initial go on Smart Pointers
* Add Deallocation
* Correct QT_WARNING_DISABLE_DEPRECATED (available since 5.9)
* Cluster Build Variables
* Hyperion Light
* Address build warnings
* Hyperion Light - UI
* Update Protobuf to latest master
* Removed compiler warnings
* Added restart ability to systray
* Correct Protobuf
* Ignore 'no-return' warning on protobuf build
* hyperion-remote: Fix auto discovery of hyperion server
* Fix Qt version override
* Update changelog
* Remove Grabber Components, if no Grabber exists
* Standalone Grabber - Fix fps default
* Remote Control - Have Source Selction accrosswhole screen
* Enable Blackborder detection only, if relevant input sources available
* Enable Blackborder detection only, if relevant input sources available
* Remote UI - rearrange containers
* Checkout
* Fix compilation on windows
* Re-added qmdnsengine template cmake
* chrono added for linux
* Removed existing AVAHI/Bonjour, allow to enable/disable mDNS
* hyperiond macos typo fix
* Fix macOS Bundle build
* Fix macOS bundle info details
* Correct CMake files
* Removed existing AVAHI/Bonjour (2)
* Share hyperion's services via mDNS
* Add mDNS Browser and mDNS for LED-Devices
* Support mDNS discovery for standalone grabbers
* Remove ZLib Dependency & Cleanup
* mDNS - hanle 2.local2 an ".local." domains equally
* Hue - Link discovery to bridge class, workaround port 443 for mDNS discovery
* Fix save button state when switching between devices
* Removed sessions (of other hyperions)
* mDNS Publisher - Simplify service naming
* mDNS refactoring & Forwarder discovery
* mDNS Updates to use device service name
* Consistency of standalone grabbers with mDNS Service Registry
* Merge branch 'hyperion-project:master' into mDNS
* Start JSON and WebServers only after Instance 0 is available
* Remove bespoke qDebug Output again
* MDNS updates and refactor Forwarder
* Minor updates
* Upgrade to CMake 3.1
* typo
* macOS fix
* Correct merge
* - Remove dynamic linker flag from standalone dispmanX Grabber
- Added ability to use system qmdns libs
* Cec handler library will load at runtime
* typo fix
* protobuf changes
* mDNS changes for Windows/macOS
* test window build qmdnsengine
* absolute path to protobuf cmake dir
* Rework Hue Wizard supporting mDNS
* LED-Devices - Retry support + Refactoring (excl. Hue)
* LED-Devices - Refactoring/Retry support Hue + additional alignments
* Address LGTM findings
* Fix CI-Build, revert test changes
* Build Windows in Release mode to avoid python problem
* Correct that WebServerObject is available earlier
* Ensure that instance name in logs for one instance are presented
* Update content LEDs
* Rework mDNS Address lookup
* Fix LED UI
* Fix for non mDNS Services (ignore default port)
* Disbale device when now input is available
* Revert back some updates, ensure last color is updated when switched on
* Handle reopening case and changed IP, port for API-calls
* Add UPD-DDP Device
* WLED support for DDP
* Fix printout
* LEDDevice - Allow more retries, udapte defaults
* LED-Net Devices - Select Custom device, if configured
Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
2022-05-01 19:42:47 +02:00
Hyperion * pInstance { nullptr } ;
2019-07-14 22:43:22 +02:00
if ( _runningInstances . contains ( instance ) )
return _runningInstances . value ( instance ) ;
mDNS Support (#1452)
* Allow build, if no grabbers are enabled
* Align available functions to right Qt version
* Update to next development version
* Align available functions to right Qt version
* fix workflows (apt/nightly)
* Disable QNetworkConfigurationManager deprecation warnings
* Initial go on Smart Pointers
* Add Deallocation
* Correct QT_WARNING_DISABLE_DEPRECATED (available since 5.9)
* Cluster Build Variables
* Hyperion Light
* Address build warnings
* Hyperion Light - UI
* Update Protobuf to latest master
* Removed compiler warnings
* Added restart ability to systray
* Correct Protobuf
* Ignore 'no-return' warning on protobuf build
* hyperion-remote: Fix auto discovery of hyperion server
* Fix Qt version override
* Update changelog
* Remove Grabber Components, if no Grabber exists
* Standalone Grabber - Fix fps default
* Remote Control - Have Source Selction accrosswhole screen
* Enable Blackborder detection only, if relevant input sources available
* Enable Blackborder detection only, if relevant input sources available
* Remote UI - rearrange containers
* Checkout
* Fix compilation on windows
* Re-added qmdnsengine template cmake
* chrono added for linux
* Removed existing AVAHI/Bonjour, allow to enable/disable mDNS
* hyperiond macos typo fix
* Fix macOS Bundle build
* Fix macOS bundle info details
* Correct CMake files
* Removed existing AVAHI/Bonjour (2)
* Share hyperion's services via mDNS
* Add mDNS Browser and mDNS for LED-Devices
* Support mDNS discovery for standalone grabbers
* Remove ZLib Dependency & Cleanup
* mDNS - hanle 2.local2 an ".local." domains equally
* Hue - Link discovery to bridge class, workaround port 443 for mDNS discovery
* Fix save button state when switching between devices
* Removed sessions (of other hyperions)
* mDNS Publisher - Simplify service naming
* mDNS refactoring & Forwarder discovery
* mDNS Updates to use device service name
* Consistency of standalone grabbers with mDNS Service Registry
* Merge branch 'hyperion-project:master' into mDNS
* Start JSON and WebServers only after Instance 0 is available
* Remove bespoke qDebug Output again
* MDNS updates and refactor Forwarder
* Minor updates
* Upgrade to CMake 3.1
* typo
* macOS fix
* Correct merge
* - Remove dynamic linker flag from standalone dispmanX Grabber
- Added ability to use system qmdns libs
* Cec handler library will load at runtime
* typo fix
* protobuf changes
* mDNS changes for Windows/macOS
* test window build qmdnsengine
* absolute path to protobuf cmake dir
* Rework Hue Wizard supporting mDNS
* LED-Devices - Retry support + Refactoring (excl. Hue)
* LED-Devices - Refactoring/Retry support Hue + additional alignments
* Address LGTM findings
* Fix CI-Build, revert test changes
* Build Windows in Release mode to avoid python problem
* Correct that WebServerObject is available earlier
* Ensure that instance name in logs for one instance are presented
* Update content LEDs
* Rework mDNS Address lookup
* Fix LED UI
* Fix for non mDNS Services (ignore default port)
* Disbale device when now input is available
* Revert back some updates, ensure last color is updated when switched on
* Handle reopening case and changed IP, port for API-calls
* Add UPD-DDP Device
* WLED support for DDP
* Fix printout
* LEDDevice - Allow more retries, udapte defaults
* LED-Net Devices - Select Custom device, if configured
Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
2022-05-01 19:42:47 +02:00
if ( ! _runningInstances . isEmpty ( ) )
{
Warning ( _log , " The requested instance index '%d' with name '%s' isn't running, return main instance " , instance , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
pInstance = _runningInstances . value ( 0 ) ;
}
return pInstance ;
2019-07-14 22:43:22 +02:00
}
2020-08-08 23:12:43 +02:00
QVector < QVariantMap > HyperionIManager : : getInstanceData ( ) const
2019-07-14 22:43:22 +02:00
{
QVector < QVariantMap > instances = _instanceTable - > getAllInstances ( ) ;
for ( auto & entry : instances )
{
// add running state
entry [ " running " ] = _runningInstances . contains ( entry [ " instance " ] . toInt ( ) ) ;
}
return instances ;
}
void HyperionIManager : : startAll ( )
{
2020-08-02 22:35:09 +02:00
for ( const auto & entry : _instanceTable - > getAllInstances ( true ) )
2019-07-14 22:43:22 +02:00
{
startInstance ( entry [ " instance " ] . toInt ( ) ) ;
}
}
void HyperionIManager : : stopAll ( )
{
// copy the instances due to loop corruption, even with .erase() return next iter
QMap < quint8 , Hyperion * > instCopy = _runningInstances ;
for ( const auto instance : instCopy )
{
instance - > stop ( ) ;
}
}
2020-08-08 13:09:15 +02:00
void HyperionIManager : : toggleStateAllInstances ( bool pause )
2020-03-26 19:37:39 +01:00
{
// copy the instances due to loop corruption, even with .erase() return next iter
QMap < quint8 , Hyperion * > instCopy = _runningInstances ;
for ( const auto instance : instCopy )
{
emit instance - > compStateChangeRequest ( hyperion : : COMP_ALL , pause ) ;
}
}
2020-10-18 17:05:07 +02:00
bool HyperionIManager : : startInstance ( quint8 inst , bool block , QObject * caller , int tan )
2019-07-14 22:43:22 +02:00
{
if ( _instanceTable - > instanceExist ( inst ) )
{
if ( ! _runningInstances . contains ( inst ) & & ! _startQueue . contains ( inst ) )
{
QThread * hyperionThread = new QThread ( ) ;
2020-07-19 15:13:41 +02:00
hyperionThread - > setObjectName ( " HyperionThread " ) ;
2020-11-01 19:47:30 +01:00
Hyperion * hyperion = new Hyperion ( inst , _readonlyMode ) ;
2019-07-14 22:43:22 +02:00
hyperion - > moveToThread ( hyperionThread ) ;
// setup thread management
connect ( hyperionThread , & QThread : : started , hyperion , & Hyperion : : start ) ;
2019-07-29 19:09:26 +02:00
connect ( hyperion , & Hyperion : : started , this , & HyperionIManager : : handleStarted ) ;
connect ( hyperion , & Hyperion : : finished , this , & HyperionIManager : : handleFinished ) ;
2019-07-25 18:23:19 +02:00
connect ( hyperion , & Hyperion : : finished , hyperionThread , & QThread : : quit , Qt : : DirectConnection ) ;
2019-07-14 22:43:22 +02:00
// setup further connections
// from Hyperion
2019-07-29 19:09:26 +02:00
connect ( hyperion , & Hyperion : : settingsChanged , this , & HyperionIManager : : settingsChanged ) ;
connect ( hyperion , & Hyperion : : videoMode , this , & HyperionIManager : : requestVideoMode ) ;
2019-07-14 22:43:22 +02:00
// to Hyperion
2019-07-29 19:09:26 +02:00
connect ( this , & HyperionIManager : : newVideoMode , hyperion , & Hyperion : : newVideoMode ) ;
2019-07-14 22:43:22 +02:00
// add to queue and start
_startQueue < < inst ;
hyperionThread - > start ( ) ;
// update db
_instanceTable - > setLastUse ( inst ) ;
_instanceTable - > setEnable ( inst , true ) ;
if ( block )
{
while ( ! hyperionThread - > isRunning ( ) ) { } ;
}
2020-10-18 17:05:07 +02:00
if ( ! _pendingRequests . contains ( inst ) & & caller ! = nullptr )
{
PendingRequests newDef { caller , tan } ;
_pendingRequests [ inst ] = newDef ;
}
2019-07-14 22:43:22 +02:00
return true ;
}
Debug ( _log , " Can't start Hyperion instance index '%d' with name '%s' it's already running or queued for start " , inst , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( inst ) ) ) ;
return false ;
}
Debug ( _log , " Can't start Hyperion instance index '%d' it doesn't exist in DB " , inst ) ;
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : stopInstance ( quint8 inst )
2019-07-14 22:43:22 +02:00
{
// inst 0 can't be stopped
if ( ! isInstAllowed ( inst ) )
return false ;
if ( _instanceTable - > instanceExist ( inst ) )
{
if ( _runningInstances . contains ( inst ) )
{
// notify a ON_STOP rather sooner than later, queued signal listener should have some time to drop the pointer before it's deleted
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_ON_STOP , inst ) ;
2019-07-14 22:43:22 +02:00
Hyperion * hyperion = _runningInstances . value ( inst ) ;
hyperion - > stop ( ) ;
// update db
_instanceTable - > setEnable ( inst , false ) ;
return true ;
}
Debug ( _log , " Can't stop Hyperion instance index '%d' with name '%s' it's not running' " , inst , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( inst ) ) ) ;
return false ;
}
Debug ( _log , " Can't stop Hyperion instance index '%d' it doesn't exist in DB " , inst ) ;
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : createInstance ( const QString & name , bool start )
2019-07-14 22:43:22 +02:00
{
quint8 inst ;
if ( _instanceTable - > createInstance ( name , inst ) )
{
Info ( _log , " New Hyperion instance created with name '%s' " , QSTRING_CSTR ( name ) ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_CREATED , inst , name ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
if ( start )
startInstance ( inst ) ;
return true ;
}
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : deleteInstance ( quint8 inst )
2019-07-14 22:43:22 +02:00
{
// inst 0 can't be deleted
if ( ! isInstAllowed ( inst ) )
return false ;
2019-07-21 19:06:47 +02:00
// stop it if required as blocking and wait
2019-07-29 19:09:26 +02:00
stopInstance ( inst ) ;
2019-07-14 22:43:22 +02:00
if ( _instanceTable - > deleteInstance ( inst ) )
{
Info ( _log , " Hyperion instance with index '%d' has been deleted " , inst ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_DELETED , inst ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
return true ;
}
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : saveName ( quint8 inst , const QString & name )
2019-07-14 22:43:22 +02:00
{
if ( _instanceTable - > saveName ( inst , name ) )
{
emit change ( ) ;
return true ;
}
return false ;
}
void HyperionIManager : : handleFinished ( )
{
Hyperion * hyperion = qobject_cast < Hyperion * > ( sender ( ) ) ;
2020-08-08 13:09:15 +02:00
quint8 instance = hyperion - > getInstanceIndex ( ) ;
2019-07-14 22:43:22 +02:00
Info ( _log , " Hyperion instance '%s' has been stopped " , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
_runningInstances . remove ( instance ) ;
2020-07-12 09:22:05 +02:00
hyperion - > thread ( ) - > deleteLater ( ) ;
2019-07-14 22:43:22 +02:00
hyperion - > deleteLater ( ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_STOPPED , instance ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
}
void HyperionIManager : : handleStarted ( )
{
Hyperion * hyperion = qobject_cast < Hyperion * > ( sender ( ) ) ;
2020-08-08 13:09:15 +02:00
quint8 instance = hyperion - > getInstanceIndex ( ) ;
2019-07-14 22:43:22 +02:00
Info ( _log , " Hyperion instance '%s' has been started " , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
_startQueue . removeAll ( instance ) ;
_runningInstances . insert ( instance , hyperion ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_STARTED , instance ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
2020-10-18 17:05:07 +02:00
if ( _pendingRequests . contains ( instance ) )
{
PendingRequests def = _pendingRequests . take ( instance ) ;
emit startInstanceResponse ( def . caller , def . tan ) ;
_pendingRequests . remove ( instance ) ;
}
2019-07-14 22:43:22 +02:00
}