mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Merge d07feea13c into dd81a23dfc
				
					
				
			This commit is contained in:
		| @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||||||
| - Support direct or multiple instance addressing via single requests (#809) | - Support direct or multiple instance addressing via single requests (#809) | ||||||
| - Support of `serverinfo` subcommands: `getInfo, subscribe, unsubscribe, getSubscriptions, getSubscriptionCommands` | - Support of `serverinfo` subcommands: `getInfo, subscribe, unsubscribe, getSubscriptions, getSubscriptionCommands` | ||||||
| - [Overview](https://github.com/hyperion-project/hyperion.ng/blob/API_Auth/doc/development/JSON-API%20_Commands_Overview.md) of API commands and subscription updates | - [Overview](https://github.com/hyperion-project/hyperion.ng/blob/API_Auth/doc/development/JSON-API%20_Commands_Overview.md) of API commands and subscription updates | ||||||
|  | - Support for requesting instance-data via JSON-API. Implemented requesting the current image in different formats or led colors. | ||||||
|  |  | ||||||
| ### Changed | ### Changed | ||||||
|  |  | ||||||
|   | |||||||
| @@ -285,6 +285,25 @@ private: | |||||||
| 	/// | 	/// | ||||||
| 	void handleSystemCommand(const QJsonObject &message, const JsonApiCommand& cmd); | 	void handleSystemCommand(const QJsonObject &message, const JsonApiCommand& cmd); | ||||||
|  |  | ||||||
|  | 	///  Handle an incoming data request message | ||||||
|  | 	///  | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	///  | ||||||
|  | 	void handleInstanceDataCommand(const QJsonObject &message, const JsonApiCommand& cmd); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON message to request the current image | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleGetImageSnapshotCommand(const QJsonObject &message, const JsonApiCommand& cmd); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON message to request the current led colors | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleGetLedSnapshotCommand(const QJsonObject &message, const JsonApiCommand& cmd); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	void applyColorAdjustments(const QJsonObject &adjustment, ColorAdjustment *colorAdjustment); | 	void applyColorAdjustments(const QJsonObject &adjustment, ColorAdjustment *colorAdjustment); | ||||||
| 	void applyColorAdjustment(const QString &colorName, const QJsonObject &adjustment, RgbChannelAdjustment &rgbAdjustment); | 	void applyColorAdjustment(const QString &colorName, const QJsonObject &adjustment, RgbChannelAdjustment &rgbAdjustment); | ||||||
| 	void applyGammaTransform(const QString &transformName, const QJsonObject &adjustment, RgbTransform &rgbTransform, char channel); | 	void applyGammaTransform(const QString &transformName, const QJsonObject &adjustment, RgbTransform &rgbTransform, char channel); | ||||||
| @@ -404,4 +423,6 @@ private: | |||||||
| 	// The JsonCallbacks instance which handles data subscription/notifications | 	// The JsonCallbacks instance which handles data subscription/notifications | ||||||
| 	QSharedPointer<JsonCallbacks> _jsonCB; | 	QSharedPointer<JsonCallbacks> _jsonCB; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ public: | |||||||
| 		Image, | 		Image, | ||||||
| 		InputSource, | 		InputSource, | ||||||
| 		Instance, | 		Instance, | ||||||
|  | 		InstanceData, | ||||||
| 		LedColors, | 		LedColors, | ||||||
| 		LedDevice, | 		LedDevice, | ||||||
| 		Logging, | 		Logging, | ||||||
| @@ -53,6 +54,7 @@ public: | |||||||
| 		case Image: return "image"; | 		case Image: return "image"; | ||||||
| 		case InputSource: return "inputsource"; | 		case InputSource: return "inputsource"; | ||||||
| 		case Instance: return "instance"; | 		case Instance: return "instance"; | ||||||
|  | 		case InstanceData: return "instance-data"; | ||||||
| 		case LedColors: return "ledcolors"; | 		case LedColors: return "ledcolors"; | ||||||
| 		case LedDevice: return "leddevice"; | 		case LedDevice: return "leddevice"; | ||||||
| 		case Logging: return "logging"; | 		case Logging: return "logging"; | ||||||
| @@ -85,7 +87,9 @@ public: | |||||||
| 		Discover, | 		Discover, | ||||||
| 		GetConfig, | 		GetConfig, | ||||||
| 		GetConfigOld, | 		GetConfigOld, | ||||||
|  | 		GetImageSnapshot, | ||||||
| 		GetInfo, | 		GetInfo, | ||||||
|  | 		GetLedSnapshot, | ||||||
| 		GetPendingTokenRequests, | 		GetPendingTokenRequests, | ||||||
| 		GetProperties, | 		GetProperties, | ||||||
| 		GetSchema, | 		GetSchema, | ||||||
| @@ -136,7 +140,9 @@ public: | |||||||
| 		case Discover: return "discover"; | 		case Discover: return "discover"; | ||||||
| 		case GetConfig: return "getconfig"; | 		case GetConfig: return "getconfig"; | ||||||
| 		case GetConfigOld: return "getconfig-old"; | 		case GetConfigOld: return "getconfig-old"; | ||||||
|  | 		case GetImageSnapshot: return "getImageSnapshot"; | ||||||
| 		case GetInfo: return "getInfo"; | 		case GetInfo: return "getInfo"; | ||||||
|  | 		case GetLedSnapshot: return "getLedSnapshot"; | ||||||
| 		case GetPendingTokenRequests: return "getPendingTokenRequests"; | 		case GetPendingTokenRequests: return "getPendingTokenRequests"; | ||||||
| 		case GetProperties: return "getProperties"; | 		case GetProperties: return "getProperties"; | ||||||
| 		case GetSchema: return "getschema"; | 		case GetSchema: return "getschema"; | ||||||
| @@ -294,6 +300,9 @@ public: | |||||||
| 			{ {"instance", "startInstance"}, { Command::Instance, SubCommand::StartInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | 			{ {"instance", "startInstance"}, { Command::Instance, SubCommand::StartInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | ||||||
| 			{ {"instance", "stopInstance"}, { Command::Instance, SubCommand::StopInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | 			{ {"instance", "stopInstance"}, { Command::Instance, SubCommand::StopInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | ||||||
| 			{ {"instance", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | 			{ {"instance", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, | ||||||
|  | 			{ {"instance-data", ""}, { Command::InstanceData, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | ||||||
|  | 			{ {"instance-data", "getImageSnapshot"}, { Command::InstanceData, SubCommand::GetImageSnapshot, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | ||||||
|  | 			{ {"instance-data", "getLedSnapshot"}, { Command::InstanceData, SubCommand::GetLedSnapshot, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes } }, | ||||||
| 			{ {"ledcolors", "imagestream-start"}, { Command::LedColors, SubCommand::ImageStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | 			{ {"ledcolors", "imagestream-start"}, { Command::LedColors, SubCommand::ImageStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | ||||||
| 			{ {"ledcolors", "imagestream-stop"}, { Command::LedColors, SubCommand::ImageStreamStop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | 			{ {"ledcolors", "imagestream-stop"}, { Command::LedColors, SubCommand::ImageStreamStop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | ||||||
| 			{ {"ledcolors", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | 			{ {"ledcolors", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								libsrc/api/JSONRPC_schema/schema-instancedata.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libsrc/api/JSONRPC_schema/schema-instancedata.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | { | ||||||
|  | 	"type":"object", | ||||||
|  | 	"required":true, | ||||||
|  | 	"properties":{ | ||||||
|  | 		"command": { | ||||||
|  | 			"type" : "string", | ||||||
|  | 			"required" : true, | ||||||
|  | 			"enum" : ["instance-data"] | ||||||
|  | 		}, | ||||||
|  | 		"subcommand" : { | ||||||
|  | 			"type" : "string", | ||||||
|  | 			"required" : true, | ||||||
|  | 			"enum" : ["getImageSnapshot","getLedSnapshot"] | ||||||
|  | 		}, | ||||||
|  | 		"instance" : { | ||||||
|  | 			"type": "integer", | ||||||
|  | 			"minimum": 0, | ||||||
|  | 			"maximum": 255 | ||||||
|  | 		}, | ||||||
|  | 		"filetype" : { | ||||||
|  | 			"type" : "string", | ||||||
|  | 			"enum" : ["BMP","JPG","PNG"] | ||||||
|  | 		}, | ||||||
|  | 		"tan" : { | ||||||
|  | 			"type" : "integer" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"additionalProperties": false | ||||||
|  | } | ||||||
| @@ -5,7 +5,7 @@ | |||||||
| 		"command": { | 		"command": { | ||||||
| 			"type" : "string", | 			"type" : "string", | ||||||
| 			"required" : true, | 			"required" : true, | ||||||
| 			"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "service", "system", "transform", "correction", "temperature" ] | 			"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "instance-data", "leddevice", "inputsource", "service", "system", "transform", "correction", "temperature" ] | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ | |||||||
|         <file alias="schema-videomode">JSONRPC_schema/schema-videomode.json</file> |         <file alias="schema-videomode">JSONRPC_schema/schema-videomode.json</file> | ||||||
|         <file alias="schema-authorize">JSONRPC_schema/schema-authorize.json</file> |         <file alias="schema-authorize">JSONRPC_schema/schema-authorize.json</file> | ||||||
|         <file alias="schema-instance">JSONRPC_schema/schema-instance.json</file> |         <file alias="schema-instance">JSONRPC_schema/schema-instance.json</file> | ||||||
|  |         <file alias="schema-instance-data">JSONRPC_schema/schema-instancedata.json</file> | ||||||
|         <file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file> |         <file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file> | ||||||
|         <file alias="schema-inputsource">JSONRPC_schema/schema-inputsource.json</file> |         <file alias="schema-inputsource">JSONRPC_schema/schema-inputsource.json</file> | ||||||
|         <file alias="schema-service">JSONRPC_schema/schema-service.json</file> |         <file alias="schema-service">JSONRPC_schema/schema-service.json</file> | ||||||
|   | |||||||
| @@ -386,6 +386,9 @@ void JsonAPI::handleCommand(const JsonApiCommand& cmd, const QJsonObject &messag | |||||||
| 	case Command::ClearAll: | 	case Command::ClearAll: | ||||||
| 		handleClearallCommand(message, cmd); | 		handleClearallCommand(message, cmd); | ||||||
| 	break; | 	break; | ||||||
|  | 	case Command::InstanceData: | ||||||
|  | 		handleInstanceDataCommand(message, cmd); | ||||||
|  | 		break; | ||||||
| 		// BEGIN | The following commands are deprecated but used to ensure backward compatibility with Hyperion Classic remote control | 		// BEGIN | The following commands are deprecated but used to ensure backward compatibility with Hyperion Classic remote control | ||||||
| 	case Command::Transform: | 	case Command::Transform: | ||||||
| 	case Command::Correction: | 	case Command::Correction: | ||||||
| @@ -398,6 +401,74 @@ void JsonAPI::handleCommand(const JsonApiCommand& cmd, const QJsonObject &messag | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void JsonAPI::handleGetImageSnapshotCommand(const QJsonObject &message, const JsonApiCommand &cmd) | ||||||
|  | { | ||||||
|  | 	QString replyMsg; | ||||||
|  | 	QString filetype = message["filetype"].toString(); | ||||||
|  | 	const PriorityMuxer::InputInfo priorityInfo = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority()); | ||||||
|  | 	Image<ColorRgb> image = priorityInfo.image; | ||||||
|  | 	QImage snapshot(reinterpret_cast<const uchar *>(image.memptr()), image.width(), image.height(), qsizetype(3) * image.width(), QImage::Format_RGB888); | ||||||
|  | 	QByteArray byteArray; | ||||||
|  |  | ||||||
|  | 	QBuffer buffer{&byteArray}; | ||||||
|  | 	buffer.open(QIODevice::WriteOnly); | ||||||
|  | 	if (!snapshot.save(&buffer, filetype.toUtf8().constData())) | ||||||
|  | 	{ | ||||||
|  | 		replyMsg = QString("Failed to create snapshot of the current image in %1 format").arg(filetype); | ||||||
|  | 		sendErrorReply(replyMsg, cmd); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	QByteArray base64Image = byteArray.toBase64(); | ||||||
|  |  | ||||||
|  | 	QJsonObject info; | ||||||
|  | 	info["format"] = filetype; | ||||||
|  | 	info["width"] = image.width(); | ||||||
|  | 	info["height"] = image.height(); | ||||||
|  | 	info["data"] = QString::fromLatin1(base64Image.data()); | ||||||
|  | 	sendSuccessDataReply(info, cmd); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonAPI::handleGetLedSnapshotCommand(const QJsonObject &message, const JsonApiCommand &cmd) | ||||||
|  | { | ||||||
|  | 	QString replyMsg; | ||||||
|  | 	const PriorityMuxer::InputInfo priorityInfo = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority()); | ||||||
|  | 	const std::vector<ColorRgb> ledColors = _hyperion->getImageProcessor()->process(priorityInfo.image); | ||||||
|  | 	if (ledColors.empty()) | ||||||
|  | 	{ | ||||||
|  | 		replyMsg = "No led colors available"; | ||||||
|  | 		sendErrorReply(replyMsg, cmd); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	QJsonArray ledColorsArray; | ||||||
|  | 	for (const auto &color : ledColors) | ||||||
|  | 	{ | ||||||
|  | 		QJsonArray rgbArray; | ||||||
|  | 		rgbArray.append(color.red); | ||||||
|  | 		rgbArray.append(color.green); | ||||||
|  | 		rgbArray.append(color.blue); | ||||||
|  | 		ledColorsArray.append(rgbArray); | ||||||
|  | 	} | ||||||
|  | 	QJsonObject info; | ||||||
|  | 	info["leds"] = ledColorsArray; | ||||||
|  | 	sendSuccessDataReply(info, cmd); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonAPI::handleInstanceDataCommand(const QJsonObject &message, const JsonApiCommand &cmd) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | 	switch (cmd.subCommand) | ||||||
|  | 	{ | ||||||
|  | 	case SubCommand::GetImageSnapshot: | ||||||
|  | 		handleGetImageSnapshotCommand(message, cmd); | ||||||
|  | 		break; | ||||||
|  | 	case SubCommand::GetLedSnapshot: | ||||||
|  | 		handleGetLedSnapshotCommand(message, cmd); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 	break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| void JsonAPI::handleColorCommand(const QJsonObject &message, const JsonApiCommand& cmd) | void JsonAPI::handleColorCommand(const QJsonObject &message, const JsonApiCommand& cmd) | ||||||
| { | { | ||||||
| 	emit forwardJsonMessage(message); | 	emit forwardJsonMessage(message); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user