mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
second part of PR #578
Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com>
This commit is contained in:
@@ -11,8 +11,12 @@
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
|
||||
// HyperionInstanceManager
|
||||
#include <hyperion/HyperionIManager.h>
|
||||
|
||||
class JsonCB;
|
||||
class AuthManager;
|
||||
class HyperionIManager;
|
||||
|
||||
class JsonAPI : public QObject
|
||||
{
|
||||
@@ -68,6 +72,14 @@ private slots:
|
||||
///
|
||||
void handleTokenResponse(const bool& success, QObject* caller, const QString& token, const QString& comment, const QString& id);
|
||||
|
||||
///
|
||||
/// @brief Handle whenever the state of a instance (HyperionIManager) changes according to enum instanceState
|
||||
/// @param instaneState A state from enum
|
||||
/// @param instance The index of instance
|
||||
/// @param name The name of the instance, just available with H_CREATED
|
||||
///
|
||||
void handleInstanceStateChange(const instanceState& state, const quint8& instance, const QString& name = QString());
|
||||
|
||||
signals:
|
||||
///
|
||||
/// Signal emits with the reply message provided with handleMessage()
|
||||
@@ -99,6 +111,9 @@ private:
|
||||
/// Log instance
|
||||
Logger* _log;
|
||||
|
||||
/// Hyperion instance manager
|
||||
HyperionIManager* _instanceManager;
|
||||
|
||||
/// Hyperion instance
|
||||
Hyperion* _hyperion;
|
||||
|
||||
@@ -125,6 +140,14 @@ private:
|
||||
/// timeout for led color refresh
|
||||
volatile qint64 _led_stream_timeout;
|
||||
|
||||
///
|
||||
/// @brief Handle the switches of Hyperion instances
|
||||
/// @param instance the instance to switch
|
||||
/// @param forced indicate if it was a forced switch by system
|
||||
/// @return true on success. false if not found
|
||||
///
|
||||
const bool handleInstanceSwitch(const quint8& instance = 0, const bool& forced = false);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Color message
|
||||
///
|
||||
@@ -181,6 +204,13 @@ private:
|
||||
///
|
||||
void handleClearCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Clearall message
|
||||
///
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleClearallCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Adjustment message
|
||||
///
|
||||
@@ -259,12 +289,11 @@ private:
|
||||
///
|
||||
const bool handleHTTPAuth(const QString& command, const int& tan, const QString& token);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Clearall message
|
||||
/// Handle an incoming JSON instance message
|
||||
///
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleClearallCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
void handleInstanceCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON message of unknown type
|
||||
|
@@ -23,7 +23,7 @@ class JsonCB : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JsonCB(QObject* parent);
|
||||
JsonCB(Hyperion* hyperion, QObject* parent);
|
||||
|
||||
///
|
||||
/// @brief Subscribe to future data updates given by cmd
|
||||
@@ -94,6 +94,11 @@ private slots:
|
||||
///
|
||||
void handleSettingsChange(const settings::type& type, const QJsonDocument& data);
|
||||
|
||||
///
|
||||
/// @brief Handle Hyperion instance manager change
|
||||
///
|
||||
void handleInstanceChange();
|
||||
|
||||
private:
|
||||
/// pointer of Hyperion instance
|
||||
Hyperion* _hyperion;
|
||||
|
@@ -16,13 +16,9 @@ class AuthTable : public DBManager
|
||||
|
||||
public:
|
||||
/// construct wrapper with auth table
|
||||
AuthTable(const QString& rootPath, QObject* parent = nullptr)
|
||||
AuthTable(QObject* parent = nullptr)
|
||||
: DBManager(parent)
|
||||
{
|
||||
// Init Hyperion database usage
|
||||
setRootPath(rootPath);
|
||||
setDB("hyperion");
|
||||
|
||||
// init Auth table
|
||||
setTable("auth");
|
||||
// create table columns
|
||||
|
219
include/db/InstanceTable.h
Normal file
219
include/db/InstanceTable.h
Normal file
@@ -0,0 +1,219 @@
|
||||
#pragma once
|
||||
|
||||
// db
|
||||
#include <db/DBManager.h>
|
||||
#include <db/SettingsTable.h>
|
||||
|
||||
// qt
|
||||
#include <QDateTime>
|
||||
|
||||
///
|
||||
/// @brief Hyperion instance manager specific database interface. prepares also the Hyperion database for all follow up usage (Init QtSqlConnection) along with db name
|
||||
///
|
||||
class InstanceTable : public DBManager
|
||||
{
|
||||
|
||||
public:
|
||||
InstanceTable(const QString& rootPath, QObject* parent = nullptr)
|
||||
: DBManager(parent)
|
||||
{
|
||||
// Init Hyperion database usage
|
||||
setRootPath(rootPath);
|
||||
setDB("hyperion");
|
||||
|
||||
// Init instance table
|
||||
setTable("instances");
|
||||
createTable(QStringList()<<"instance INTEGER"<<"friendly_name TEXT"<<"enabled INTEGER DEFAULT 0"<<"last_use TEXT");
|
||||
|
||||
// create the first Hyperion instance index 0
|
||||
createInstance();
|
||||
|
||||
};
|
||||
~InstanceTable(){};
|
||||
|
||||
///
|
||||
/// @brief Create a new Hyperion instance entry, the name needs to be unique
|
||||
/// @param name The name of the instance
|
||||
/// @param[out] inst The id that has been assigned
|
||||
/// @return True on success else false
|
||||
///
|
||||
inline const bool createInstance(const QString& name, quint8& inst)
|
||||
{
|
||||
VectorPair fcond;
|
||||
fcond.append(CPair("friendly_name",name));
|
||||
|
||||
// check duplicate
|
||||
if(!recordExists(fcond))
|
||||
{
|
||||
inst = 0;
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance",inst));
|
||||
|
||||
// increment to next avail index
|
||||
while(recordExists(cond))
|
||||
{
|
||||
inst++;
|
||||
cond.removeFirst();
|
||||
cond.append(CPair("instance",inst));
|
||||
}
|
||||
// create
|
||||
QVariantMap data;
|
||||
data["friendly_name"] = name;
|
||||
data["instance"] = inst;
|
||||
VectorPair lcond;
|
||||
return createRecord(lcond, data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Delete a Hyperion instance
|
||||
/// @param inst The id that has been assigned
|
||||
/// @return True on success else false
|
||||
///
|
||||
inline const bool deleteInstance(const quint8& inst)
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance",inst));
|
||||
if(deleteRecord(cond))
|
||||
{
|
||||
// delete settings entries
|
||||
SettingsTable settingsTable(inst);
|
||||
settingsTable.deleteInstance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Assign a new name for the given instance
|
||||
/// @param inst The instance index
|
||||
/// @param name The new name of the instance
|
||||
/// @return True on success else false (instance not found)
|
||||
///
|
||||
inline const bool saveName(const quint8& inst, const QString& name)
|
||||
{
|
||||
if(instanceExist(inst))
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance",inst));
|
||||
QVariantMap data;
|
||||
data["friendly_name"] = name;
|
||||
|
||||
return updateRecord(cond, data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief Get all instances with all columns
|
||||
/// @param justEnabled return just enabled instances if true
|
||||
/// @return The found instances
|
||||
///
|
||||
inline QVector<QVariantMap> getAllInstances(const bool& justEnabled = false)
|
||||
{
|
||||
QVector<QVariantMap> results;
|
||||
getRecords(results);
|
||||
if(justEnabled)
|
||||
{
|
||||
for (auto it = results.begin(); it != results.end();)
|
||||
{
|
||||
if( ! (*it)["enabled"].toBool())
|
||||
{
|
||||
it = results.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Test if instance record exists
|
||||
/// @param[in] user The user id
|
||||
/// @return true on success else false
|
||||
///
|
||||
inline const bool instanceExist(const quint8& inst)
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance",inst));
|
||||
return recordExists(cond);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Get instance name by instance index
|
||||
/// @param index The index to search for
|
||||
/// @return The name of this index, may return NOT FOUND if not found
|
||||
///
|
||||
inline const QString getNamebyIndex(const quint8 index)
|
||||
{
|
||||
QVariantMap results;
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance", index));
|
||||
getRecord(cond, results, QStringList("friendly_name"));
|
||||
|
||||
QString name = results["friendly_name"].toString();
|
||||
return name.isEmpty() ? "NOT FOUND" : name;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Update 'last_use' timestamp
|
||||
/// @param inst The instance to update
|
||||
///
|
||||
inline void setLastUse(const quint8& inst)
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance", inst));
|
||||
QVariantMap map;
|
||||
map["last_use"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||||
updateRecord(cond, map);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Update 'enabled' column by instance index
|
||||
/// @param inst The instance to update
|
||||
/// @param newState True when enabled else false
|
||||
///
|
||||
inline void setEnable(const quint8& inst, const bool& newState)
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance", inst));
|
||||
QVariantMap map;
|
||||
map["enabled"] = newState;
|
||||
updateRecord(cond, map);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Get state of 'enabled' column by instance index
|
||||
/// @param inst The instance to get
|
||||
/// @return True when enabled else false
|
||||
///
|
||||
inline const bool isEnabled(const quint8& inst)
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance", inst));
|
||||
QVariantMap results;
|
||||
getRecord(cond, results);
|
||||
|
||||
return results["enabled"].toBool();
|
||||
}
|
||||
|
||||
private:
|
||||
///
|
||||
/// @brief Create first Hyperion instance entry, if index 0 is not found.
|
||||
///
|
||||
inline void createInstance()
|
||||
{
|
||||
QVariantMap data;
|
||||
data["friendly_name"] = "First LED Hardware instance";
|
||||
VectorPair cond;
|
||||
cond.append(CPair("instance", 0));
|
||||
if(createRecord(cond, data))
|
||||
setEnable(0, true);
|
||||
else
|
||||
throw std::runtime_error("Failed to create Hyperion root instance in db! This should never be the case...");
|
||||
}
|
||||
};
|
62
include/db/MetaTable.h
Normal file
62
include/db/MetaTable.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
// hyperion
|
||||
#include <db/DBManager.h>
|
||||
|
||||
// qt
|
||||
#include <QDateTime>
|
||||
#include <QUuid>
|
||||
#include <QNetworkInterface>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
///
|
||||
/// @brief meta table specific database interface
|
||||
///
|
||||
class MetaTable : public DBManager
|
||||
{
|
||||
|
||||
public:
|
||||
/// construct wrapper with plugins table and columns
|
||||
MetaTable(QObject* parent = nullptr)
|
||||
: DBManager(parent)
|
||||
{
|
||||
setTable("meta");
|
||||
createTable(QStringList()<<"uuid TEXT"<<"created_at TEXT");
|
||||
};
|
||||
~MetaTable(){};
|
||||
|
||||
///
|
||||
/// @brief Get the uuid, if the uuid is not set it will be created
|
||||
/// @return The uuid
|
||||
///
|
||||
inline const QString getUUID()
|
||||
{
|
||||
QVector<QVariantMap> results;
|
||||
getRecords(results, QStringList() << "uuid");
|
||||
|
||||
for(const auto & entry : results)
|
||||
{
|
||||
if(!entry["uuid"].toString().isEmpty())
|
||||
return entry["uuid"].toString();
|
||||
}
|
||||
|
||||
// create new uuidv5 based on net adapter MAC, save to db and return
|
||||
QString hash;
|
||||
foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
|
||||
{
|
||||
if (!(interface.flags() & QNetworkInterface::IsLoopBack))
|
||||
{
|
||||
hash = QCryptographicHash::hash(interface.hardwareAddress().toLocal8Bit(),QCryptographicHash::Sha1).toHex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
const QString newUuid = QUuid::createUuidV5(QUuid(), hash).toString().mid(1, 36);
|
||||
VectorPair cond;
|
||||
cond.append(CPair("uuid",newUuid));
|
||||
QVariantMap map;
|
||||
map["created_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||||
createRecord(cond, map);
|
||||
|
||||
return newUuid;
|
||||
}
|
||||
};
|
@@ -95,6 +95,16 @@ public:
|
||||
return results["config"].toString();
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Delete all settings entries associated with this instance, called from InstanceTable of HyperionIManager
|
||||
///
|
||||
inline void deleteInstance() const
|
||||
{
|
||||
VectorPair cond;
|
||||
cond.append(CPair("hyperion_inst",_hyperion_inst));
|
||||
deleteRecord(cond);
|
||||
}
|
||||
|
||||
inline bool isSettingGlobal(const QString& type) const
|
||||
{
|
||||
// list of global settings
|
||||
|
@@ -26,6 +26,9 @@ public slots:
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
void setDeviceVideoStandard(QString device, VideoStandard videoStandard);
|
||||
|
||||
signals:
|
||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||
|
||||
private slots:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
void readError(const char* err);
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <QMap>
|
||||
|
||||
class AuthTable;
|
||||
class MetaTable;
|
||||
class QTimer;
|
||||
|
||||
///
|
||||
@@ -19,7 +20,7 @@ class AuthManager : public QObject
|
||||
private:
|
||||
friend class HyperionDaemon;
|
||||
/// constructor is private, can be called from HyperionDaemon
|
||||
AuthManager(const QString& rootPath, QObject* parent = 0);
|
||||
AuthManager(QObject* parent = 0);
|
||||
|
||||
public:
|
||||
struct AuthDefinition{
|
||||
@@ -31,6 +32,12 @@ public:
|
||||
QString lastUse;
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief Get the unique id (imported from removed class 'Stats')
|
||||
/// @return The unique id
|
||||
///
|
||||
const QString & getID() { return _uuid; };
|
||||
|
||||
///
|
||||
/// @brief Get all available token entries
|
||||
///
|
||||
@@ -40,13 +47,13 @@ public:
|
||||
/// @brief Check authorization is required according to the user setting
|
||||
/// @return True if authorization required else false
|
||||
///
|
||||
const bool & isAuthRequired();
|
||||
bool & isAuthRequired();
|
||||
|
||||
///
|
||||
/// @brief Check if authorization is required for local network connections
|
||||
/// @return True if authorization required else false
|
||||
///
|
||||
const bool & isLocalAuthRequired();
|
||||
bool & isLocalAuthRequired();
|
||||
|
||||
///
|
||||
/// @brief Create a new token and skip the usual chain
|
||||
@@ -61,14 +68,14 @@ public:
|
||||
/// @param pw The password
|
||||
/// @return True if authorized else false
|
||||
///
|
||||
const bool isUserAuthorized(const QString& user, const QString& pw);
|
||||
bool isUserAuthorized(const QString& user, const QString& pw);
|
||||
|
||||
///
|
||||
/// @brief Check if token is authorized
|
||||
/// @param token The token
|
||||
/// @return True if authorized else false
|
||||
///
|
||||
const bool isTokenAuthorized(const QString& token);
|
||||
bool isTokenAuthorized(const QString& token);
|
||||
|
||||
///
|
||||
/// @brief Generate a new pending token request with the provided comment and id as identifier helper
|
||||
@@ -83,14 +90,14 @@ public:
|
||||
/// @param id The id of the request
|
||||
/// @return True on success, false if not found
|
||||
///
|
||||
const bool acceptTokenRequest(const QString& id);
|
||||
bool acceptTokenRequest(const QString& id);
|
||||
|
||||
///
|
||||
/// @brief Deny a token request by id, inform the requester
|
||||
/// @param id The id of the request
|
||||
/// @return True on success, false if not found
|
||||
///
|
||||
const bool denyTokenRequest(const QString& id);
|
||||
bool denyTokenRequest(const QString& id);
|
||||
|
||||
///
|
||||
/// @brief Get pending requests
|
||||
@@ -103,7 +110,7 @@ public:
|
||||
/// @param id The token id
|
||||
/// @return True on success else false (or not found)
|
||||
///
|
||||
const bool deleteToken(const QString& id);
|
||||
bool deleteToken(const QString& id);
|
||||
|
||||
/// Pointer of this instance
|
||||
static AuthManager* manager;
|
||||
@@ -140,6 +147,12 @@ private:
|
||||
/// Database interface for auth table
|
||||
AuthTable* _authTable;
|
||||
|
||||
/// Database interface for meta table
|
||||
MetaTable* _metaTable;
|
||||
|
||||
/// Unique ID (imported from removed class 'Stats')
|
||||
QString _uuid;
|
||||
|
||||
/// All pending requests
|
||||
QMap<QString,AuthDefinition> _pendingRequests;
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <grabber/VideoStandard.h>
|
||||
#include <utils/ImageResampler.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
///
|
||||
/// @brief The Grabber class is responsible to apply image resizes (with or without ImageResampler)
|
||||
@@ -96,6 +97,12 @@ public:
|
||||
///
|
||||
void setEnabled(bool enable);
|
||||
|
||||
signals:
|
||||
///
|
||||
/// @brief PIPE component state changes from HyperionDaemon to V4L2Grabber
|
||||
///
|
||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||
|
||||
protected:
|
||||
ImageResampler _imageResampler;
|
||||
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QMutex>
|
||||
|
||||
// hyperion-utils includes
|
||||
@@ -36,7 +35,6 @@
|
||||
#include <utils/settings.h>
|
||||
|
||||
// Forward class declaration
|
||||
class QTimer;
|
||||
class HyperionDaemon;
|
||||
class ImageProcessor;
|
||||
class MessageForwarder;
|
||||
@@ -71,28 +69,13 @@ public:
|
||||
///
|
||||
/// Destructor; cleans up resources
|
||||
///
|
||||
~Hyperion();
|
||||
virtual ~Hyperion();
|
||||
|
||||
///
|
||||
/// free all alocated objects, should be called only from constructor or before restarting hyperion
|
||||
///
|
||||
void freeObjects(bool emitCloseSignal=false);
|
||||
|
||||
///
|
||||
/// @brief creates a new Hyperion instance, usually called from the Hyperion Daemon
|
||||
/// @param[in] daemon The Hyperion daemon parent
|
||||
/// @param[in] instance The instance id
|
||||
/// @param[in] rootPath Root path of all hyperion userdata
|
||||
/// @return Hyperion instance pointer
|
||||
///
|
||||
static Hyperion* initInstance(HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath);
|
||||
|
||||
///
|
||||
/// @brief Get a pointer of this Hyperion instance
|
||||
/// @return Hyperion instance pointer
|
||||
///
|
||||
static Hyperion* getInstance();
|
||||
|
||||
///
|
||||
/// @brief Get a pointer to the effect engine
|
||||
/// @return EffectEngine instance pointer
|
||||
@@ -122,6 +105,12 @@ public:
|
||||
///
|
||||
bool saveSettings(QJsonObject config, const bool& correct = false);
|
||||
|
||||
///
|
||||
/// @brief Get instance index of this instance
|
||||
/// @return The index of this instance
|
||||
///
|
||||
const quint8 & getInstanceIndex() { return _instIndex; };
|
||||
|
||||
///
|
||||
/// Returns the number of attached leds
|
||||
///
|
||||
@@ -194,14 +183,6 @@ public:
|
||||
/// @return json config
|
||||
const QJsonObject& getQJsonConfig();
|
||||
|
||||
/// get path+filename of configfile
|
||||
/// @return the current config path+filename
|
||||
QString getConfigFilePath() { return _configFile; };
|
||||
|
||||
/// get filename of configfile
|
||||
/// @return the current config filename
|
||||
QString getConfigFileName() const;
|
||||
|
||||
///
|
||||
/// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
|
||||
/// A repeated call to update the base data of a known priority won't overwrite their current timeout
|
||||
@@ -244,21 +225,9 @@ public:
|
||||
|
||||
ComponentRegister& getComponentRegister() { return _componentRegister; };
|
||||
|
||||
bool configModified() { return _configMod; };
|
||||
|
||||
bool configWriteable() { return _configWrite; };
|
||||
|
||||
/// gets the methode how image is maped to leds
|
||||
const int & getLedMappingType();
|
||||
|
||||
/// get the root path for all hyperion user data files
|
||||
const QString &getRootPath() { return _rootPath; };
|
||||
|
||||
/// get unique id per instance
|
||||
const QString &getId(){ return _id; };
|
||||
/// set unique id
|
||||
void setId(QString id){ _id = id; };
|
||||
|
||||
int getLatchTime() const;
|
||||
|
||||
/// forward smoothing config
|
||||
@@ -295,13 +264,6 @@ public slots:
|
||||
///
|
||||
bool setInputImage(const int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1, const bool& clearEffect = true);
|
||||
|
||||
///
|
||||
/// @brief Set the given priority to inactive
|
||||
/// @param priority The priority
|
||||
/// @return True on success false if not found
|
||||
///
|
||||
bool setInputInactive(const quint8& priority);
|
||||
|
||||
///
|
||||
/// Writes a single color to all the leds for the given time and priority
|
||||
/// Registers comp color or provided type against muxer
|
||||
@@ -314,6 +276,13 @@ public slots:
|
||||
///
|
||||
void setColor(int priority, const ColorRgb &ledColor, const int timeout_ms = -1, const QString& origin = "System" ,bool clearEffects = true);
|
||||
|
||||
///
|
||||
/// @brief Set the given priority to inactive
|
||||
/// @param priority The priority
|
||||
/// @return True on success false if not found
|
||||
///
|
||||
bool setInputInactive(const quint8& priority);
|
||||
|
||||
///
|
||||
/// Returns the list with unique adjustment identifiers
|
||||
/// @return The list with adjustment identifiers
|
||||
@@ -372,8 +341,15 @@ public slots:
|
||||
///
|
||||
void setVideoMode(const VideoMode& mode);
|
||||
|
||||
public:
|
||||
static Hyperion *_hyperion;
|
||||
///
|
||||
/// @brief Init after thread start
|
||||
///
|
||||
void start();
|
||||
|
||||
///
|
||||
/// @brief Stop the execution of this thread, helper to properly track eventing
|
||||
///
|
||||
void stop();
|
||||
|
||||
signals:
|
||||
/// Signal which is emitted when a priority channel is actively cleared
|
||||
@@ -453,6 +429,16 @@ signals:
|
||||
///
|
||||
void rawLedColors(const std::vector<ColorRgb>& ledValues);
|
||||
|
||||
///
|
||||
/// @brief Emits before thread quit is requested
|
||||
///
|
||||
void finished();
|
||||
|
||||
///
|
||||
/// @brief Emits after thread has been started
|
||||
///
|
||||
void started();
|
||||
|
||||
private slots:
|
||||
///
|
||||
/// Updates the priority muxer with the current time and (re)writes the led color with applied
|
||||
@@ -460,9 +446,6 @@ private slots:
|
||||
///
|
||||
void update();
|
||||
|
||||
/// check for configWriteable and modified changes, called by _fsWatcher or fallback _cTimer
|
||||
void checkConfigState(QString cfile = NULL);
|
||||
|
||||
///
|
||||
/// @brief Apply ComponentRegister emits for COMP_ALL. Enables/Disables core timers
|
||||
/// @param comp The component
|
||||
@@ -477,17 +460,23 @@ private slots:
|
||||
///
|
||||
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
|
||||
|
||||
///
|
||||
/// @brief Apply new videoMode from Daemon to _currVideoMode
|
||||
///
|
||||
void handleNewVideoMode(const VideoMode& mode) { _currVideoMode = mode; };
|
||||
|
||||
private:
|
||||
friend class HyperionDaemon;
|
||||
friend class HyperionIManager;
|
||||
|
||||
///
|
||||
/// Constructs the Hyperion instance based on the given Json configuration
|
||||
/// @brief Constructs the Hyperion instance, just accessible for HyperionIManager
|
||||
/// @param instance The instance index
|
||||
///
|
||||
/// @param[in] qjsonConfig The Json configuration
|
||||
///
|
||||
Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath);
|
||||
Hyperion(const quint8& instance);
|
||||
|
||||
/// The parent Hyperion Daemon
|
||||
HyperionDaemon* _daemon;
|
||||
/// instance index
|
||||
const quint8 _instIndex;
|
||||
|
||||
/// Settings manager of this instance
|
||||
SettingsManager* _settingsManager;
|
||||
@@ -521,17 +510,8 @@ private:
|
||||
/// Effect engine
|
||||
EffectEngine * _effectEngine;
|
||||
|
||||
// Message forwarder
|
||||
MessageForwarder * _messageForwarder;
|
||||
|
||||
/// the name of config file
|
||||
QString _configFile;
|
||||
|
||||
/// root path for all hyperion user data files
|
||||
QString _rootPath;
|
||||
|
||||
/// unique id per instance
|
||||
QString _id;
|
||||
// // Message forwarder
|
||||
// MessageForwarder * _messageForwarder;
|
||||
|
||||
/// Logger instance
|
||||
Logger * _log;
|
||||
@@ -539,25 +519,11 @@ private:
|
||||
/// count of hardware leds
|
||||
unsigned _hwLedCount;
|
||||
|
||||
QByteArray _configHash;
|
||||
|
||||
QSize _ledGridSize;
|
||||
|
||||
/// Store the previous compID for smarter update()
|
||||
hyperion::Components _prevCompId;
|
||||
|
||||
/// Observe filesystem changes (_configFile), if failed use Timer
|
||||
QFileSystemWatcher _fsWatcher;
|
||||
QTimer* _cTimer;
|
||||
|
||||
/// holds the prev states of configWriteable and modified
|
||||
bool _prevConfigMod = false;
|
||||
bool _prevConfigWrite = true;
|
||||
|
||||
/// holds the current states of configWriteable and modified
|
||||
bool _configMod = false;
|
||||
bool _configWrite = true;
|
||||
|
||||
/// Background effect instance, kept active to react on setting changes
|
||||
BGEffectHandler* _BGEffectHandler;
|
||||
/// Capture control for Daemon native capture
|
||||
@@ -566,6 +532,8 @@ private:
|
||||
/// buffer for leds (with adjustment)
|
||||
std::vector<ColorRgb> _ledBuffer;
|
||||
|
||||
VideoMode _currVideoMode = VIDEO_2D;
|
||||
|
||||
/// Boblight instance
|
||||
BoblightServer* _boblightServer;
|
||||
|
||||
|
177
include/hyperion/HyperionIManager.h
Normal file
177
include/hyperion/HyperionIManager.h
Normal file
@@ -0,0 +1,177 @@
|
||||
#pragma once
|
||||
|
||||
// util
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <utils/settings.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
// qt
|
||||
#include <QMap>
|
||||
|
||||
class Hyperion;
|
||||
class InstanceTable;
|
||||
|
||||
enum instanceState{
|
||||
H_STARTED,
|
||||
H_ON_STOP,
|
||||
H_STOPPED,
|
||||
H_CREATED,
|
||||
H_DELETED
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief HyperionInstanceManager manages the instances of the the Hyperion class
|
||||
///
|
||||
class HyperionIManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// global instance pointer
|
||||
static HyperionIManager* getInstance() { return HIMinstance; };
|
||||
static HyperionIManager* HIMinstance;
|
||||
|
||||
///
|
||||
/// @brief Is given instance running?
|
||||
/// @param inst The instance to check
|
||||
/// @return True when running else false
|
||||
///
|
||||
const bool IsInstanceRunning(const quint8& inst) { return _runningInstances.contains(inst); };
|
||||
|
||||
///
|
||||
/// @brief Get a Hyperion instance by index
|
||||
/// @param intance the index
|
||||
/// @return Hyperion instance, if index is not found returns instance 0
|
||||
///
|
||||
Hyperion* getHyperionInstance(const quint8& instance = 0);
|
||||
|
||||
///
|
||||
/// @brief Get instance data of all instaces in db + running state
|
||||
///
|
||||
const QVector<QVariantMap> getInstanceData();
|
||||
|
||||
///
|
||||
/// @brief Start a Hyperion instance
|
||||
/// @param instance Instance index
|
||||
/// @param block If true return when thread has been started
|
||||
/// @return Return true on success, false if not found in db
|
||||
///
|
||||
const bool startInstance(const quint8& inst, const bool& block = false);
|
||||
|
||||
///
|
||||
/// @brief Stop a Hyperion instance
|
||||
/// @param instance Instance index
|
||||
/// @param block If true return when thread has been started
|
||||
/// @return Return true on success, false if not found in db
|
||||
///
|
||||
const bool stopInstance(const quint8& inst, const bool& block = false);
|
||||
|
||||
///
|
||||
/// @brief Create a new Hyperion instance entry in db
|
||||
/// @param name The friendly name of the instance
|
||||
/// @param start If true it will be started after creation (async)
|
||||
/// @return Return true on success false if name is already in use or a db error occurred
|
||||
///
|
||||
const bool createInstance(const QString& name, const bool& start = false);
|
||||
|
||||
///
|
||||
/// @brief Delete Hyperion instance entry in db. Cleanup also all associated table data for this instance
|
||||
/// @param inst The instance index
|
||||
/// @return Return true on success, false if not found or not allowed
|
||||
///
|
||||
const bool deleteInstance(const quint8& inst);
|
||||
|
||||
///
|
||||
/// @brief Assign a new name to the given instance
|
||||
/// @param inst The instance index
|
||||
/// @param name The instance name index
|
||||
/// @return Return true on success, false if not found
|
||||
///
|
||||
const bool saveName(const quint8& inst, const QString& name);
|
||||
|
||||
signals:
|
||||
///
|
||||
/// @brief Emits whenever the state of a instance changes according to enum instanceState
|
||||
/// @param instaneState A state from enum
|
||||
/// @param instance The index of instance
|
||||
/// @param name The name of the instance, just available with H_CREATED
|
||||
///
|
||||
void instanceStateChanged(const instanceState& state, const quint8& instance, const QString& name = QString());
|
||||
|
||||
///
|
||||
/// @brief Emits whenever something changes, the lazy version of instanceStateChanged (- H_ON_STOP) + saveName() emit
|
||||
///
|
||||
void change();
|
||||
|
||||
signals:
|
||||
///////////////////////////////////////
|
||||
/// FROM HYPERIONDAEMON TO HYPERION ///
|
||||
///////////////////////////////////////
|
||||
|
||||
///
|
||||
/// @brief PIPE videoMode back to Hyperion
|
||||
///
|
||||
void newVideoMode(const VideoMode& mode);
|
||||
|
||||
///////////////////////////////////////
|
||||
/// FROM HYPERION TO HYPERIONDAEMON ///
|
||||
///////////////////////////////////////
|
||||
|
||||
///
|
||||
/// @brief PIPE settings events from Hyperion
|
||||
///
|
||||
void settingsChanged(const settings::type& type, const QJsonDocument& data);
|
||||
|
||||
///
|
||||
/// @brief PIPE videoMode request changes from Hyperion to HyperionDaemon
|
||||
///
|
||||
void requestVideoMode(const VideoMode& mode);
|
||||
|
||||
///
|
||||
/// @brief PIPE component state changes from Hyperion to HyperionDaemon
|
||||
///
|
||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||
|
||||
private slots:
|
||||
///
|
||||
/// @brief handle started signal of Hyperion instances
|
||||
///
|
||||
void handleStarted();
|
||||
|
||||
///
|
||||
/// @brief handle finished signal of Hyperion instances
|
||||
///
|
||||
void handleFinished();
|
||||
|
||||
private:
|
||||
friend class HyperionDaemon;
|
||||
///
|
||||
/// @brief Construct the Manager
|
||||
/// @param The root path of all userdata
|
||||
///
|
||||
HyperionIManager(const QString& rootPath, QObject* parent = nullptr);
|
||||
|
||||
///
|
||||
/// @brief Start all instances that are marked as enabled in db. Non blocking
|
||||
///
|
||||
void startAll();
|
||||
|
||||
///
|
||||
/// @brief Stop all instances, used from hyperiond
|
||||
///
|
||||
void stopAll();
|
||||
|
||||
///
|
||||
/// @brief check if a instance is allowed for management. Instance 0 represents the root instance
|
||||
/// @apram inst The instance to check
|
||||
///
|
||||
const bool isInstAllowed(const quint8& inst) { return (inst > 0); };
|
||||
|
||||
private:
|
||||
Logger* _log;
|
||||
InstanceTable* _instanceTable;
|
||||
const QString _rootPath;
|
||||
QMap<quint8, Hyperion*> _runningInstances;
|
||||
QList<quint8> _startQueue;
|
||||
};
|
@@ -18,11 +18,10 @@ class SettingsManager : public QObject
|
||||
public:
|
||||
///
|
||||
/// @brief Construct a settings manager and assign a hyperion instance
|
||||
/// @params instance Instance number of Hyperion
|
||||
/// @params configFile The config file
|
||||
/// @params hyperion The parent hyperion instance
|
||||
/// @params instance Instance index of HyperionInstanceManager
|
||||
/// @params parent The parent hyperion instance
|
||||
///
|
||||
SettingsManager(const quint8& instance, const QString& configFile, Hyperion* hyperion = nullptr);
|
||||
SettingsManager(const quint8& instance, QObject* parent = nullptr);
|
||||
|
||||
///
|
||||
/// @brief Save a complete json config
|
||||
|
@@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
// qt includes
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QTimer>
|
||||
|
||||
// STL incldues
|
||||
// STL includes
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
// Utility includes
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/ColorRgbw.h>
|
||||
|
@@ -19,6 +19,7 @@
|
||||
class BonjourServiceRegister;
|
||||
class QUdpSocket;
|
||||
class NetOrigin;
|
||||
class Hyperion;
|
||||
|
||||
///
|
||||
/// This class creates a UDP server which accepts connections from boblight clients.
|
||||
@@ -57,7 +58,7 @@ public slots:
|
||||
///
|
||||
void stop();
|
||||
|
||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||
void updatedComponentState(const hyperion::Components component, const bool enable);
|
||||
|
||||
///
|
||||
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
|
||||
|
@@ -55,12 +55,6 @@ QString getDirName( QString sourceFile);
|
||||
///
|
||||
bool removeFile(const QString& path, Logger* log, bool ignError=false);
|
||||
|
||||
///
|
||||
/// @brief Convert a path that may contain special placeholders
|
||||
/// @param[in] path The path to convert
|
||||
///
|
||||
QString convertPath(const QString path);
|
||||
|
||||
///
|
||||
/// @brief resolve the file error and print a message
|
||||
/// @param[in] file The file which caused the error
|
||||
|
Reference in New Issue
Block a user