mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Troubleshooting and ...
- More i18n - Easy use of mutual exclusion in JsonAPI with QMutexLocker - Smoothing type "linear" hidden in the WebUI, because there is currently only one - Message forwarding implemented again - For compatibility to home assistants and other remote controls, "activeEffects" and "activeLedColor" has been added to the JSON-RPC - FlatBuffer clear now the Priority on disconnect - The information "available V4L2 devices" is now only displayed if the device list is not empty - LED device "PiBlaster" excluded from OSX build
This commit is contained in:
		| @@ -565,12 +565,14 @@ | ||||
| 	"edt_conf_fw_proto_itemtitle" : "Proto Ziel", | ||||
| 	"edt_conf_js_heading_title" : "JSON Server", | ||||
| 	"edt_conf_fbs_heading_title" : "Flatbuffers Server", | ||||
| 	"edt_conf_fbs_timeout_title" : "Zeitüberschreitung", | ||||
| 	"edt_conf_fbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert", | ||||
| 	"edt_conf_bobls_heading_title" : "Boblight Server", | ||||
| 	"edt_conf_udpl_heading_title" : "UDP Listener", | ||||
| 	"edt_conf_udpl_address_title" : "Adresse", | ||||
| 	"edt_conf_udpl_address_expl" : "Die Adresse auf der UDP Pakete akzeptiert werden.", | ||||
| 	"edt_conf_udpl_timeout_title" : "Zeitüberschreitung", | ||||
| 	"edt_conf_udpl_timeout_expl" : "Wenn für die angegeben Zeit keine UDP Pakete empfangen werden, wird die Komponente (vorübergehend) deaktiviert", | ||||
| 	"edt_conf_udpl_timeout_expl" : "Wenn für die angegebene Zeit keine UDP Pakete empfangen werden, wird die Komponente (vorübergehend) deaktiviert", | ||||
| 	"edt_conf_udpl_shared_title" : "Gemeinsam genutzt", | ||||
| 	"edt_conf_udpl_shared_expl" : "Wird gemeinsam über alle Hyperion Instanzen genutzt.", | ||||
| 	"edt_conf_webc_heading_title" : "Web Konfiguration", | ||||
|   | ||||
| @@ -566,6 +566,8 @@ | ||||
| 	"edt_conf_fw_proto_itemtitle" : "Proto target", | ||||
| 	"edt_conf_js_heading_title" : "JSON Server", | ||||
| 	"edt_conf_fbs_heading_title" : "Flatbuffers Server", | ||||
| 	"edt_conf_fbs_timeout_title" : "Timeout", | ||||
| 	"edt_conf_fbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.", | ||||
| 	"edt_conf_bobls_heading_title" : "Boblight Server", | ||||
| 	"edt_conf_udpl_heading_title" : "UDP Listener", | ||||
| 	"edt_conf_udpl_address_title" : "Address", | ||||
|   | ||||
| @@ -50,7 +50,6 @@ $(document).ready( function() { | ||||
|  | ||||
| 		fileReader.onload = function () { | ||||
| 			imageData = this.result.split(',')[1]; | ||||
| 			console.log(imageData); | ||||
| 			cbs.success(file.name); | ||||
| 		}; | ||||
|  | ||||
|   | ||||
| @@ -587,6 +587,9 @@ function createHelpTable(list, phead){ | ||||
| 	{ | ||||
| 		if(list[key].access != 'system') | ||||
| 		{ | ||||
| 			// break one iteration (in the loop), if the schema has the entry hidden=true | ||||
| 			if ("options" in list[key] && "hidden" in list[key].options && (list[key].options.hidden)) | ||||
| 				continue; | ||||
| 			var text = list[key].title.replace('title', 'expl'); | ||||
| 			tbody.appendChild(createTableRow([$.i18n(list[key].title), $.i18n(text)], false, false)); | ||||
|  | ||||
| @@ -595,7 +598,9 @@ function createHelpTable(list, phead){ | ||||
| 				var ilist = sortProperties(list[key].items.properties); | ||||
| 				for (ikey in ilist) | ||||
| 				{ | ||||
|  | ||||
| 					// break one iteration (in the loop), if the schema has the entry hidden=true | ||||
| 					if ("options" in ilist[ikey] && "hidden" in ilist[ikey].options && (ilist[ikey].options.hidden)) | ||||
| 						continue; | ||||
| 					var itext = ilist[ikey].title.replace('title', 'expl'); | ||||
| 					tbody.appendChild(createTableRow([$.i18n(ilist[ikey].title), $.i18n(itext)], false, false)); | ||||
| 				} | ||||
|   | ||||
| @@ -326,12 +326,6 @@ public slots: | ||||
| 	/// | ||||
| 	ColorAdjustment * getAdjustment(const QString& id); | ||||
|  | ||||
| 	/// | ||||
| 	/// Returns  MessageForwarder Object | ||||
| 	/// @return instance of message forwarder object | ||||
| 	/// | ||||
| 	MessageForwarder * getForwarder(); | ||||
|  | ||||
| 	/// Tell Hyperion that the corrections have changed and the leds need to be updated | ||||
| 	void adjustmentsUpdated(); | ||||
|  | ||||
| @@ -345,7 +339,7 @@ public slots: | ||||
| 	const bool clear(int priority); | ||||
|  | ||||
| 	/// | ||||
| 	/// Clears all priority channels. This will switch the leds off until a new priority is written. | ||||
| 	/// @brief Clears all priority channels. This will switch the leds off until a new priority is written. | ||||
| 	/// | ||||
| 	void clearall(bool forceClearAll=false); | ||||
|  | ||||
| @@ -416,6 +410,9 @@ signals: | ||||
| 	/// Signal which is emitted, when a new json message should be forwarded | ||||
| 	void forwardJsonMessage(QJsonObject); | ||||
|  | ||||
| 	/// Signal which is emitted, when a new proto image should be forwarded | ||||
| 	void forwardProtoMessage(Image<ColorRgb>); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Is emitted from clients who request a videoMode change | ||||
| 	/// | ||||
|   | ||||
| @@ -18,37 +18,86 @@ | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/settings.h> | ||||
| #include <utils/Logger.h> | ||||
| #include <utils/Components.h> | ||||
| #include <utils/Image.h> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/PriorityMuxer.h> | ||||
|  | ||||
| // Forward declaration | ||||
| class Hyperion; | ||||
| class QTcpSocket; | ||||
| class FlatBufferConnection; | ||||
|  | ||||
| class MessageForwarder : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
|  | ||||
| 	MessageForwarder(Hyperion* hyperion, const QJsonDocument & config); | ||||
| 	MessageForwarder(Hyperion* hyperion); | ||||
| 	~MessageForwarder(); | ||||
|  | ||||
| 	void addJsonSlave(QString slave); | ||||
| 	void addProtoSlave(QString slave); | ||||
|  | ||||
| 	bool protoForwardingEnabled(); | ||||
| 	bool jsonForwardingEnabled(); | ||||
| 	bool forwardingEnabled() { return jsonForwardingEnabled() || protoForwardingEnabled(); }; | ||||
| 	QStringList getProtoSlaves() const { return _protoSlaves; }; | ||||
| 	QStringList getJsonSlaves() const { return _jsonSlaves; }; | ||||
|  | ||||
| private slots: | ||||
| 	/// | ||||
| 	/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor | ||||
| 	/// @param type   settingyType from enum | ||||
| 	/// @param config configuration object | ||||
| 	/// | ||||
| 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | ||||
| 	void handleSettingsUpdate(const settings::type &type, const QJsonDocument &config); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Handle component state change MessageForwarder | ||||
| 	/// @param component  The component from enum | ||||
| 	/// @param enable     The new state | ||||
| 	/// | ||||
| 	void componentStateChanged(const hyperion::Components component, bool enable); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Handle priority updates from Priority Muxer | ||||
| 	/// @param  priority  The new visible priority | ||||
| 	/// | ||||
| 	void handlePriorityChanges(const quint8 &priority); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Forward message to all json slaves | ||||
| 	/// @param message The JSON message to send | ||||
| 	/// | ||||
| 	void forwardJsonMessage(const QJsonObject &message); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Forward image to all proto slaves | ||||
| 	/// @param image The PROTO image to send | ||||
| 	/// | ||||
| 	void forwardProtoMessage(const Image<ColorRgb> &image); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Forward message to a single json slave | ||||
| 	/// @param message The JSON message to send | ||||
| 	/// @param socket The TCP-Socket with the connection to the slave | ||||
| 	/// | ||||
| 	void sendJsonMessage(const QJsonObject &message, QTcpSocket *socket); | ||||
|  | ||||
| private: | ||||
| 	Hyperion* _hyperion; | ||||
| 	Logger*   _log; | ||||
| 	QStringList   _protoSlaves; | ||||
| 	/// Hyperion instance | ||||
| 	Hyperion *_hyperion; | ||||
|  | ||||
| 	/// Logger instance | ||||
| 	Logger   *_log; | ||||
|  | ||||
| 	/// Muxer instance | ||||
| 	PriorityMuxer *_muxer; | ||||
|  | ||||
| 	// JSON connection for forwarding | ||||
| 	QStringList   _jsonSlaves; | ||||
|  | ||||
| 	/// Proto connection for forwarding | ||||
| 	QStringList _protoSlaves; | ||||
| 	QList<FlatBufferConnection*> _forwardClients; | ||||
|  | ||||
| 	/// Flag if forwarder is enabled | ||||
| 	bool _forwarder_enabled = true; | ||||
|  | ||||
| 	const int _priority; | ||||
| }; | ||||
|   | ||||
| @@ -107,7 +107,7 @@ public: | ||||
| 	/// | ||||
| 	/// @return The current priority | ||||
| 	/// | ||||
| 	int getCurrentPriority() const; | ||||
| 	int getCurrentPriority() const { return _currentPriority; } | ||||
|  | ||||
| 	/// | ||||
| 	/// Returns the state (enabled/disabled) of a specific priority channel | ||||
| @@ -197,7 +197,7 @@ signals: | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Emits whenever the visible priority has changed | ||||
| 	/// @param  priority  The new visible prioritiy | ||||
| 	/// @param  priority  The new visible priority | ||||
| 	/// | ||||
| 	void visiblePriorityChanged(const quint8& priority); | ||||
|  | ||||
|   | ||||
| @@ -49,17 +49,9 @@ private slots: | ||||
| 	void closedConnection(void); | ||||
|  | ||||
| public slots: | ||||
|  | ||||
| 	/// | ||||
| 	/// forward message to a single json slaves | ||||
| 	/// | ||||
| 	/// @param message The JSON message to send | ||||
| 	/// | ||||
| 	void sendMessage(const QJsonObject & message, QTcpSocket * socket); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor | ||||
| 	/// @param type   settingyType from enum | ||||
| 	/// @param type   settings type from enum | ||||
| 	/// @param config configuration object | ||||
| 	/// | ||||
| 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | ||||
|   | ||||
| @@ -76,11 +76,6 @@ signals: | ||||
| 	/// | ||||
| 	const bool setGlobalInput(const int priority, const std::vector<ColorRgb>& ledColors, const int timeout_ms = -1, const bool& clearEffect = true); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief forward clear to HyperionDaemon | ||||
| 	/// | ||||
| 	void clearGlobalPriority(const int& _priority, const hyperion::Components& component); | ||||
|  | ||||
| private slots: | ||||
| 	/// | ||||
| 	/// Slot which is called when a client tries to create a new connection | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <sstream> | ||||
|  | ||||
| #include <hyperion/ColorAdjustment.h> | ||||
| #include <hyperion/MultiColorAdjustment.h> | ||||
| #include <hyperion/LedString.h> | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include <QByteArray> | ||||
| #include <QDateTime> | ||||
| #include <QHostInfo> | ||||
| #include <QMutexLocker> | ||||
|  | ||||
| // hyperion includes | ||||
| #include <utils/jsonschema/QJsonFactory.h> | ||||
| @@ -55,9 +56,6 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, QObject* parent, bool noListe | ||||
|  | ||||
| 	// notify hyperion about a jsonMessageForward | ||||
| 	connect(this, &JsonAPI::forwardJsonMessage, _hyperion, &Hyperion::forwardJsonMessage); | ||||
|  | ||||
| 	_image_stream_mutex.unlock(); | ||||
| 	_led_stream_mutex.unlock(); | ||||
| } | ||||
|  | ||||
| void JsonAPI::handleMessage(const QString& messageString) | ||||
| @@ -475,10 +473,10 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString& | ||||
| 	// BEGIN | The following entries are derecated but used to ensure backward compatibility with hyperion Classic remote control | ||||
| 	// TODO Output the real transformation information instead of default | ||||
|  | ||||
| 		// host name | ||||
| 		// HOST NAME | ||||
| 		info["hostname"] = QHostInfo::localHostName(); | ||||
|  | ||||
| 		// transform information (default values) | ||||
| 		// TRANSFORM INFORMATION (DEFAULT VALUES) | ||||
| 		QJsonArray transformArray; | ||||
| 		for (const QString& transformId : _hyperion->getAdjustmentIds()) | ||||
| 		{ | ||||
| @@ -507,9 +505,66 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString& | ||||
|  | ||||
| 			transformArray.append(transform); | ||||
| 		} | ||||
|  | ||||
| 		info["transform"] = transformArray; | ||||
|  | ||||
| 		// ACTIVE EFFECT INFO | ||||
| 		QJsonArray activeEffects; | ||||
| 		const std::list<ActiveEffectDefinition> & activeEffectsDefinitions = _hyperion->getActiveEffects(); | ||||
| 		for (const ActiveEffectDefinition & activeEffectDefinition : activeEffectsDefinitions) | ||||
| 		{ | ||||
| 			if (activeEffectDefinition.priority != PriorityMuxer::LOWEST_PRIORITY -1) | ||||
| 			{ | ||||
| 				QJsonObject activeEffect; | ||||
| 				activeEffect["script"] = activeEffectDefinition.script; | ||||
| 				activeEffect["name"] = activeEffectDefinition.name; | ||||
| 				activeEffect["priority"] = activeEffectDefinition.priority; | ||||
| 				activeEffect["timeout"] = activeEffectDefinition.timeout; | ||||
| 				activeEffect["args"] = activeEffectDefinition.args; | ||||
| 				activeEffects.append(activeEffect); | ||||
| 			} | ||||
| 		} | ||||
| 		info["activeEffects"] = activeEffects; | ||||
|  | ||||
| 		// ACTIVE STATIC LED COLOR | ||||
| 		QJsonArray activeLedColors; | ||||
| 		const Hyperion::InputInfo & priorityInfo = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority()); | ||||
| 		if(priorityInfo.componentId == hyperion::COMP_COLOR && !priorityInfo.ledColors.empty()) | ||||
| 		{ | ||||
| 			QJsonObject LEDcolor; | ||||
| 			// check if LED Color not Black (0,0,0) | ||||
| 			if ((priorityInfo.ledColors.begin()->red + | ||||
| 			priorityInfo.ledColors.begin()->green + | ||||
| 			priorityInfo.ledColors.begin()->blue != 0)) | ||||
| 			{ | ||||
| 				QJsonObject LEDcolor; | ||||
|  | ||||
| 				// add RGB Value to Array | ||||
| 				QJsonArray RGBValue; | ||||
| 				RGBValue.append(priorityInfo.ledColors.begin()->red); | ||||
| 				RGBValue.append(priorityInfo.ledColors.begin()->green); | ||||
| 				RGBValue.append(priorityInfo.ledColors.begin()->blue); | ||||
| 				LEDcolor.insert("RGB Value", RGBValue); | ||||
|  | ||||
| 				uint16_t Hue; | ||||
| 				float Saturation, Luminace; | ||||
|  | ||||
| 				// add HSL Value to Array | ||||
| 				QJsonArray HSLValue; | ||||
| 				ColorSys::rgb2hsl(priorityInfo.ledColors.begin()->red, | ||||
| 						priorityInfo.ledColors.begin()->green, | ||||
| 						priorityInfo.ledColors.begin()->blue, | ||||
| 						Hue, Saturation, Luminace); | ||||
|  | ||||
| 				HSLValue.append(Hue); | ||||
| 				HSLValue.append(Saturation); | ||||
| 				HSLValue.append(Luminace); | ||||
| 				LEDcolor.insert("HSL Value", HSLValue); | ||||
|  | ||||
| 				activeLedColors.append(LEDcolor); | ||||
| 			} | ||||
| 		} | ||||
| 		info["activeLedColor"] = activeLedColors; | ||||
|  | ||||
| 	// END | ||||
|  | ||||
| 	sendSuccessDataReply(QJsonDocument(info), command, tan); | ||||
| @@ -952,7 +1007,8 @@ void JsonAPI::sendErrorReply(const QString &error, const QString &command, const | ||||
|  | ||||
| void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors) | ||||
| { | ||||
| 	if ( (_led_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() && _led_stream_mutex.tryLock(0) ) | ||||
| 	QMutexLocker lock(&_led_stream_mutex); | ||||
| 	if ( (_led_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() ) | ||||
| 	{ | ||||
| 		_led_stream_timeout = QDateTime::currentMSecsSinceEpoch(); | ||||
| 		QJsonObject result; | ||||
| @@ -973,14 +1029,13 @@ void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors) | ||||
|  | ||||
| 		// send the result | ||||
| 		emit callbackMessage(_streaming_leds_reply); | ||||
|  | ||||
| 		_led_stream_mutex.unlock(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonAPI::setImage(const Image<ColorRgb> & image) | ||||
| { | ||||
| 	if ( (_image_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() && _image_stream_mutex.tryLock(0) ) | ||||
| 	QMutexLocker lock(&_image_stream_mutex); | ||||
| 	if ( (_image_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() ) | ||||
| 	{ | ||||
| 		_image_stream_timeout = QDateTime::currentMSecsSinceEpoch(); | ||||
|  | ||||
| @@ -994,8 +1049,6 @@ void JsonAPI::setImage(const Image<ColorRgb> & image) | ||||
| 		result["image"] = "data:image/jpg;base64,"+QString(ba.toBase64()); | ||||
| 		_streaming_image_reply["result"] = result; | ||||
| 		emit callbackMessage(_streaming_image_reply); | ||||
|  | ||||
| 		_image_stream_mutex.unlock(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,6 @@ | ||||
| #include <QRgb> | ||||
|  | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <QDebug> | ||||
| FlatBufferClient::FlatBufferClient(QTcpSocket* socket, const int &timeout, QObject *parent) | ||||
| 	: QObject(parent) | ||||
| 	, _log(Logger::getInstance("FLATBUFSERVER")) | ||||
| @@ -61,14 +60,6 @@ void FlatBufferClient::readyRead() | ||||
| 		} | ||||
| 		sendErrorReply("Unable to parse message"); | ||||
| 	} | ||||
| 		//emit newMessage(msgData,messageSize); | ||||
|  | ||||
|  | ||||
| 	// Emit this to send a new priority register event to all Hyperion instances, | ||||
| 	// emit registerGlobalInput(_priority, hyperion::COMP_FLATBUFSERVER, QString("%1@%2").arg("PLACE_ORIGIN_STRING_FROM_SENDER_HERE",_socket->peerAddress())); | ||||
|  | ||||
| 	// Emit this to send the image data event to all Hyperion instances | ||||
| 	// emit setGlobalInput(_priority, _image, _timeout); | ||||
| } | ||||
|  | ||||
| void FlatBufferClient::forceClose() | ||||
| @@ -78,9 +69,9 @@ void FlatBufferClient::forceClose() | ||||
|  | ||||
| void FlatBufferClient::disconnected() | ||||
| { | ||||
| 	qDebug()<<"Socket Closed"; | ||||
| 	//emit clearGlobalPriority(_priority, hyperion::COMP_FLATBUFSERVER); | ||||
| 	Debug(_log, "Socket Closed"); | ||||
|     _socket->deleteLater(); | ||||
| 	_hyperion->clear(_priority); | ||||
| 	emit clientDisconnected(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -44,11 +44,6 @@ signals: | ||||
| 	/// | ||||
| 	const bool setGlobalInputImage(const int priority, const Image<ColorRgb>& image, const int timeout_ms = -1); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief forward clear to HyperionDaemon | ||||
| 	/// | ||||
| 	void clearGlobalPriority(const int& priority, const hyperion::Components& component); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Emits whenever the client disconnected | ||||
| 	/// | ||||
|   | ||||
| @@ -151,6 +151,7 @@ void FlatBufferConnection::sendMessage(const uint8_t* buffer, uint32_t size) | ||||
| 		{ | ||||
| 			case QAbstractSocket::UnconnectedState: | ||||
| 				Info(_log, "No connection to Hyperion: %s:%d", _host.toStdString().c_str(), _port); | ||||
| 				_registered = false; | ||||
| 				break; | ||||
| 			case QAbstractSocket::ConnectedState: | ||||
| 				Info(_log, "Connected to Hyperion: %s:%d", _host.toStdString().c_str(), _port); | ||||
| @@ -158,6 +159,7 @@ void FlatBufferConnection::sendMessage(const uint8_t* buffer, uint32_t size) | ||||
| 				break; | ||||
| 			default: | ||||
| 				Debug(_log, "Connecting to Hyperion: %s:%d", _host.toStdString().c_str(), _port); | ||||
| 				_registered = false; | ||||
| 				break; | ||||
| 	  } | ||||
| 	  _prevSocketState = _socket.state(); | ||||
|   | ||||
| @@ -58,7 +58,6 @@ void FlatBufferServer::newConnection() | ||||
| 	{ | ||||
| 		if(QTcpSocket* socket = _server->nextPendingConnection()) | ||||
| 		{ | ||||
|  | ||||
| 			Debug(_log, "New connection from %s", QSTRING_CSTR(socket->peerAddress().toString())); | ||||
| 			FlatBufferClient *client = new FlatBufferClient(socket, _timeout, this); | ||||
| 			// internal | ||||
|   | ||||
| @@ -92,7 +92,8 @@ bool V4L2Grabber::init() | ||||
| 			{ | ||||
| 				v4lDevices_str += "\t"+ dev.first + "\t" + dev.second + "\n"; | ||||
| 			} | ||||
| 			Info(_log, "available V4L2 devices:\n%s", QSTRING_CSTR(v4lDevices_str)); | ||||
| 			if (!v4lDevices_str.isEmpty()) | ||||
| 				Info(_log, "available V4L2 devices:\n%s", QSTRING_CSTR(v4lDevices_str)); | ||||
| 		} | ||||
|  | ||||
| 		if ( _deviceName == "auto" ) | ||||
|   | ||||
| @@ -3,6 +3,10 @@ | ||||
| SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion) | ||||
| SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion) | ||||
|  | ||||
| include_directories( | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/flatbufserver | ||||
| ) | ||||
|  | ||||
| FILE ( GLOB Hyperion_SOURCES "${CURRENT_HEADER_DIR}/*.h"  "${CURRENT_SOURCE_DIR}/*.h"  "${CURRENT_SOURCE_DIR}/*.cpp" ) | ||||
|  | ||||
| SET(Hyperion_RESOURCES ${CURRENT_SOURCE_DIR}/resource.qrc) | ||||
| @@ -15,6 +19,8 @@ add_library(hyperion | ||||
| target_link_libraries(hyperion | ||||
| 	blackborder | ||||
| 	hyperion-utils | ||||
| 	flatbufserver | ||||
| 	flatbuffers | ||||
| 	leddevice | ||||
| 	bonjour | ||||
| 	boblightserver | ||||
|   | ||||
| @@ -39,7 +39,6 @@ CaptureCont::CaptureCont(Hyperion* hyperion) | ||||
|  | ||||
| CaptureCont::~CaptureCont() | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CaptureCont::handleV4lImage(const Image<ColorRgb> & image) | ||||
| @@ -54,7 +53,6 @@ void CaptureCont::handleSystemImage(const Image<ColorRgb>& image) | ||||
| 	_hyperion->setInputImage(_systemCaptPrio, image); | ||||
| } | ||||
|  | ||||
|  | ||||
| void CaptureCont::setSystemCaptureEnable(const bool& enable) | ||||
| { | ||||
| 	if(_systemCaptEnabled != enable) | ||||
| @@ -63,6 +61,7 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable) | ||||
| 		{ | ||||
| 			_hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER); | ||||
| 			connect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, this, &CaptureCont::handleSystemImage); | ||||
| 			connect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, _hyperion, &Hyperion::forwardProtoMessage); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -82,6 +81,7 @@ void CaptureCont::setV4LCaptureEnable(const bool& enable) | ||||
| 		{ | ||||
| 			_hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L); | ||||
| 			connect(GlobalSignals::getInstance(), &GlobalSignals::setV4lImage, this, &CaptureCont::handleV4lImage); | ||||
| 			connect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, _hyperion, &Hyperion::forwardProtoMessage); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
|   | ||||
| @@ -68,11 +68,6 @@ Hyperion* Hyperion::getInstance() | ||||
| 	return Hyperion::_hyperion; | ||||
| } | ||||
|  | ||||
| MessageForwarder * Hyperion::getForwarder() | ||||
| { | ||||
| 	return _messageForwarder; | ||||
| } | ||||
|  | ||||
| Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath) | ||||
| 	: _daemon(daemon) | ||||
| 	, _settingsManager(new SettingsManager(this, instance, configFile)) | ||||
| @@ -83,7 +78,7 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString | ||||
| 	, _muxer(_ledString.leds().size()) | ||||
| 	, _raw2ledAdjustment(hyperion::createLedColorsAdjustment(_ledString.leds().size(), getSetting(settings::COLOR).object())) | ||||
| 	, _effectEngine(nullptr) | ||||
| 	, _messageForwarder(new MessageForwarder(this, getSetting(settings::NETFORWARD))) | ||||
| 	, _messageForwarder(new MessageForwarder(this)) | ||||
| 	, _configFile(configFile) | ||||
| 	, _rootPath(rootPath) | ||||
| 	, _log(Logger::getInstance("HYPERION")) | ||||
| @@ -408,9 +403,7 @@ const bool Hyperion::setInputImage(const int priority, const Image<ColorRgb>& im | ||||
|  | ||||
| 		// if this priority is visible, update immediately | ||||
| 		if(priority == _muxer.getCurrentPriority()) | ||||
| 		{ | ||||
| 			update(); | ||||
| 		} | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|   | ||||
| @@ -70,7 +70,7 @@ void ImageProcessor::setSize(const unsigned width, const unsigned height) | ||||
| 	} | ||||
|  | ||||
| 	// Clean up the old buffer and mapping | ||||
| 	delete _imageToLeds; | ||||
| 	_imageToLeds = 0; | ||||
|  | ||||
| 	// Construct a new buffer and mapping | ||||
| 	_imageToLeds = (width>0 && height>0) ? (new ImageToLedsMap(width, height, 0, 0, _ledString.leds())) : nullptr; | ||||
| @@ -85,7 +85,7 @@ void ImageProcessor::setLedString(const LedString& ledString) | ||||
| 	const unsigned height = _imageToLeds->height(); | ||||
|  | ||||
| 	// Clean up the old buffer and mapping | ||||
| 	delete _imageToLeds; | ||||
| 	_imageToLeds = 0; | ||||
|  | ||||
| 	// Construct a new buffer and mapping | ||||
| 	_imageToLeds = new ImageToLedsMap(width, height, 0, 0, _ledString.leds()); | ||||
|   | ||||
| @@ -1,32 +1,58 @@ | ||||
| // STL includes | ||||
| #include <stdexcept> | ||||
|  | ||||
| // project includes | ||||
| #include <hyperion/MessageForwarder.h> | ||||
|  | ||||
| #include <utils/Logger.h> | ||||
| // hyperion includes | ||||
| #include <hyperion/Hyperion.h> | ||||
|  | ||||
| MessageForwarder::MessageForwarder(Hyperion* hyperion, const QJsonDocument & config) | ||||
| // utils includes | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| // qt includes | ||||
| #include <QTcpServer> | ||||
| #include <QTcpSocket> | ||||
|  | ||||
| #include <flatbufserver/FlatBufferConnection.h> | ||||
|  | ||||
| MessageForwarder::MessageForwarder(Hyperion *hyperion) | ||||
| 	: QObject() | ||||
| 	, _hyperion(hyperion) | ||||
| 	, _log(Logger::getInstance("NETFORWARDER")) | ||||
| 	, _muxer(_hyperion->getMuxerInstance()) | ||||
| 	, _forwarder_enabled(true) | ||||
| 	, _priority(140) | ||||
| { | ||||
| 	handleSettingsUpdate(settings::NETFORWARD, config); | ||||
| 	// get settings updates | ||||
| 	connect(_hyperion, &Hyperion::settingsChanged, this, &MessageForwarder::handleSettingsUpdate); | ||||
|  | ||||
| 	// component changes | ||||
| 	connect(_hyperion, &Hyperion::componentStateChanged, this, &MessageForwarder::componentStateChanged); | ||||
|  | ||||
| 	// connect with Muxer visible priority changes | ||||
| 	connect(_muxer, &PriorityMuxer::visiblePriorityChanged, this, &MessageForwarder::handlePriorityChanges); | ||||
|  | ||||
| 	// init | ||||
| 	handleSettingsUpdate(settings::NETFORWARD, _hyperion->getSetting(settings::NETFORWARD)); | ||||
| } | ||||
|  | ||||
| MessageForwarder::~MessageForwarder() | ||||
| { | ||||
| 	while (!_forwardClients.isEmpty()) | ||||
| 		delete _forwardClients.takeFirst(); | ||||
| } | ||||
|  | ||||
| void MessageForwarder::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | ||||
| void MessageForwarder::handleSettingsUpdate(const settings::type &type, const QJsonDocument &config) | ||||
| { | ||||
| 	if(type == settings::NETFORWARD) | ||||
| 	{ | ||||
| 		// clear the current targets | ||||
| 		_jsonSlaves.clear(); | ||||
| 		_protoSlaves.clear(); | ||||
| 		while (!_forwardClients.isEmpty()) | ||||
| 			delete _forwardClients.takeFirst(); | ||||
|  | ||||
| 		// build new one | ||||
| 		const QJsonObject &obj = config.object(); | ||||
| 		if ( !obj["json"].isNull() ) | ||||
| @@ -46,12 +72,64 @@ void MessageForwarder::handleSettingsUpdate(const settings::type& type, const QJ | ||||
| 				addProtoSlave(entry.toString()); | ||||
| 			} | ||||
| 		} | ||||
| 		InfoIf(obj["enable"].toBool(true), _log, "Forward now to json targets '%s' and proto targets '%s'", QSTRING_CSTR(_jsonSlaves.join(", ")), QSTRING_CSTR(_protoSlaves.join(", "))) | ||||
|  | ||||
| 		if (!_jsonSlaves.isEmpty() && obj["enable"].toBool() && _forwarder_enabled) | ||||
| 		{ | ||||
| 			InfoIf(obj["enable"].toBool(true), _log, "Forward now to json targets '%s'", QSTRING_CSTR(_jsonSlaves.join(", "))); | ||||
| 			connect(_hyperion, &Hyperion::forwardJsonMessage, this, &MessageForwarder::forwardJsonMessage, Qt::UniqueConnection); | ||||
| 		} else if (_jsonSlaves.isEmpty() || ! obj["enable"].toBool() || !_forwarder_enabled) | ||||
| 			disconnect(_hyperion, &Hyperion::forwardJsonMessage, 0, 0); | ||||
|  | ||||
| 		if (!_protoSlaves.isEmpty() && obj["enable"].toBool() && _forwarder_enabled) | ||||
| 		{ | ||||
| 			InfoIf(obj["enable"].toBool(true), _log, "Forward now to proto targets '%s'", QSTRING_CSTR(_protoSlaves.join(", "))); | ||||
| 			connect(_hyperion, &Hyperion::forwardProtoMessage, this, &MessageForwarder::forwardProtoMessage, Qt::UniqueConnection); | ||||
| 		} else if ( _protoSlaves.isEmpty() || ! obj["enable"].toBool() || !_forwarder_enabled) | ||||
| 			disconnect(_hyperion, &Hyperion::forwardProtoMessage, 0, 0); | ||||
|  | ||||
| 		// update comp state | ||||
| 		_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_FORWARDER, obj["enable"].toBool(true)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MessageForwarder::componentStateChanged(const hyperion::Components component, bool enable) | ||||
| { | ||||
| 	if (component == hyperion::COMP_FORWARDER && _forwarder_enabled != enable) | ||||
| 	{ | ||||
| 		_forwarder_enabled = enable; | ||||
| 		handleSettingsUpdate(settings::NETFORWARD, _hyperion->getSetting(settings::NETFORWARD)); | ||||
| 		Info(_log, "Message Forwarder change state to %s", (_forwarder_enabled ? "enabled" : "disabled")); | ||||
| 		_hyperion->getComponentRegister().componentStateChanged(component, _forwarder_enabled); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MessageForwarder::handlePriorityChanges(const quint8 &priority) | ||||
| { | ||||
| 	const QJsonObject obj = _hyperion->getSetting(settings::NETFORWARD).object(); | ||||
| 	if (priority != 0 && _forwarder_enabled && obj["enable"].toBool()) | ||||
| 	{ | ||||
| 		_protoSlaves.clear(); | ||||
| 		while (!_forwardClients.isEmpty()) | ||||
| 			delete _forwardClients.takeFirst(); | ||||
|  | ||||
| 		hyperion::Components activePrio = _hyperion->getPriorityInfo(priority).componentId; | ||||
| 		if (activePrio == hyperion::COMP_GRABBER || activePrio == hyperion::COMP_V4L) | ||||
| 		{ | ||||
| 			if ( !obj["proto"].isNull() ) | ||||
| 			{ | ||||
| 				const QJsonArray & addr = obj["proto"].toArray(); | ||||
| 				for (const auto& entry : addr) | ||||
| 				{ | ||||
| 					addProtoSlave(entry.toString()); | ||||
| 				} | ||||
| 			} | ||||
| 			connect(_hyperion, &Hyperion::forwardProtoMessage, this, &MessageForwarder::forwardProtoMessage, Qt::UniqueConnection); | ||||
| 		} | ||||
| 		else | ||||
| 			disconnect(_hyperion, &Hyperion::forwardProtoMessage, 0, 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MessageForwarder::addJsonSlave(QString slave) | ||||
| { | ||||
| 	QStringList parts = slave.split(":"); | ||||
| @@ -70,14 +148,15 @@ void MessageForwarder::addJsonSlave(QString slave) | ||||
| 	} | ||||
|  | ||||
| 	// verify loop with jsonserver | ||||
| 	const QJsonObject& obj = _hyperion->getSetting(settings::JSONSERVER).object(); | ||||
| 	const QJsonObject &obj = _hyperion->getSetting(settings::JSONSERVER).object(); | ||||
| 	if(QHostAddress(parts[0]) == QHostAddress::LocalHost && parts[1].toInt() == obj["port"].toInt()) | ||||
| 	{ | ||||
| 		Error(_log, "Loop between JsonServer and Forwarder! (%s)",QSTRING_CSTR(slave)); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	_jsonSlaves << slave; | ||||
| 	if (_forwarder_enabled) | ||||
| 		_jsonSlaves << slave; | ||||
| } | ||||
|  | ||||
| void MessageForwarder::addProtoSlave(QString slave) | ||||
| @@ -98,21 +177,91 @@ void MessageForwarder::addProtoSlave(QString slave) | ||||
| 	} | ||||
|  | ||||
| 	// verify loop with protoserver | ||||
| 	const QJsonObject& obj = _hyperion->getSetting(settings::FLATBUFSERVER).object(); | ||||
| 	const QJsonObject &obj = _hyperion->getSetting(settings::FLATBUFSERVER).object(); | ||||
| 	if(QHostAddress(parts[0]) == QHostAddress::LocalHost && parts[1].toInt() == obj["port"].toInt()) | ||||
| 	{ | ||||
| 		Error(_log, "Loop between ProtoServer and Forwarder! (%s)",QSTRING_CSTR(slave)); | ||||
| 		return; | ||||
| 	} | ||||
| 	_protoSlaves << slave; | ||||
|  | ||||
| 	if (_forwarder_enabled) | ||||
| 	{ | ||||
| 		_protoSlaves << slave; | ||||
| 		FlatBufferConnection* flatbuf = new FlatBufferConnection("Message Forwarder", slave.toLocal8Bit().constData(), _priority, true); | ||||
| 		_forwardClients << flatbuf; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool MessageForwarder::protoForwardingEnabled() | ||||
| void MessageForwarder::forwardJsonMessage(const QJsonObject &message) | ||||
| { | ||||
| 	return ! _protoSlaves.empty(); | ||||
| 	if (_forwarder_enabled) | ||||
| 	{ | ||||
| 		QTcpSocket client; | ||||
| 		for (int i=0; i<_jsonSlaves.size(); i++) | ||||
| 		{ | ||||
| 			QStringList parts = _jsonSlaves.at(i).split(":"); | ||||
| 			client.connectToHost(QHostAddress(parts[0]), parts[1].toUShort()); | ||||
| 			if ( client.waitForConnected(500) ) | ||||
| 			{ | ||||
| 				sendJsonMessage(message,&client); | ||||
| 				client.close(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool MessageForwarder::jsonForwardingEnabled() | ||||
| void MessageForwarder::forwardProtoMessage(const Image<ColorRgb> &image) | ||||
| { | ||||
| 	return ! _jsonSlaves.empty(); | ||||
| 	if (_forwarder_enabled) | ||||
| 	{ | ||||
| 		for (int i=0; i < _forwardClients.size(); i++) | ||||
| 		{ | ||||
| 			_forwardClients.at(i)->setRegister("Message Forwarder", _priority); | ||||
| 			_forwardClients.at(i)->setImage(image); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MessageForwarder::sendJsonMessage(const QJsonObject &message, QTcpSocket *socket) | ||||
| { | ||||
| 	// for hyperion classic compatibility | ||||
| 	QJsonObject jsonMessage = message; | ||||
| 	if (jsonMessage.contains("tan") && jsonMessage["tan"].isNull()) | ||||
| 		jsonMessage["tan"] = 100; | ||||
|  | ||||
| 	// serialize message | ||||
| 	QJsonDocument writer(jsonMessage); | ||||
| 	QByteArray serializedMessage = writer.toJson(QJsonDocument::Compact) + "\n"; | ||||
|  | ||||
| 	// write message | ||||
| 	socket->write(serializedMessage); | ||||
| 	if (!socket->waitForBytesWritten()) | ||||
| 	{ | ||||
| 		Debug(_log, "Error while writing data to host"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// read reply data | ||||
| 	QByteArray serializedReply; | ||||
| 	while (!serializedReply.contains('\n')) | ||||
| 	{ | ||||
| 		// receive reply | ||||
| 		if (!socket->waitForReadyRead()) | ||||
| 		{ | ||||
| 			Debug(_log, "Error while writing data from host"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		serializedReply += socket->readAll(); | ||||
| 	} | ||||
|  | ||||
| 	// parse reply data | ||||
| 	QJsonParseError error; | ||||
| 	QJsonDocument reply = QJsonDocument::fromJson(serializedReply ,&error); | ||||
|  | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		Error(_log, "Error while parsing reply: invalid json"); | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -108,11 +108,6 @@ void PriorityMuxer::updateLedColorsLength(const int& ledCount) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int PriorityMuxer::getCurrentPriority() const | ||||
| { | ||||
| 	return _currentPriority; | ||||
| } | ||||
|  | ||||
| QList<int> PriorityMuxer::getPriorities() const | ||||
| { | ||||
| 	return _activeInputs.keys(); | ||||
| @@ -299,7 +294,7 @@ void PriorityMuxer::setCurrentTime(void) | ||||
| 		else | ||||
| 		{ | ||||
| 			// timeoutTime of -100 is awaiting data (inactive); skip | ||||
| 			if(infoIt->timeoutTime_ms >= -1) | ||||
| 			if(infoIt->timeoutTime_ms >= -100) | ||||
| 				newPriority = qMin(newPriority, infoIt->priority); | ||||
|  | ||||
| 			// call timeTrigger when effect or color is running with timeout > 0, blacklist prio 255 | ||||
|   | ||||
| @@ -17,7 +17,8 @@ | ||||
| 			"enum" : ["linear"], | ||||
| 			"default" : "linear", | ||||
| 			"options" : { | ||||
| 				"enum_titles" : ["edt_conf_enum_linear"] | ||||
| 				"enum_titles" : ["edt_conf_enum_linear"], | ||||
| 				"hidden":true | ||||
| 			}, | ||||
| 			"propertyOrder" : 2 | ||||
| 		}, | ||||
|   | ||||
| @@ -114,43 +114,3 @@ void JsonServer::closedConnection(void) | ||||
| 	// schedule to delete the connection object | ||||
| 	connection->deleteLater(); | ||||
| } | ||||
|  | ||||
| void JsonServer::sendMessage(const QJsonObject & message, QTcpSocket * socket) | ||||
| { | ||||
| 	// serialize message | ||||
| 	QJsonDocument writer(message); | ||||
| 	QByteArray serializedMessage = writer.toJson(QJsonDocument::Compact) + "\n"; | ||||
|  | ||||
| 	// write message | ||||
| 	socket->write(serializedMessage); | ||||
| 	if (!socket->waitForBytesWritten()) | ||||
| 	{ | ||||
| 		Debug(_log, "Error while writing data to host"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// read reply data | ||||
| 	QByteArray serializedReply; | ||||
| 	while (!serializedReply.contains('\n')) | ||||
| 	{ | ||||
| 		// receive reply | ||||
| 		if (!socket->waitForReadyRead()) | ||||
| 		{ | ||||
| 			Debug(_log, "Error while writing data from host"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		serializedReply += socket->readAll(); | ||||
| 	} | ||||
|  | ||||
| 	// parse reply data | ||||
| 	QJsonParseError error; | ||||
| 	QJsonDocument reply = QJsonDocument::fromJson(serializedReply ,&error); | ||||
|  | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		Error(_log, "Error while parsing reply: invalid json"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,11 @@ FILE ( GLOB Leddevice_SOURCES | ||||
| 	"${CURRENT_SOURCE_DIR}/dev_other/*.cpp" | ||||
| ) | ||||
|  | ||||
| if ( ENABLE_OSX ) | ||||
| 	list(REMOVE_ITEM Leddevice_SOURCES "${CURRENT_SOURCE_DIR}/dev_other/LedDevicePiBlaster.h") | ||||
| 	list(REMOVE_ITEM Leddevice_SOURCES "${CURRENT_SOURCE_DIR}/dev_other/LedDevicePiBlaster.cpp") | ||||
| endif() | ||||
|  | ||||
| if ( ENABLE_USB_HID ) | ||||
| 	find_package(libusb-1.0 REQUIRED) | ||||
| 	include_directories( | ||||
|   | ||||
| @@ -80,7 +80,7 @@ void UDPListener::stop() | ||||
| 	_server->close(); | ||||
| 	_isActive = false; | ||||
| 	Info(_log, "Stopped"); | ||||
| 	emit clearGlobalPriority(_priority, hyperion::COMP_UDPLISTENER); | ||||
| //	emit clearGlobalPriority(_priority, hyperion::COMP_UDPLISTENER); | ||||
| } | ||||
|  | ||||
| void UDPListener::componentStateChanged(const hyperion::Components component, bool enable) | ||||
|   | ||||
| @@ -171,6 +171,8 @@ void HyperionDaemon::freeObjects() | ||||
| 	_fbGrabber      = nullptr; | ||||
| 	_osxGrabber     = nullptr; | ||||
| 	_qtGrabber      = nullptr; | ||||
| 	_flatBufferServer = nullptr; | ||||
| 	_ssdp = nullptr; | ||||
| 	_webserver      = nullptr; | ||||
| 	_jsonServer     = nullptr; | ||||
| 	_udpListener    = nullptr; | ||||
|   | ||||
| @@ -4,11 +4,9 @@ | ||||
| #include <utils/jsonschema/QJsonFactory.h> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <utils/hyperion.h> | ||||
| #include <hyperion/ImageToLedsMap.h> | ||||
|  | ||||
| using namespace hyperion; | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	QString homeDir = getenv("RASPILIGHT_HOME"); | ||||
| @@ -23,12 +21,12 @@ int main() | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	const LedString ledString = Hyperion::createLedString(config["leds"], Hyperion::createColorOrder(config["device"].toObject())); | ||||
| 	const LedString ledString = hyperion::createLedString(config["leds"].toArray(), hyperion::createColorOrder(config["device"].toObject())); | ||||
|  | ||||
| 	const ColorRgb testColor = {64, 123, 12}; | ||||
|  | ||||
| 	Image<ColorRgb> image(64, 64, testColor); | ||||
| 	ImageToLedsMap map(64, 64, 0, 0, ledString.leds()); | ||||
| 	hyperion::ImageToLedsMap map(64, 64, 0, 0, ledString.leds()); | ||||
|  | ||||
| 	std::vector<ColorRgb> ledColors(ledString.leds().size()); | ||||
| 	map.getMeanLedColor(image, ledColors); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user