Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better documentation about how custom values are represented in JSON. #23965

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions examples/chip-tool/commands/clusters/ClusterCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub
InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig)
{
AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId);
AddArgument("command-id", 0, UINT32_MAX, &mCommandId);
AddArgument("payload", &mPayload);
AddByIdArguments();
AddArguments();
}

ClusterCommand(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig), mClusterId(clusterId)
{
AddArgument("command-id", 0, UINT32_MAX, &mCommandId);
AddArgument("payload", &mPayload);
AddByIdArguments();
AddArguments();
}

Expand Down Expand Up @@ -137,6 +135,41 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub
// Subclasses are responsible for calling AddArguments.
}

void AddByIdArguments()
{
AddArgument("command-id", 0, UINT32_MAX, &mCommandId);
AddArgument("payload", &mPayload,
"The command payload. This should be a JSON-encoded object, with string representations of field ids as keys. "
" The values for the keys are represented as follows, depending on the type:\n"
" * struct: a JSON-encoded object, with field ids as keys.\n"
" * list: a JSON-encoded array of values.\n"
" * null: A literal null.\n"
" * boolean: A literal true or false.\n"
" * unsigned integer: One of:\n"
" a) The number directly, as decimal.\n"
" b) A string starting with \"u:\" followed by decimal digits\n"
" * signed integer: One of:\n"
" a) The number directly, if it's negative.\n"
" b) A string starting with \"s:\" followed by decimal digits\n"
" * single-precision float: A string starting with \"f:\" followed by the number.\n"
" * double-precision float: One of:\n"
" a) The number directly, if it's not an integer.\n"
" b) A string starting with \"d:\" followed by the number.\n"
" * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n"
" * string: A string with the characters.\n"
"\n"
" An example payload may look like this: '{ \"0x0\": { \"0\": null, \"1\": false }, \"1\": [17, \"u:17\"], "
"\"0x2\": [ -17, \"s:17\", \"s:-17\" ], \"0x3\": \"f:2\", \"0x4\": [ \"d:3\", 4.5 ], \"0x5\": \"hex:ab12\", "
"\"0x6\": \"ab12\" }' and represents:\n"
" Field 0: a struct with two fields, one with value null and one with value false.\n"
" Field 1: A list of unsigned integers.\n"
" Field 2: A list of signed integers.\n"
" Field 3: A single-precision float.\n"
" Field 4: A list of double-precision floats.\n"
" Field 5: A 2-byte octet string.\n"
" Field 6: A 4-char character string.");
}

void AddArguments()
{
AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs,
Expand Down
42 changes: 35 additions & 7 deletions examples/chip-tool/commands/clusters/WriteAttributeCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,50 @@ class WriteAttribute : public InteractionModelWriter, public ModelCommand, publi
AddArgument("attribute-name", attributeName, "The attribute name to write.");
}

template <typename minType, typename maxType>
void AddArgumentAttributeValues(minType minValue, maxType maxValue)
template <typename U = T, std::enable_if_t<std::is_same<U, std::vector<CustomArgument *>>::value, int> = 0>
static const char * GetAttributeValuesDescription()
{
AddArgument("attribute-values", minValue, maxValue, &mAttributeValues,
"Comma-separated list of attribute values to write.");
return "Comma-separated list of attribute values to write. Each value is represented as follows, depending on the type:\n"
" * struct: a JSON-encoded object, with field ids as keys.\n"
" * list: a JSON-encoded array of values.\n"
" * null: A literal null.\n"
" * boolean: A literal true or false.\n"
" * unsigned integer: One of:\n"
" a) The number directly, as decimal.\n"
" b) The number directly, as 0x followed by hex digits. (Only for the toplevel value, not inside structs or "
"lists.)\n"
" c) A string starting with \"u:\" followed by decimal digits\n"
" * signed integer: One of:\n"
" a) The number directly, if it's negative.\n"
" c) A string starting with \"s:\" followed by decimal digits\n"
" * single-precision float: A string starting with \"f:\" followed by the number.\n"
" * double-precision float: One of:\n"
" a) The number directly, if it's not an integer.\n"
" b) A string starting with \"d:\" followed by the number.\n"
" * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n"
" * string: A string with the characters.";
}

void AddArgumentAttributeValues()
static const char * GetTypedAttributeValuesDescription() { return "Comma-separated list of attribute values to write."; }

template <typename U = T, std::enable_if_t<!std::is_same<U, std::vector<CustomArgument *>>::value, int> = 0>
static const char * GetAttributeValuesDescription()
{
AddArgument("attribute-values", &mAttributeValues, "Comma-separated list of attribute values to write.");
return GetTypedAttributeValuesDescription();
}

template <typename minType, typename maxType>
void AddArgumentAttributeValues(minType minValue, maxType maxValue)
{
AddArgument("attribute-values", minValue, maxValue, &mAttributeValues, GetTypedAttributeValuesDescription());
}

void AddArgumentAttributeValues() { AddArgument("attribute-values", &mAttributeValues, GetAttributeValuesDescription()); }

void AddArgumentAttributeValues(TypedComplexArgument<T> & attributeParser)
{
attributeParser.SetArgument(&mAttributeValues);
AddArgument("attribute-values", &attributeParser, "Comma-separated list of attribute values to write.");
AddArgument("attribute-values", &attributeParser, GetTypedAttributeValuesDescription());
}

void AddArguments()
Expand Down