From 7a604ee5e73b4a513b08ff7589601a7348d29cbf Mon Sep 17 00:00:00 2001 From: LordGrey <48840279+Lord-Grey@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:12:30 +0200 Subject: [PATCH] Add Event Subscriptions & Instance specific replies --- include/api/JsonAPI.h | 11 +-- include/api/JsonApiCommand.h | 148 ++++++++++++++++-------------- include/api/JsonApiSubscription.h | 27 ++++++ include/api/JsonCallbacks.h | 13 +-- libsrc/api/JsonAPI.cpp | 54 +++++++---- libsrc/api/JsonCallbacks.cpp | 39 ++++---- libsrc/events/EventHandler.cpp | 2 + 7 files changed, 179 insertions(+), 115 deletions(-) diff --git a/include/api/JsonAPI.h b/include/api/JsonAPI.h index 7cef7f14..714e2bfd 100644 --- a/include/api/JsonAPI.h +++ b/include/api/JsonAPI.h @@ -316,7 +316,7 @@ private: /// /// Send a standard reply indicating success /// - void sendSuccessReply(const QString &command = "", int tan = 0); + void sendSuccessReply(const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No); /// /// Send a standard reply indicating success with data @@ -326,7 +326,7 @@ private: /// /// Send a standard reply indicating success with data /// - void sendSuccessDataReply(const QJsonValue &infoData, const QString &command = "", int tan = 0); + void sendSuccessDataReply(const QJsonValue &infoData, const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No); /// /// Send a standard reply indicating success with data and error details @@ -336,8 +336,7 @@ private: /// /// Send a standard reply indicating success with data and error details /// - void sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command = "", int tan = 0, const QStringList& errorDetails = {}); - + void sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command = "", int tan = 0, const QStringList& errorDetails = {}, InstanceCmd::Type isInstanceCmd = InstanceCmd::No); /// /// Send a message with data. @@ -349,7 +348,7 @@ private: /// Send a message with data /// Note: To be used as a new message and not as a response to a previous request. /// - void sendNewRequest(const QJsonValue &infoData, const QString &command); + void sendNewRequest(const QJsonValue &infoData, const QString &command, InstanceCmd::Type isInstanceCmd = InstanceCmd::No); /// /// Send an error message back to the client @@ -372,7 +371,7 @@ private: /// @param error String describing the error /// @param errorDetails additional information detailing the error scenario /// - void sendErrorReply(const QString &error, const QStringList& errorDetails = {}, const QString &command = "", int tan = 0); + void sendErrorReply(const QString &error, const QStringList& errorDetails = {}, const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No); void sendNoAuthorization(const JsonApiCommand& cmd); diff --git a/include/api/JsonApiCommand.h b/include/api/JsonApiCommand.h index 5ec8caf8..e7abe96e 100644 --- a/include/api/JsonApiCommand.h +++ b/include/api/JsonApiCommand.h @@ -194,6 +194,14 @@ public: }; }; +class InstanceCmd { +public: + enum Type { + No, + Yes + }; +}; + class JsonApiCommand { public: @@ -202,21 +210,26 @@ public: subCommand(SubCommand::Unknown), tan(0), authorization(Authorization::Admin), + isInstanceCmd(InstanceCmd::No), isNolistenerCmd(NoListenerCmd::Yes) {} JsonApiCommand(Command::Type command, SubCommand::Type subCommand, Authorization::Type authorization, - NoListenerCmd::Type isNolistenerCmd, int tan = 0) + InstanceCmd::Type isInstanceCmd, + NoListenerCmd::Type isNolistenerCmd, + int tan = 0) : command(command), subCommand(subCommand), tan(tan), authorization(authorization), + isInstanceCmd(isInstanceCmd), isNolistenerCmd(isNolistenerCmd) {} Command::Type getCommand() const { return command; } SubCommand::Type getSubCommand() const { return subCommand; } + InstanceCmd::Type instanceCmd() const { return isInstanceCmd; }; int getTan() const { return tan; } QString toString() const { @@ -232,6 +245,7 @@ public: int tan; Authorization::Type authorization; + InstanceCmd::Type isInstanceCmd; NoListenerCmd::Type isNolistenerCmd; }; @@ -242,72 +256,72 @@ public: static const CommandLookupMap& getCommandLookup() { static const CommandLookupMap commandLookup { - { {"adjustment", ""}, { Command::Adjustment, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"authorize", "adminRequired"}, { Command::Authorize, SubCommand::AdminRequired, Authorization::No, NoListenerCmd::Yes} }, - { {"authorize", "answerRequest"}, { Command::Authorize, SubCommand::AnswerRequest, Authorization::Admin, NoListenerCmd::No} }, - { {"authorize", "createToken"}, { Command::Authorize, SubCommand::CreateToken, Authorization::Admin, NoListenerCmd::No} }, - { {"authorize", "deleteToken"}, { Command::Authorize, SubCommand::DeleteToken, Authorization::Admin, NoListenerCmd::Yes} }, - { {"authorize", "getPendingTokenRequests"}, { Command::Authorize, SubCommand::GetPendingTokenRequests, Authorization::Admin, NoListenerCmd::No} }, - { {"authorize", "getTokenList"}, { Command::Authorize, SubCommand::GetTokenList, Authorization::Admin, NoListenerCmd::Yes} }, - { {"authorize", "login"}, { Command::Authorize, SubCommand::Login, Authorization::No, NoListenerCmd::No} }, - { {"authorize", "logout"}, { Command::Authorize, SubCommand::Logout, Authorization::No, NoListenerCmd::No} }, - { {"authorize", "newPassword"}, { Command::Authorize, SubCommand::NewPassword, Authorization::Admin, NoListenerCmd::Yes} }, - { {"authorize", "newPasswordRequired"}, { Command::Authorize, SubCommand::NewPasswordRequired, Authorization::No, NoListenerCmd::Yes} }, - { {"authorize", "renameToken"}, { Command::Authorize, SubCommand::RenameToken, Authorization::Admin, NoListenerCmd::Yes} }, - { {"authorize", "requestToken"}, { Command::Authorize, SubCommand::RequestToken, Authorization::No, NoListenerCmd::Yes} }, - { {"authorize", "tokenRequired"}, { Command::Authorize, SubCommand::TokenRequired, Authorization::No, NoListenerCmd::Yes} }, - { {"clear", ""}, { Command::Clear, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"clearall", ""}, { Command::ClearAll, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"color", ""}, { Command::Color, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"componentstate", ""}, { Command::ComponentState, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"config", "getconfig"}, { Command::Config, SubCommand::GetConfig, Authorization::Admin, NoListenerCmd::Yes} }, - { {"config", "getschema"}, { Command::Config, SubCommand::GetSchema, Authorization::Admin, NoListenerCmd::Yes} }, - { {"config", "reload"}, { Command::Config, SubCommand::Reload, Authorization::Admin, NoListenerCmd::Yes} }, - { {"config", "restoreconfig"}, { Command::Config, SubCommand::RestoreConfig, Authorization::Admin, NoListenerCmd::Yes} }, - { {"config", "setconfig"}, { Command::Config, SubCommand::SetConfig, Authorization::Admin, NoListenerCmd::Yes} }, - { {"correction", ""}, { Command::Correction, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"create-effect", ""}, { Command::CreateEffect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"delete-effect", ""}, { Command::DeleteEffect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"effect", ""}, { Command::Effect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"image", ""}, { Command::Image, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"inputsource", "discover"}, { Command::InputSource, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} }, - { {"inputsource", "getProperties"}, { Command::InputSource, SubCommand::GetProperties, Authorization::Yes, NoListenerCmd::Yes} }, - { {"instance", "createInstance"}, { Command::Instance, SubCommand::CreateInstance, Authorization::Admin, NoListenerCmd::Yes} }, - { {"instance", "deleteInstance"}, { Command::Instance, SubCommand::DeleteInstance, Authorization::Admin, NoListenerCmd::Yes} }, - { {"instance", "saveName"}, { Command::Instance, SubCommand::SaveName, Authorization::Admin, NoListenerCmd::Yes} }, - { {"instance", "startInstance"}, { Command::Instance, SubCommand::StartInstance, Authorization::Yes, NoListenerCmd::Yes} }, - { {"instance", "stopInstance"}, { Command::Instance, SubCommand::StopInstance, Authorization::Yes, NoListenerCmd::Yes} }, - { {"instance", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, NoListenerCmd::Yes} }, - { {"ledcolors", "imagestream-start"}, { Command::LedColors, SubCommand::ImageStreamStart, Authorization::Yes, NoListenerCmd::Yes} }, - { {"ledcolors", "imagestream-stop"}, { Command::LedColors, SubCommand::ImageStreamStop, Authorization::Yes, NoListenerCmd::Yes} }, - { {"ledcolors", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, NoListenerCmd::Yes} }, - { {"ledcolors", "ledstream-stop"}, { Command::LedColors, SubCommand::LedStreamStop, Authorization::Yes, NoListenerCmd::Yes} }, - { {"leddevice", "addAuthorization"}, { Command::LedDevice, SubCommand::AddAuthorization, Authorization::Yes, NoListenerCmd::Yes} }, - { {"leddevice", "discover"}, { Command::LedDevice, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} }, - { {"leddevice", "getProperties"}, { Command::LedDevice, SubCommand::GetProperties, Authorization::Yes, NoListenerCmd::Yes} }, - { {"leddevice", "identify"}, { Command::LedDevice, SubCommand::Identify, Authorization::Yes, NoListenerCmd::Yes} }, - { {"logging", "start"}, { Command::Logging, SubCommand::Start, Authorization::Yes, NoListenerCmd::Yes} }, - { {"logging", "stop"}, { Command::Logging, SubCommand::Stop, Authorization::Yes, NoListenerCmd::Yes} }, - { {"logging", "update"}, { Command::Logging, SubCommand::Update, Authorization::Yes, NoListenerCmd::Yes} }, - { {"processing", ""}, { Command::Processing, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"sourceselect", ""}, { Command::SourceSelect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"serverinfo", ""}, { Command::ServerInfo, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"serverinfo", "getInfo"}, { Command::ServerInfo, SubCommand::GetInfo, Authorization::Yes, NoListenerCmd::Yes} }, - { {"serverinfo", "subscribe"}, { Command::ServerInfo, SubCommand::Subscribe, Authorization::Yes, NoListenerCmd::No} }, - { {"serverinfo", "unsubscribe"}, { Command::ServerInfo, SubCommand::Unsubscribe, Authorization::Yes, NoListenerCmd::No} }, - { {"serverinfo", "getSubscriptions"}, { Command::ServerInfo, SubCommand::GetSubscriptions, Authorization::Yes, NoListenerCmd::No} }, - { {"serverinfo", "getSubscriptionCommands"}, { Command::ServerInfo, SubCommand::GetSubscriptionCommands, Authorization::No, NoListenerCmd::No} }, - { {"sysinfo", ""}, { Command::SysInfo, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "restart"}, { Command::System, SubCommand::Restart, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "resume"}, { Command::System, SubCommand::Resume, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "suspend"}, { Command::System, SubCommand::Suspend, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "toggleSuspend"}, { Command::System, SubCommand::ToggleSuspend, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "idle"}, { Command::System, SubCommand::Idle, Authorization::Yes, NoListenerCmd::Yes} }, - { {"system", "toggleIdle"}, { Command::System, SubCommand::ToggleIdle, Authorization::Yes, NoListenerCmd::Yes} }, - { {"temperature", ""}, { Command::Temperature, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"transform", ""}, { Command::Transform, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"videomode", ""}, { Command::VideoMode, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} }, - { {"service", "discover"}, { Command::Service, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} } + { {"adjustment", ""}, { Command::Adjustment, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"authorize", "adminRequired"}, { Command::Authorize, SubCommand::AdminRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "answerRequest"}, { Command::Authorize, SubCommand::AnswerRequest, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} }, + { {"authorize", "createToken"}, { Command::Authorize, SubCommand::CreateToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} }, + { {"authorize", "deleteToken"}, { Command::Authorize, SubCommand::DeleteToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "getPendingTokenRequests"}, { Command::Authorize, SubCommand::GetPendingTokenRequests, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} }, + { {"authorize", "getTokenList"}, { Command::Authorize, SubCommand::GetTokenList, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "login"}, { Command::Authorize, SubCommand::Login, Authorization::No, InstanceCmd::No, NoListenerCmd::No} }, + { {"authorize", "logout"}, { Command::Authorize, SubCommand::Logout, Authorization::No, InstanceCmd::No, NoListenerCmd::No} }, + { {"authorize", "newPassword"}, { Command::Authorize, SubCommand::NewPassword, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "newPasswordRequired"}, { Command::Authorize, SubCommand::NewPasswordRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "renameToken"}, { Command::Authorize, SubCommand::RenameToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "requestToken"}, { Command::Authorize, SubCommand::RequestToken, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"authorize", "tokenRequired"}, { Command::Authorize, SubCommand::TokenRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"clear", ""}, { Command::Clear, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"clearall", ""}, { Command::ClearAll, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"color", ""}, { Command::Color, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"componentstate", ""}, { Command::ComponentState, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"config", "getconfig"}, { Command::Config, SubCommand::GetConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"config", "getschema"}, { Command::Config, SubCommand::GetSchema, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"config", "reload"}, { Command::Config, SubCommand::Reload, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"config", "restoreconfig"}, { Command::Config, SubCommand::RestoreConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"config", "setconfig"}, { Command::Config, SubCommand::SetConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"correction", ""}, { Command::Correction, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"create-effect", ""}, { Command::CreateEffect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"delete-effect", ""}, { Command::DeleteEffect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"effect", ""}, { Command::Effect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"image", ""}, { Command::Image, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"inputsource", "discover"}, { Command::InputSource, SubCommand::Discover, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"inputsource", "getProperties"}, { Command::InputSource, SubCommand::GetProperties, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"instance", "createInstance"}, { Command::Instance, SubCommand::CreateInstance, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"instance", "deleteInstance"}, { Command::Instance, SubCommand::DeleteInstance, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"instance", "saveName"}, { Command::Instance, SubCommand::SaveName, Authorization::Admin, 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", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, InstanceCmd::No, 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", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"ledcolors", "ledstream-stop"}, { Command::LedColors, SubCommand::LedStreamStop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"leddevice", "addAuthorization"}, { Command::LedDevice, SubCommand::AddAuthorization, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"leddevice", "discover"}, { Command::LedDevice, SubCommand::Discover, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"leddevice", "getProperties"}, { Command::LedDevice, SubCommand::GetProperties, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"leddevice", "identify"}, { Command::LedDevice, SubCommand::Identify, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"logging", "start"}, { Command::Logging, SubCommand::Start, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"logging", "stop"}, { Command::Logging, SubCommand::Stop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"logging", "update"}, { Command::Logging, SubCommand::Update, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"processing", ""}, { Command::Processing, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"serverinfo", ""}, { Command::ServerInfo, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"serverinfo", "getInfo"}, { Command::ServerInfo, SubCommand::GetInfo, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"serverinfo", "subscribe"}, { Command::ServerInfo, SubCommand::Subscribe, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} }, + { {"serverinfo", "unsubscribe"}, { Command::ServerInfo, SubCommand::Unsubscribe, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} }, + { {"serverinfo", "getSubscriptions"}, { Command::ServerInfo, SubCommand::GetSubscriptions, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} }, + { {"serverinfo", "getSubscriptionCommands"}, { Command::ServerInfo, SubCommand::GetSubscriptionCommands, Authorization::No, InstanceCmd::No, NoListenerCmd::No} }, + { {"service", "discover"}, { Command::Service, SubCommand::Discover, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"sourceselect", ""}, { Command::SourceSelect, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"sysinfo", ""}, { Command::SysInfo, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "restart"}, { Command::System, SubCommand::Restart, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "resume"}, { Command::System, SubCommand::Resume, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "suspend"}, { Command::System, SubCommand::Suspend, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "toggleSuspend"}, { Command::System, SubCommand::ToggleSuspend, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "idle"}, { Command::System, SubCommand::Idle, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"system", "toggleIdle"}, { Command::System, SubCommand::ToggleIdle, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }, + { {"temperature", ""}, { Command::Temperature, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"transform", ""}, { Command::Transform, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} }, + { {"videomode", ""}, { Command::VideoMode, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} } }; return commandLookup; } diff --git a/include/api/JsonApiSubscription.h b/include/api/JsonApiSubscription.h index f924099f..e090e319 100644 --- a/include/api/JsonApiSubscription.h +++ b/include/api/JsonApiSubscription.h @@ -16,6 +16,7 @@ public: #if defined(ENABLE_EFFECTENGINE) EffectsUpdate, #endif + EventUpdate, ImageToLedMappingUpdate, ImageUpdate, InstanceUpdate, @@ -35,6 +36,7 @@ public: #if defined(ENABLE_EFFECTENGINE) case EffectsUpdate: return "effects-update"; #endif + case EventUpdate: return "event-update"; case ImageToLedMappingUpdate: return "imageToLedMapping-update"; case ImageUpdate: return "image-update"; case InstanceUpdate: return "instance-update"; @@ -48,6 +50,30 @@ public: default: return "unknown"; } } + + static bool isInstacneSpecific(Type type) { + switch (type) { + case AdjustmentUpdate: + case ComponentsUpdate: +#if defined(ENABLE_EFFECTENGINE) + case EffectsUpdate: +#endif + case ImageToLedMappingUpdate: + case ImageUpdate: + case LedColorsUpdate: + case LedsUpdate: + case PrioritiesUpdate: + case SettingsUpdate: + return true; + case EventUpdate: + case InstanceUpdate: + case LogMsgUpdate: + case TokenUpdate: + case VideomodeUpdate: + default: + return false; + } + } }; class JsonApiSubscription { @@ -86,6 +112,7 @@ public: #if defined(ENABLE_EFFECTENGINE) { {"effects-update"}, { Subscription::EffectsUpdate, true} }, #endif + { {"event-update"}, { Subscription::EventUpdate, true} }, { {"imageToLedMapping-update"}, { Subscription::ImageToLedMappingUpdate, true} }, { {"image-update"}, { Subscription::ImageUpdate, false} }, { {"instance-update"}, { Subscription::InstanceUpdate, true} }, diff --git a/include/api/JsonCallbacks.h b/include/api/JsonCallbacks.h index 88bc9689..d4dac47c 100644 --- a/include/api/JsonCallbacks.h +++ b/include/api/JsonCallbacks.h @@ -2,22 +2,17 @@ #include "api/JsonApiSubscription.h" #include +#include // qt incl #include #include #include -// components def #include - -// videModes #include -// settings #include -// AuthManager #include - #include class Hyperion; @@ -177,6 +172,12 @@ private slots: /// void handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &); + /// + /// @brief Is called whenever an event is triggert + /// @param image The current event + /// + void handleEventUpdate(const Event &event); + private: /// construct callback msg diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index a5d9c221..fd589d38 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -1312,45 +1312,51 @@ void JsonAPI::handleSystemCommand(const QJsonObject& /*message*/, const JsonApiC void JsonAPI::sendSuccessReply(const JsonApiCommand& cmd) { - sendSuccessReply(cmd.toString(), cmd.tan); + sendSuccessReply(cmd.toString(), cmd.tan, cmd.isInstanceCmd); } -void JsonAPI::sendSuccessReply(const QString &command, int tan) +void JsonAPI::sendSuccessReply(const QString &command, int tan, InstanceCmd::Type isInstanceCmd) { - // create reply QJsonObject reply; - reply["instance"] = _hyperion->getInstanceIndex(); reply["success"] = true; reply["command"] = command; reply["tan"] = tan; - // send reply + if (isInstanceCmd == InstanceCmd::Yes) + { + reply["instance"] = _hyperion->getInstanceIndex(); + } + emit callbackMessage(reply); } void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd) { - sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, {}); + sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, {}, cmd.isInstanceCmd); } -void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const QString &command, int tan) +void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const QString &command, int tan, InstanceCmd::Type isInstanceCmd) { - sendSuccessDataReplyWithError(infoData, command, tan, {}); + sendSuccessDataReplyWithError(infoData, command, tan, {}, isInstanceCmd); } void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const JsonApiCommand& cmd, const QStringList& errorDetails) { - sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, errorDetails); + sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, errorDetails, cmd.isInstanceCmd); } -void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command, int tan, const QStringList& errorDetails) +void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command, int tan, const QStringList& errorDetails, InstanceCmd::Type isInstanceCmd) { QJsonObject reply; - reply["instance"] = _hyperion->getInstanceIndex(); reply["success"] = true; - reply["command"] = command; reply["tan"] = tan; + + if (isInstanceCmd == InstanceCmd::Yes) + { + reply["instance"] = _hyperion->getInstanceIndex(); + } + reply["info"] = infoData; if (!errorDetails.isEmpty()) @@ -1369,13 +1375,19 @@ void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QS void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd) { - sendSuccessDataReplyWithError(infoData, cmd.toString()); + sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.isInstanceCmd); } -void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command) +void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command, InstanceCmd::Type isInstanceCmd) { QJsonObject request; request["command"] = command; + + if (isInstanceCmd == InstanceCmd::Yes) + { + request["instance"] = _hyperion->getInstanceIndex(); + } + request["info"] = infoData; emit callbackMessage(request); @@ -1383,24 +1395,26 @@ void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command) void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd) { - sendErrorReply(error, {}, cmd.toString(), cmd.tan); + sendErrorReply(error, {}, cmd.toString(), cmd.tan, cmd.isInstanceCmd); } void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const JsonApiCommand& cmd) { - sendErrorReply(error, errorDetails, cmd.toString(), cmd.tan); + sendErrorReply(error, errorDetails, cmd.toString(), cmd.tan, cmd.isInstanceCmd); } -void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const QString &command, int tan) +void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const QString &command, int tan, InstanceCmd::Type isInstanceCmd) { - // create reply QJsonObject reply; - reply["instance"] = _hyperion->getInstanceIndex(); reply["success"] = false; - reply["command"] = command; reply["tan"] = tan; + if (isInstanceCmd == InstanceCmd::Yes) + { + reply["instance"] = _hyperion->getInstanceIndex(); + } + reply["error"] = error; if (!errorDetails.isEmpty()) { diff --git a/libsrc/api/JsonCallbacks.cpp b/libsrc/api/JsonCallbacks.cpp index 8f89b449..a8d8685f 100644 --- a/libsrc/api/JsonCallbacks.cpp +++ b/libsrc/api/JsonCallbacks.cpp @@ -1,33 +1,20 @@ -// proj incl #include #include #include -// hyperion #include - -// HyperionIManager #include -// components - +#include #include -// priorityMuxer - #include - -// utils #include +#include -// qt #include #include #include #include -// Image to led map helper - -#include - using namespace hyperion; JsonCallbacks::JsonCallbacks(Logger *log, const QString& peerAddress, QObject* parent) @@ -56,6 +43,9 @@ bool JsonCallbacks::subscribe(const Subscription::Type cmd) connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange); break; #endif + case Subscription::EventUpdate: + connect(EventHandler::getInstance().data(), &EventHandler::signalEvent, this, &JsonCallbacks::handleEventUpdate); + break; case Subscription::ImageToLedMappingUpdate: connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange); break; @@ -155,6 +145,9 @@ bool JsonCallbacks::unsubscribe(const Subscription::Type cmd) disconnect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange); break; #endif + case Subscription::EventUpdate: + disconnect(EventHandler::getInstance().data(), &EventHandler::signalEvent, this, &JsonCallbacks::handleEventUpdate); + break; case Subscription::ImageToLedMappingUpdate: disconnect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange); break; @@ -290,9 +283,13 @@ QStringList JsonCallbacks::getSubscribedCommands() const void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data) { QJsonObject obj; - obj["instance"] = _hyperion->getInstanceIndex(); obj["command"] = Subscription::toString(cmd); + if (Subscription::isInstacneSpecific(cmd)) + { + obj["instance"] = _hyperion->getInstanceIndex(); + } + if (data.userType() == QMetaType::QJsonArray) { obj["data"] = data.toJsonArray(); } else { @@ -449,3 +446,13 @@ void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg) doCallback(Subscription::LogMsgUpdate, QVariant(result)); } + +void JsonCallbacks::handleEventUpdate(const Event &event) +{ + QJsonObject result; + + result["event"] = eventToString(event); + + doCallback(Subscription::EventUpdate, QVariant(result)); +} + diff --git a/libsrc/events/EventHandler.cpp b/libsrc/events/EventHandler.cpp index a76ed462..58eab1cc 100644 --- a/libsrc/events/EventHandler.cpp +++ b/libsrc/events/EventHandler.cpp @@ -179,10 +179,12 @@ void EventHandler::handleEvent(Event event) break; case Event::Reload: + emit signalEvent(Event::Reload); Process::restartHyperion(10); break; case Event::Restart: + emit signalEvent(Event::Restart); Process::restartHyperion(11); break;