add command for getting schema via json api (#179)

* - update coding style
- add command for getting schema via json api
- json api: merge config commands into one single "config" command with subcommands

* make setconfig work
This commit is contained in:
redPanther 2016-08-15 22:32:01 +02:00 committed by GitHub
parent 75fd7ed8ba
commit 8e8c21fa3b
11 changed files with 183 additions and 90 deletions

View File

@ -3,17 +3,47 @@
- use QT wherever it's possible (except there is a good reason)
- use unix line endings (not windows)
- indent your code with TABs instead of spaces
- your files should end with a newline
- names are camel case
- use utf8 file encoding (ANSI encoding is strictly forbidden!)
- use speaking names for variables.
- avoid code dups -> if you write similar code blocks more the 2 times -> refactoring!
- avoid compiler macros (#ifdef #define ...) where possible
- class member variables must prefixed with underscore `int _myMemberVar`
- follow this rule for curly brackets
```
bad:
if (conditon) {
code
code
}
good:
if (condition)
{
code
code
}
```
- initializer list on constructors:
```
bad:
MyClass::MyClass()
: myVarA(0), myVarB("eee"), myVarC(true)
{
}
```
MyClass::MyClass() : myVarA(0),
myVarB("eee"),
myVarC(true)
{
}
good:
MyClass::MyClass()
: myVarA(0),
, myVarB("eee")
, myVarC(true)
{
}
```

View File

@ -14,6 +14,7 @@
#include <QCryptographicHash>
#include <QHostInfo>
#include <QString>
#include <QFile>
// hyperion util includes
#include <hyperion/ImageProcessorFactory.h>
@ -266,10 +267,8 @@ void JsonClientConnection::handleMessage(const std::string &messageString)
handleAdjustmentCommand(message);
else if (command == "sourceselect")
handleSourceSelectCommand(message);
else if (command == "configget")
handleConfigGetCommand(message);
else if (command == "configset")
handleConfigSetCommand(message);
else if (command == "config")
handleConfigCommand(message);
else if (command == "componentstate")
handleComponentStateCommand(message);
else
@ -833,7 +832,28 @@ void JsonClientConnection::handleSourceSelectCommand(const Json::Value & message
}
}
void JsonClientConnection::handleConfigGetCommand(const Json::Value &)
void JsonClientConnection::handleConfigCommand(const Json::Value & message)
{
std::string subcommand = message.get("subcommand","").asString();
if (subcommand == "getschema")
{
handleSchemaGetCommand(message);
}
else if (subcommand == "getconfig")
{
handleConfigGetCommand(message);
}
else if (subcommand == "setconfig")
{
handleConfigSetCommand(message);
}
else
{
sendErrorReply("unknown or missing subcommand");
}
}
void JsonClientConnection::handleConfigGetCommand(const Json::Value & message)
{
// create result
Json::Value result;
@ -845,6 +865,30 @@ void JsonClientConnection::handleConfigGetCommand(const Json::Value &)
sendMessage(result);
}
void JsonClientConnection::handleSchemaGetCommand(const Json::Value & message)
{
// create result
Json::Value result;
result["success"] = true;
Json::Value & schemaJson = result["result"];
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE(resource);
// read the json schema from the resource
QResource schemaData(":/hyperion-schema");
assert(schemaData.isValid());
Json::Reader jsonReader;
if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false))
{
throw std::runtime_error("ERROR: Json schema wrong: " + jsonReader.getFormattedErrorMessages()) ;
}
// send the result
sendMessage(result);
}
void JsonClientConnection::handleConfigSetCommand(const Json::Value &message)
{
struct nested
@ -871,10 +915,10 @@ void JsonClientConnection::handleConfigSetCommand(const Json::Value &message)
if(message.size() > 0)
{
if (message.isObject() && message.isMember("configset"))
if (message.isObject() && message.isMember("config"))
{
std::string errors;
if (!checkJson(message["configset"], ":/hyperion-schema", errors, true))
if (!checkJson(message["config"], ":/hyperion-schema", errors, true))
{
sendErrorReply("Error while validating json: " + errors);
return;
@ -882,7 +926,7 @@ void JsonClientConnection::handleConfigSetCommand(const Json::Value &message)
bool createKey = message.isMember("create");
Json::Value hyperionConfig = _hyperion->getJsonConfig();
nested::configSetCommand(message["configset"], hyperionConfig, createKey);
nested::configSetCommand(message["config"], hyperionConfig, createKey);
JsonFactory::writeJson(_hyperion->getConfigFileName(), hyperionConfig);

View File

@ -139,6 +139,18 @@ private:
///
void handleSourceSelectCommand(const Json::Value & message);
/// Handle an incoming JSON GetConfig message
///
/// @param message the incoming message
///
void handleConfigCommand(const Json::Value & message);
/// Handle an incoming JSON GetConfig message
///
/// @param message the incoming message
///
void handleSchemaGetCommand(const Json::Value & message);
/// Handle an incoming JSON GetConfig message
///
/// @param message the incoming message

View File

@ -12,8 +12,7 @@
<file alias="schema-adjustment">schema/schema-adjustment.json</file>
<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-config">schema/schema-config.json</file>
<file alias="schema-componentstate">schema/schema-componentstate.json</file>
</qresource>
</RCC>

View File

@ -0,0 +1,23 @@
{
"type":"object",
"required":true,
"properties":{
"command": {
"type" : "string",
"required" : true,
"enum" : ["config"]
},
"subcommand": {
"type" : "string",
"required" : true,
"enum" : ["getconfig","setconfig","getschema"]
},
"config": {
"type" : "object"
},
"create": {
"type" : "boolean"
}
},
"additionalProperties": false
}

View File

@ -1,12 +0,0 @@
{
"type":"object",
"required":true,
"properties":{
"command": {
"type" : "string",
"required" : true,
"enum" : ["configget"]
}
},
"additionalProperties": false
}

View File

@ -1,20 +0,0 @@
{
"type" : "object",
"required" : true,
"properties" : {
"command": {
"type" : "string",
"required" : true,
"enum" : ["configset"]
},
"configset": {
"type" : "object",
"required" : true
},
"create": {
"type" : "boolean",
"required" : false
}
},
"additionalProperties": false
}

View File

@ -5,7 +5,7 @@
"command": {
"type" : "string",
"required" : true,
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature", "adjustment", "sourceselect", "configget", "configset", "componentstate"]
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature", "adjustment", "sourceselect", "config", "componentstate"]
}
}
}

View File

@ -1,5 +1,6 @@
// stl includes
#include <stdexcept>
#include <cassert>
// Qt includes
#include <QRgb>
@ -239,13 +240,15 @@ void JsonConnection::setSourceAutoSelect()
parseReply(reply);
}
QString JsonConnection::getConfigFile()
QString JsonConnection::getConfig(std::string type)
{
assert( type == "schema" || type == "config" );
std::cout << "Get configuration file from Hyperion Server" << std::endl;
// create command
Json::Value command;
command["command"] = "configget";
command["command"] = "config";
command["subcommand"] = (type == "schema")? "getschema" : "getconfig";
// send command message
Json::Value reply = sendMessage(command);
@ -265,13 +268,15 @@ QString JsonConnection::getConfigFile()
return QString();
}
void JsonConnection::setConfigFile(const std::string &jsonString, bool create)
void JsonConnection::setConfig(const std::string &jsonString, bool create)
{
// create command
Json::Value command;
command["command"] = "configset";
command["command"] = "config";
command["subcommand"] = "setconfig";
command["create"] = create;
Json::Value & config = command["configset"];
Json::Value & config = command["config"];
if (jsonString.size() > 0)
{
Json::Reader reader;

View File

@ -106,7 +106,7 @@ public:
///
/// Print the current loaded Hyperion configuration file
///
QString getConfigFile();
QString getConfig(std::string type);
///
/// Write JSON Value(s) to the actual loaded configuration file
@ -114,7 +114,7 @@ public:
/// @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);
void setConfig(const std::string & jsonString, bool create);
///
/// Set the color transform of the leds

View File

@ -52,44 +52,45 @@ int main(int argc, char * argv[])
// create the option parser and initialize all parameters
OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface");
ParameterSet & parameters = optionParser.getParameters();
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toLatin1().constData());
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toLatin1().constData());
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB)");
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
StringParameter & argEffect = parameters.add<StringParameter> ('e', "effect" , "Enable the effect with the given name");
StringParameter & argEffectArgs = parameters.add<StringParameter> (0x0, "effectArgs", "Arguments to use in combination with the specified effect. Should be a Json object string.");
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info and active effects with priority and duration");
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
StringParameter & argEnableComponent = parameters.add<StringParameter> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argDisableComponent = parameters.add<StringParameter> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argId = parameters.add<StringParameter> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "!DEPRECATED! Will be removed soon! Set the HSV saturation gain of the leds");
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value" , "!DEPRECATED! Will be removed soon! Set the HSV value gain of the leds");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toLatin1().constData());
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toLatin1().constData());
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB)");
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
StringParameter & argEffect = parameters.add<StringParameter> ('e', "effect" , "Enable the effect with the given name");
StringParameter & argEffectArgs = parameters.add<StringParameter> (0x0, "effectArgs", "Arguments to use in combination with the specified effect. Should be a Json object string.");
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info and active effects with priority and duration");
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
StringParameter & argEnableComponent = parameters.add<StringParameter> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argDisableComponent = parameters.add<StringParameter> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argId = parameters.add<StringParameter> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "!DEPRECATED! Will be removed soon! Set the HSV saturation gain of the leds");
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value" , "!DEPRECATED! Will be removed soon! Set the HSV value gain of the leds");
DoubleParameter & argSaturationL = parameters.add<DoubleParameter> ('u', "saturationL", "Set the HSL saturation gain of the leds");
DoubleParameter & argLuminance = parameters.add<DoubleParameter> ('m', "luminance" , "Set the HSL luminance gain of the leds");
DoubleParameter & argLuminanceMin= parameters.add<DoubleParameter> ('n', "luminanceMin" , "Set the HSL luminance minimum of the leds (backlight)");
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "!DEPRECATED! Will be removed soon! Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "!DEPRECATED! Will be removed soon! Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
SwitchParameter<> & argPrint = parameters.add<SwitchParameter<> >(0x0, "print" , "Print the json input and output messages on stdout");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help" , "Show this help message and exit");
StringParameter & argIdC = parameters.add<StringParameter> ('y', "qualifier" , "!DEPRECATED! Will be removed soon! Identifier(qualifier) of the correction to set");
CorrectionParameter & argCorrection= parameters.add<CorrectionParameter>('Y', "correction" , "!DEPRECATED! Will be removed soon! Set the correction of the leds (requires 3 space seperated values between 0 and 255)");
StringParameter & argIdT = parameters.add<StringParameter> ('z', "qualifier" , "Identifier(qualifier) of the temperature correction to set");
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "!DEPRECATED! Will be removed soon! Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "!DEPRECATED! Will be removed soon! Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
SwitchParameter<> & argPrint = parameters.add<SwitchParameter<> >(0x0, "print" , "Print the json input and output messages on stdout");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help" , "Show this help message and exit");
StringParameter & argIdC = parameters.add<StringParameter> ('y', "qualifier" , "!DEPRECATED! Will be removed soon! Identifier(qualifier) of the correction to set");
CorrectionParameter & argCorrection = parameters.add<CorrectionParameter>('Y', "correction" , "!DEPRECATED! Will be removed soon! Set the correction of the leds (requires 3 space seperated values between 0 and 255)");
StringParameter & argIdT = parameters.add<StringParameter> ('z', "qualifier" , "Identifier(qualifier) of the temperature correction to set");
CorrectionParameter & argTemperature= parameters.add<CorrectionParameter>('Z', "temperature" , "Set the temperature correction of the leds (requires 3 space seperated values between 0 and 255)");
StringParameter & argIdA = parameters.add<StringParameter> ('j', "qualifier" , "Identifier(qualifier) of the adjustment to set");
AdjustmentParameter & argRAdjust = parameters.add<AdjustmentParameter>('R', "redAdjustment" , "Set the adjustment of the red color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argGAdjust = parameters.add<AdjustmentParameter>('G', "greenAdjustment", "Set the adjustment of the green color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argBAdjust = parameters.add<AdjustmentParameter>('B', "blueAdjustment", "Set the adjustment of the blue color (requires 3 space seperated values between 0 and 255)");
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)");
StringParameter & argIdA = parameters.add<StringParameter> ('j', "qualifier" , "Identifier(qualifier) of the adjustment to set");
AdjustmentParameter & argRAdjust = parameters.add<AdjustmentParameter>('R', "redAdjustment" , "Set the adjustment of the red color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argGAdjust = parameters.add<AdjustmentParameter>('G', "greenAdjustment", "Set the adjustment of the green color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argBAdjust = parameters.add<AdjustmentParameter>('B', "blueAdjustment", "Set the adjustment of the blue color (requires 3 space seperated values between 0 and 255)");
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");
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.");
SwitchParameter<> & argSchemaGet = parameters.add<SwitchParameter<> >(0x0, "schemaGet" , "Print the json schema for Hyperion configuration");
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());
@ -113,7 +114,12 @@ 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(), argConfigSet.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(), argSchemaGet.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;
@ -128,6 +134,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 << " " << argSchemaGet.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;
@ -202,12 +209,17 @@ int main(int argc, char * argv[])
}
else if (argConfigGet.isSet())
{
QString info = connection.getConfigFile();
std::cout << "Configuration File:\n" << info.toStdString() << std::endl;
QString info = connection.getConfig("config");
std::cout << "Configuration:\n" << info.toStdString() << std::endl;
}
else if (argSchemaGet.isSet())
{
QString info = connection.getConfig("schema");
std::cout << "Configuration Schema\n" << info.toStdString() << std::endl;
}
else if (argConfigSet.isSet())
{
connection.setConfigFile(argConfigSet.getValue(), argCreate.isSet());
connection.setConfig(argConfigSet.getValue(), argCreate.isSet());
}
else if (colorModding)
{