added all devices - API: HTTP read/write #506

This commit is contained in:
proddy
2020-09-20 15:52:44 +02:00
parent 22fcff6682
commit 9fc15650a2
35 changed files with 742 additions and 425 deletions

View File

@@ -29,12 +29,15 @@ std::vector<Command::CmdFunction> Command::cmdfunctions_;
// calls a command, context is the device_type
// id may be used to represent a heating circuit for example
// returns false if error or not found
bool Command::call_command(const uint8_t device_type, const char * cmd, const char * value, const int8_t id) {
bool Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & output) {
#ifdef EMSESP_DEBUG
if (id == -1) {
LOG_DEBUG(F("[DEBUG] Calling command %s, value %s, id is default"), cmd, value);
std::string dname = EMSdevice::device_type_2_device_name(device_type);
if (value == nullptr) {
LOG_DEBUG(F("[DEBUG] Calling command %s in %s"), cmd, dname.c_str());
} else if (id == -1) {
LOG_DEBUG(F("[DEBUG] Calling command %s, value %s, id is default in %s"), cmd, value, dname.c_str());
} else {
LOG_DEBUG(F("[DEBUG] Calling command %s, value %s, id is %d"), cmd, value, id);
LOG_DEBUG(F("[DEBUG] Calling command %s, value %s, id is %d in %s"), cmd, value, id, dname.c_str());
}
#endif
@@ -42,23 +45,37 @@ bool Command::call_command(const uint8_t device_type, const char * cmd, const ch
for (const auto & cf : cmdfunctions_) {
if (cf.device_type_ == device_type) {
const char * cf_cmd = uuid::read_flash_string(cf.cmd_).c_str();
// find a matching command and call it
if (strcmp(cf_cmd, cmd) == 0) {
return ((cf.cmdfunction_)(value, id)); // call function, data needs to be a string and can be null
if (cf.cmdfunction_json_) {
// check if json object is empty, if so quit
if (output.isNull()) {
LOG_WARNING(F("Ignore call for command %s in %s because no json"), cmd, EMSdevice::device_type_2_device_name(device_type).c_str());
}
return ((cf.cmdfunction_json_)(value, id, output));
} else {
return ((cf.cmdfunction_)(value, id));
}
}
}
}
}
return false;
return false; // command not found
}
// add a command to the list
void Command::add_command(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb) {
cmdfunctions_.emplace_back(device_type, device_id, cmd, cb);
// add a command to the list, which does not return json
void Command::add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb) {
cmdfunctions_.emplace_back(device_type, cmd, cb, nullptr);
// see if we need to subscribe
Mqtt::register_command(device_type, device_id, cmd, cb);
}
// add a command to the list, which does return json object as output
void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb) {
cmdfunctions_.emplace_back(device_type, cmd, nullptr, cb);
}
// see if a command exists for that device type
bool Command::find(const uint8_t device_type, const char * cmd) {
for (const auto & cf : cmdfunctions_) {
@@ -70,7 +87,7 @@ bool Command::find(const uint8_t device_type, const char * cmd) {
}
// output list of all commands to console for a specific DeviceType
void Command::show_commands(uuid::console::Shell & shell, uint8_t device_type) {
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
for (const auto & cf : Command::commands()) {
if (cf.device_type_ == device_type) {
shell.printf("%s ", uuid::read_flash_string(cf.cmd_).c_str());
@@ -81,9 +98,9 @@ void Command::show_commands(uuid::console::Shell & shell, uint8_t device_type) {
// determines the device_type from the shell context we're in
uint8_t Command::context_2_device_type(unsigned int context) {
if (context == ShellContext::MAIN) {
return EMSdevice::DeviceType::SERVICEKEY;
}
// if (context == ShellContext::MAIN) {
// return EMSdevice::DeviceType::SERVICEKEY;
// }
if (context == ShellContext::BOILER) {
return EMSdevice::DeviceType::BOILER;
}
@@ -99,34 +116,36 @@ uint8_t Command::context_2_device_type(unsigned int context) {
if (context == ShellContext::THERMOSTAT) {
return EMSdevice::DeviceType::THERMOSTAT;
}
if (context == ShellContext::SENSOR) {
return EMSdevice::DeviceType::SENSOR;
}
return EMSdevice::DeviceType::UNKNOWN; // unknown type
}
// show command per current context
void Command::show_commands(uuid::console::Shell & shell) {
show_commands(shell, context_2_device_type(shell.context()));
void Command::show(uuid::console::Shell & shell) {
show(shell, context_2_device_type(shell.context()));
}
// output list of all commands to console
void Command::show_all_commands(uuid::console::Shell & shell) {
void Command::show_all(uuid::console::Shell & shell) {
// show system first
shell.printf("%s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SERVICEKEY).c_str());
show_commands(shell, EMSdevice::DeviceType::SERVICEKEY);
show(shell, EMSdevice::DeviceType::SERVICEKEY);
// do this in the order of factory classes to keep a consistent order when displaying
for (const auto & device_class : EMSFactory::device_handlers()) {
for (const auto & emsdevice : EMSESP::emsdevices) {
if ((emsdevice) && (emsdevice->device_type() == device_class.first)) {
shell.printf("%s: ", EMSdevice::device_type_2_device_name(device_class.first).c_str());
show_commands(shell, device_class.first);
show(shell, device_class.first);
}
}
}
}
// given a context, automatically add the commands to the console
// Add the console 'call' command to the given context
void Command::add_context_commands(unsigned int context) {
// if we're adding commands for a thermostat or mixing, then include an additional optional paramter called heating circuit
flash_string_vector params;
@@ -147,7 +166,7 @@ void Command::add_context_commands(unsigned int context) {
if (arguments.empty()) {
// list options
shell.print("Available commands: ");
show_commands(shell);
show(shell);
shell.println();
return;
}
@@ -155,16 +174,35 @@ void Command::add_context_commands(unsigned int context) {
// determine the device_type from the shell context
uint8_t device_type = context_2_device_type(shell.context());
// validate the command
const char * cmd = arguments[0].c_str();
if (!find(device_type, cmd)) {
shell.print(F("Unknown command. Available commands are: "));
show(shell);
shell.println();
return;
}
DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE);
JsonObject output = doc.to<JsonObject>();
bool ok = false;
if (arguments.size() == 1) {
// no value specified
(void)Command::call_command(device_type, cmd, nullptr, -1);
// no value specified, just the cmd
ok = Command::call(device_type, cmd, nullptr, -1, output);
} else if (arguments.size() == 2) {
// has a value but no id
(void)Command::call_command(device_type, cmd, arguments.back().c_str(), -1);
ok = Command::call(device_type, cmd, arguments.back().c_str(), -1, output);
} else {
// use value, which could be an id or hc
(void)Command::call_command(device_type, cmd, arguments[1].c_str(), atoi(arguments[2].c_str()));
ok = Command::call(device_type, cmd, arguments[1].c_str(), atoi(arguments[2].c_str()), output);
}
if (ok) {
shell.print(F("output: "));
serializeJson(doc, shell);
shell.println();
shell.println();
}
},
[&](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) -> std::vector<std::string> {
@@ -182,5 +220,4 @@ void Command::add_context_commands(unsigned int context) {
});
}
} // namespace emsesp