mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
JSON RPC Writer (configSet) (#175)
* Remove "endOfJson" Value Deprecated value from Hypercon * Remove "endOfJson" Value Deprecated value from Hypercon * Add writeJson function to JsonFactory * ability to ignore required value in schema file * Remove "endOfJson" Value * Add handleConfigSetCommand function * Add handleConfigSetCommand function * Update JsonSchemas.qrc * Update schema.json * Update JsonSchemaChecker.cpp * Add configSet command to Hyperion-remote * Add setConfigFile function * Add setConfigFile function * Add schema-configset.json
This commit is contained in:
parent
97181fa83c
commit
68fd395670
@ -604,7 +604,5 @@
|
||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
||||
}
|
||||
],
|
||||
|
||||
"endOfJson" : "endOfJson"
|
||||
]
|
||||
}
|
||||
|
@ -437,7 +437,5 @@
|
||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
||||
}
|
||||
],
|
||||
|
||||
"endOfJson" : "endOfJson"
|
||||
]
|
||||
}
|
||||
|
@ -63,4 +63,12 @@ public:
|
||||
}
|
||||
return jsonTree;
|
||||
}
|
||||
|
||||
static void writeJson(const std::string& filename, Json::Value& jsonTree)
|
||||
{
|
||||
Json::StyledStreamWriter writer;
|
||||
|
||||
std::ofstream ofs(filename.c_str());
|
||||
writer.write(ofs, jsonTree);
|
||||
}
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
/// @param value The JSON value to check
|
||||
/// @return true when the arguments is valid according to the schema
|
||||
///
|
||||
bool validate(const Json::Value & value);
|
||||
bool validate(const Json::Value & value, bool ignoreRequired = false);
|
||||
|
||||
///
|
||||
/// @return A list of error messages
|
||||
@ -179,6 +179,8 @@ private:
|
||||
private:
|
||||
/// The schema of the entire json-configuration
|
||||
Json::Value _schema;
|
||||
/// ignore the required value in json schema
|
||||
bool _ignoreRequired;
|
||||
|
||||
/// The current location into a json-configuration structure being checked
|
||||
std::list<std::string> _currentPath;
|
||||
|
@ -896,10 +896,6 @@
|
||||
},
|
||||
"additionalProperties" : false
|
||||
}
|
||||
},
|
||||
"endOfJson" :
|
||||
{
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/jsonschema/JsonFactory.h>
|
||||
|
||||
// project includes
|
||||
#include "JsonClientConnection.h"
|
||||
@ -267,6 +268,8 @@ void JsonClientConnection::handleMessage(const std::string &messageString)
|
||||
handleSourceSelectCommand(message);
|
||||
else if (command == "configget")
|
||||
handleConfigGetCommand(message);
|
||||
else if (command == "configset")
|
||||
handleConfigSetCommand(message);
|
||||
else if (command == "componentstate")
|
||||
handleComponentStateCommand(message);
|
||||
else
|
||||
@ -842,6 +845,53 @@ void JsonClientConnection::handleConfigGetCommand(const Json::Value &)
|
||||
sendMessage(result);
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleConfigSetCommand(const Json::Value &message)
|
||||
{
|
||||
struct nested
|
||||
{
|
||||
static void configSetCommand(const Json::Value& message, Json::Value& config, bool& create)
|
||||
{
|
||||
if (!config.isObject() || !message.isObject())
|
||||
return;
|
||||
|
||||
for (const auto& key : message.getMemberNames()) {
|
||||
if ((config.isObject() && config.isMember(key)) || create)
|
||||
{
|
||||
if (config[key].type() == Json::objectValue && message[key].type() == Json::objectValue)
|
||||
{
|
||||
configSetCommand(message[key], config[key], create);
|
||||
}
|
||||
else
|
||||
if ( !config[key].empty() || create)
|
||||
config[key] = message[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(message.size() > 0)
|
||||
{
|
||||
if (message.isObject() && message.isMember("configset"))
|
||||
{
|
||||
std::string errors;
|
||||
if (!checkJson(message["configset"], ":/hyperion-schema", errors, true))
|
||||
{
|
||||
sendErrorReply("Error while validating json: " + errors);
|
||||
return;
|
||||
}
|
||||
|
||||
bool createKey = message.isMember("create");
|
||||
Json::Value hyperionConfig = _hyperion->getJsonConfig();
|
||||
nested::configSetCommand(message["configset"], hyperionConfig, createKey);
|
||||
|
||||
JsonFactory::writeJson(_hyperion->getConfigFileName(), hyperionConfig);
|
||||
|
||||
sendSuccessReply();
|
||||
}
|
||||
} else
|
||||
sendErrorReply("Error while parsing json: Message size " + message.size());
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleComponentStateCommand(const Json::Value& message)
|
||||
{
|
||||
const Json::Value & componentState = message["componentstate"];
|
||||
@ -956,7 +1006,7 @@ void JsonClientConnection::sendErrorReply(const std::string &error)
|
||||
sendMessage(reply);
|
||||
}
|
||||
|
||||
bool JsonClientConnection::checkJson(const Json::Value & message, const QString & schemaResource, std::string & errorMessage)
|
||||
bool JsonClientConnection::checkJson(const Json::Value & message, const QString & schemaResource, std::string & errorMessage, bool ignoreRequired)
|
||||
{
|
||||
// read the json schema from the resource
|
||||
QResource schemaData(schemaResource);
|
||||
@ -974,7 +1024,7 @@ bool JsonClientConnection::checkJson(const Json::Value & message, const QString
|
||||
schema.setSchema(schemaJson);
|
||||
|
||||
// check the message
|
||||
if (!schema.validate(message))
|
||||
if (!schema.validate(message, ignoreRequired))
|
||||
{
|
||||
const std::list<std::string> & errors = schema.getMessages();
|
||||
std::stringstream ss;
|
||||
|
@ -144,6 +144,11 @@ private:
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleConfigGetCommand(const Json::Value & message);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON SetConfig message
|
||||
///
|
||||
void handleConfigSetCommand(const Json::Value & message);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Component State message
|
||||
@ -197,12 +202,13 @@ private:
|
||||
/// Check if a JSON messag is valid according to a given JSON schema
|
||||
///
|
||||
/// @param message JSON message which need to be checked
|
||||
/// @param schemaResource Qt esource identifier with the JSON schema
|
||||
/// @param schemaResource Qt Resource identifier with the JSON schema
|
||||
/// @param errors Output error message
|
||||
/// @param ignoreRequired ignore the required value in JSON schema
|
||||
///
|
||||
/// @return true if message conforms the given JSON schema
|
||||
///
|
||||
bool checkJson(const Json::Value & message, const QString &schemaResource, std::string & errors);
|
||||
bool checkJson(const Json::Value & message, const QString &schemaResource, std::string & errors, bool ignoreRequired = false);
|
||||
|
||||
private:
|
||||
/// The TCP-Socket that is connected tot the Json-client
|
||||
|
@ -13,6 +13,7 @@
|
||||
<file alias="schema-effect">schema/schema-effect.json</file>
|
||||
<file alias="schema-sourceselect">schema/schema-sourceselect.json</file>
|
||||
<file alias="schema-configget">schema/schema-configget.json</file>
|
||||
<file alias="schema-configset">schema/schema-configset.json</file>
|
||||
<file alias="schema-componentstate">schema/schema-componentstate.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
20
libsrc/jsonserver/schema/schema-configset.json
Normal file
20
libsrc/jsonserver/schema/schema-configset.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"type" : "object",
|
||||
"required" : true,
|
||||
"properties" : {
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["configset"]
|
||||
},
|
||||
"configset": {
|
||||
"type" : "object",
|
||||
"required" : true
|
||||
},
|
||||
"create": {
|
||||
"type" : "boolean",
|
||||
"required" : false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature", "adjustment", "sourceselect", "configget", "componentstate"]
|
||||
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature", "adjustment", "sourceselect", "configget", "configset", "componentstate"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,10 @@ bool JsonSchemaChecker::setSchema(const Json::Value & schema)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonSchemaChecker::validate(const Json::Value & value)
|
||||
bool JsonSchemaChecker::validate(const Json::Value & value, bool ignoreRequired)
|
||||
{
|
||||
// initialize state
|
||||
_ignoreRequired = ignoreRequired;
|
||||
_error = false;
|
||||
_messages.clear();
|
||||
_currentPath.clear();
|
||||
@ -201,7 +202,7 @@ void JsonSchemaChecker::checkProperties(const Json::Value & value, const Json::V
|
||||
{
|
||||
validate(value[property], propertyValue);
|
||||
}
|
||||
else if (propertyValue.get("required", false).asBool())
|
||||
else if (propertyValue.get("required", false).asBool() && !_ignoreRequired)
|
||||
{
|
||||
_error = true;
|
||||
setMessage("missing member");
|
||||
|
@ -265,6 +265,29 @@ QString JsonConnection::getConfigFile()
|
||||
return QString();
|
||||
}
|
||||
|
||||
void JsonConnection::setConfigFile(const std::string &jsonString, bool create)
|
||||
{
|
||||
// create command
|
||||
Json::Value command;
|
||||
command["command"] = "configset";
|
||||
command["create"] = create;
|
||||
Json::Value & config = command["configset"];
|
||||
if (jsonString.size() > 0)
|
||||
{
|
||||
Json::Reader reader;
|
||||
if (!reader.parse(jsonString, config, false))
|
||||
{
|
||||
throw std::runtime_error("Error in configset arguments: " + reader.getFormattedErrorMessages());
|
||||
}
|
||||
}
|
||||
|
||||
// send command message
|
||||
Json::Value reply = sendMessage(command);
|
||||
|
||||
// parse reply message
|
||||
parseReply(reply);
|
||||
}
|
||||
|
||||
void JsonConnection::setTransform(std::string * transformId, double * saturation, double * value, double * saturationL, double * luminance, double * luminanceMin, ColorTransformValues *threshold, ColorTransformValues *gamma, ColorTransformValues *blacklevel, ColorTransformValues *whitelevel)
|
||||
{
|
||||
std::cout << "Set color transforms" << std::endl;
|
||||
|
@ -108,6 +108,14 @@ public:
|
||||
///
|
||||
QString getConfigFile();
|
||||
|
||||
///
|
||||
/// Write JSON Value(s) to the actual loaded configuration file
|
||||
///
|
||||
/// @param jsonString The JSON String(s) to write
|
||||
/// @param create Specifies whether the nonexistent json string to be created
|
||||
///
|
||||
void setConfigFile(const std::string & jsonString, bool create);
|
||||
|
||||
///
|
||||
/// Set the color transform of the leds
|
||||
///
|
||||
|
@ -87,7 +87,9 @@ int main(int argc, char * argv[])
|
||||
IntParameter & argSource = parameters.add<IntParameter> (0x0, "sourceSelect" , "Set current active priority channel and deactivate auto source switching");
|
||||
SwitchParameter<> & argSourceAuto = parameters.add<SwitchParameter<> >(0x0, "sourceAutoSelect", "Enables auto source, if disabled prio by manual selecting input source");
|
||||
SwitchParameter<> & argSourceOff = parameters.add<SwitchParameter<> >(0x0, "sourceOff", "select no source, this results in leds activly set to black (=off)");
|
||||
SwitchParameter<> & argConfigGet = parameters.add<SwitchParameter<> >(0x0, "configget" , "Print the current loaded Hyperion configuration file");
|
||||
SwitchParameter<> & argConfigGet = parameters.add<SwitchParameter<> >(0x0, "configGet" , "Print the current loaded Hyperion configuration file");
|
||||
StringParameter & argConfigSet = parameters.add<StringParameter>('W', "configSet", "Write to the actual loaded configuration file. Should be a Json object string.");
|
||||
SwitchParameter<> & argCreate = parameters.add<SwitchParameter<> >(0x0, "createkeys", "Create non exist Json Entry(s) in the actual loaded configuration file. Argument to use in combination with configSet.");
|
||||
|
||||
// set the default values
|
||||
argAddress.setDefault(defaultServerAddress.toStdString());
|
||||
@ -111,7 +113,7 @@ int main(int argc, char * argv[])
|
||||
bool colorModding = colorTransform || colorAdjust || argCorrection.isSet() || argTemperature.isSet();
|
||||
|
||||
// check that exactly one command was given
|
||||
int commandCount = count({argColor.isSet(), argImage.isSet(), argEffect.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), argEnableComponent.isSet(), argDisableComponent.isSet(), colorModding, argSource.isSet(), argSourceAuto.isSet(), argSourceOff.isSet(), argConfigGet.isSet()});
|
||||
int commandCount = count({argColor.isSet(), argImage.isSet(), argEffect.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), argEnableComponent.isSet(), argDisableComponent.isSet(), colorModding, argSource.isSet(), argSourceAuto.isSet(), argSourceOff.isSet(), argConfigGet.isSet(), argConfigSet.isSet()});
|
||||
if (commandCount != 1)
|
||||
{
|
||||
std::cerr << (commandCount == 0 ? "No command found." : "Multiple commands found.") << " Provide exactly one of the following options:" << std::endl;
|
||||
@ -126,6 +128,7 @@ int main(int argc, char * argv[])
|
||||
std::cerr << " " << argSource.usageLine() << std::endl;
|
||||
std::cerr << " " << argSourceAuto.usageLine() << std::endl;
|
||||
std::cerr << " " << argConfigGet.usageLine() << std::endl;
|
||||
std::cerr << " " << argConfigSet.usageLine() << std::endl;
|
||||
std::cerr << "or one or more of the available color modding operations:" << std::endl;
|
||||
std::cerr << " " << argId.usageLine() << std::endl;
|
||||
std::cerr << " " << argSaturation.usageLine() << std::endl;
|
||||
@ -202,6 +205,10 @@ int main(int argc, char * argv[])
|
||||
QString info = connection.getConfigFile();
|
||||
std::cout << "Configuration File:\n" << info.toStdString() << std::endl;
|
||||
}
|
||||
else if (argConfigSet.isSet())
|
||||
{
|
||||
connection.setConfigFile(argConfigSet.getValue(), argCreate.isSet());
|
||||
}
|
||||
else if (colorModding)
|
||||
{
|
||||
if (argCorrection.isSet())
|
||||
|
Loading…
Reference in New Issue
Block a user