added new command called commands

This commit is contained in:
proddy
2021-05-09 10:58:44 +02:00
parent 4a06d328d6
commit 81f4724d71
9 changed files with 157 additions and 51 deletions

View File

@@ -43,11 +43,11 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val
#ifdef EMSESP_DEBUG
if (value == nullptr) {
LOG_DEBUG(F("[DEBUG] Calling %s command %s"), dname.c_str(), cmd);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s'"), dname.c_str(), cmd);
} else if (id == -1) {
LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is default"), dname.c_str(), cmd, value);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s', value %s, id is default"), dname.c_str(), cmd, value);
} else {
LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is %d"), dname.c_str(), cmd, value, id);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s', value %s, id is %d"), dname.c_str(), cmd, value, id);
}
#endif
@@ -67,11 +67,11 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val
#ifdef EMSESP_DEBUG
std::string dname = EMSdevice::device_type_2_device_name(device_type);
if (value == nullptr) {
LOG_DEBUG(F("[DEBUG] Calling %s command %s"), dname.c_str(), cmd);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s'"), dname.c_str(), cmd);
} else if (id == -1) {
LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is default"), dname.c_str(), cmd, value);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s', value %s, id is default"), dname.c_str(), cmd, value);
} else {
LOG_DEBUG(F("[DEBUG] Calling %s command %s, value %s, id is %d"), dname.c_str(), cmd, value, id);
LOG_DEBUG(F("[DEBUG] Calling %s command '%s', value %s, id is %d"), dname.c_str(), cmd, value, id);
}
#endif
@@ -125,13 +125,16 @@ char * Command::check_command(char * out, const char * cmd, int8_t & id) {
}
// add a command to the list, which does not return json
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, uint8_t flag) {
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, const __FlashStringHelper * description, uint8_t flag) {
// if the command already exists for that device type don't add it
if (find_command(device_type, uuid::read_flash_string(cmd).c_str()) != nullptr) {
return;
}
cmdfunctions_.emplace_back(device_type, flag, cmd, cb, nullptr);
// if the description is empty, it's hidden which means it will not show up in Web or Console as an available command
bool hidden = (description == nullptr);
cmdfunctions_.emplace_back(device_type, flag, cmd, cb, nullptr, description, hidden); // callback for json is nullptr
// see if we need to subscribe
if (Mqtt::enabled()) {
@@ -140,14 +143,15 @@ void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, cm
}
// add a command to the list, which does return json object as output
// flag is fixed
// optional parameter hidden for commands that will not show up on the Console
void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb, bool hidden) {
void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb, const __FlashStringHelper * description, bool hidden) {
// if the command already exists for that device type don't add it
if (find_command(device_type, uuid::read_flash_string(cmd).c_str()) != nullptr) {
return;
}
cmdfunctions_.emplace_back(device_type, MqttSubFlag::FLAG_NOSUB, cmd, nullptr, cb, hidden); // add command
cmdfunctions_.emplace_back(device_type, MqttSubFlag::FLAG_NOSUB, cmd, nullptr, cb, description, hidden); // callback for json is included
}
// see if a command exists for that device type
@@ -173,25 +177,78 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ch
return nullptr; // command not found
}
// output list of all commands to console for a specific DeviceType
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
// list all commands for a specific device, output as json
bool Command::list(const uint8_t device_type, JsonObject & json) {
if (cmdfunctions_.empty()) {
shell.println(F("No commands available"));
json["message"] = "no commands available";
return false;
}
// create a list of commands, sort them, print them
// create a list of commands, sort them
std::list<std::string> sorted_cmds;
for (const auto & cf : cmdfunctions_) {
if ((cf.device_type_ == device_type) && !cf.hidden_) {
sorted_cmds.push_back(uuid::read_flash_string(cf.cmd_));
}
}
sorted_cmds.sort();
for (auto & cl : sorted_cmds) {
for (const auto & cf : cmdfunctions_) {
if ((cf.device_type_ == device_type) && !cf.hidden_ && cf.description_ && (cl == uuid::read_flash_string(cf.cmd_))) {
json[cl] = cf.description_;
}
}
}
return true;
}
// output list of all commands to console for a specific DeviceType
void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbose) {
if (cmdfunctions_.empty()) {
shell.println(F("No commands available"));
return;
}
// create a list of commands, sort them
std::list<std::string> sorted_cmds;
for (const auto & cf : cmdfunctions_) {
if ((cf.device_type_ == device_type) && !cf.hidden_) {
sorted_cmds.push_back(uuid::read_flash_string(cf.cmd_));
}
}
sorted_cmds.sort();
// if not in verbose mode, just print them on a single line
if (!verbose) {
for (auto & cl : sorted_cmds) {
shell.print(cl);
shell.print(" ");
}
shell.println();
return;
}
// verbose mode
shell.println();
for (auto & cl : sorted_cmds) {
shell.print(" ");
shell.print(cl);
// find and print the description
for (const auto & cf : cmdfunctions_) {
if ((cf.device_type_ == device_type) && !cf.hidden_ && cf.description_ && (cl == uuid::read_flash_string(cf.cmd_))) {
// pad with spaces
for (uint8_t i = cl.length(); i++ < 22;) {
shell.print(' ');
}
shell.print(COLOR_BRIGHT_CYAN);
shell.print(uuid::read_flash_string(cf.description_));
shell.print(COLOR_RESET);
}
}
shell.println();
}
shell.println();
}
@@ -244,24 +301,31 @@ void Command::show_devices(uuid::console::Shell & shell) {
}
// output list of all commands to console
// calls show with verbose mode set
void Command::show_all(uuid::console::Shell & shell) {
shell.println(F("Available commands per device: "));
// show system first
shell.print(COLOR_BOLD_ON);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM).c_str());
show(shell, EMSdevice::DeviceType::SYSTEM);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::SYSTEM, true);
// show sensor
if (EMSESP::have_sensors()) {
shell.print(COLOR_BOLD_ON);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR).c_str());
show(shell, EMSdevice::DeviceType::DALLASSENSOR);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::DALLASSENSOR, true);
}
// do this in the order of factory classes to keep a consistent order when displaying
for (const auto & device_class : EMSFactory::device_handlers()) {
if (Command::device_has_commands(device_class.first)) {
shell.print(COLOR_BOLD_ON);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(device_class.first).c_str());
show(shell, device_class.first);
shell.print(COLOR_RESET);
show(shell, device_class.first, true);
}
}
}

View File

@@ -45,6 +45,7 @@ class Command {
const __FlashStringHelper * cmd_;
cmdfunction_p cmdfunction_;
cmdfunction_json_p cmdfunction_json_;
const __FlashStringHelper * description_;
bool hidden_; // if its command not to be shown on the Console
CmdFunction(const uint8_t device_type,
@@ -52,12 +53,14 @@ class Command {
const __FlashStringHelper * cmd,
cmdfunction_p cmdfunction,
cmdfunction_json_p cmdfunction_json,
const __FlashStringHelper * description,
bool hidden = false)
: device_type_(device_type)
, flag_(flag)
, cmd_(cmd)
, cmdfunction_(cmdfunction)
, cmdfunction_json_(cmdfunction_json)
, description_(description)
, hidden_(hidden) {
}
};
@@ -68,16 +71,19 @@ class Command {
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json);
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id = 0);
static void add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, uint8_t flag = 0);
static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb, bool hidden = false);
static void add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, const __FlashStringHelper * description, uint8_t flag = 0);
static void
add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb, const __FlashStringHelper * description, bool hidden = false);
static void show_all(uuid::console::Shell & shell);
static Command::CmdFunction * find_command(const uint8_t device_type, const char * cmd);
static char * check_command(char * out, const char * cmd, int8_t & id);
static void show(uuid::console::Shell & shell, uint8_t device_type);
static void show(uuid::console::Shell & shell, uint8_t device_type, bool verbose);
static void show_devices(uuid::console::Shell & shell);
static bool device_has_commands(const uint8_t device_type);
static bool list(const uint8_t device_type, JsonObject & json);
private:
static uuid::log::Logger logger_;

View File

@@ -40,10 +40,17 @@ void DallasSensor::start() {
#ifndef EMSESP_STANDALONE
bus_.begin(dallas_gpio_);
#endif
// API call
Command::add_with_json(EMSdevice::DeviceType::DALLASSENSOR, F_(info), [&](const char * value, const int8_t id, JsonObject & json) {
return command_info(value, id, json);
});
// API calls
Command::add_with_json(
EMSdevice::DeviceType::DALLASSENSOR,
F_(info),
[&](const char * value, const int8_t id, JsonObject & json) { return command_info(value, id, json); },
F_(info_cmd));
Command::add_with_json(
EMSdevice::DeviceType::DALLASSENSOR,
F_(commands),
[&](const char * value, const int8_t id, JsonObject & json) { return command_commands(value, id, json); },
F_(commands_cmd));
}
}
@@ -306,6 +313,11 @@ bool DallasSensor::updated_values() {
return false;
}
// list commands
bool DallasSensor::command_commands(const char * value, const int8_t id, JsonObject & json) {
return Command::list(EMSdevice::DeviceType::DALLASSENSOR, json);
}
// creates JSON doc from values
// returns false if empty
// e.g. dallassensor_data = {"sensor1":{"id":"28-EA41-9497-0E03-5F","temp":23.30},"sensor2":{"id":"28-233D-9497-0C03-8B","temp":24.0}}
@@ -413,7 +425,6 @@ void DallasSensor::publish_values(const bool force) {
sensor_no++; // increment sensor count
}
// doc.shrinkToFit();
Mqtt::publish(F("dallassensor_data"), doc.as<JsonObject>());
}

View File

@@ -113,6 +113,7 @@ class DallasSensor {
uint64_t get_id(const uint8_t addr[]);
bool command_info(const char * value, const int8_t id, JsonObject & json);
bool command_commands(const char * value, const int8_t id, JsonObject & json);
uint32_t last_activity_ = uuid::get_uptime();
uint32_t last_publish_ = uuid::get_uptime();

View File

@@ -968,18 +968,31 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std::
return true;
}
Command::add_with_json(device_type, F_(info), [device_type](const char * value, const int8_t id, JsonObject & json) {
return command_info(device_type, json, id, true);
});
Command::add_with_json(
device_type,
F_(info),
[device_type](const char * value, const int8_t id, JsonObject & json) { return command_info(device_type, json, id, true); },
F_(info_cmd));
Command::add_with_json(
device_type,
F("info_short"),
[device_type](const char * value, const int8_t id, JsonObject & json) { return command_info(device_type, json, id, false); },
nullptr,
true); // this command is hidden
Command::add_with_json(
device_type,
F_(commands),
[device_type](const char * value, const int8_t id, JsonObject & json) { return command_commands(device_type, json, id); },
F_(commands_cmd));
return true;
}
// list all available commands, return as json
bool EMSESP::command_commands(uint8_t device_type, JsonObject & json, const int8_t id) {
return Command::list(device_type, json);
}
// export all values to info command
// value is ignored here
// info command always shows in verbose mode, so full names are displayed

View File

@@ -216,6 +216,7 @@ class EMSESP {
static void publish_response(std::shared_ptr<const Telegram> telegram);
static void publish_all_loop();
static bool command_info(uint8_t device_type, JsonObject & json, const int8_t id, bool verbose = true);
static bool command_commands(uint8_t device_type, JsonObject & json, const int8_t id);
static constexpr uint32_t EMS_FETCH_FREQUENCY = 60000; // check every minute
static uint32_t last_fetch_;

View File

@@ -135,6 +135,10 @@ MAKE_PSTR(new_password_prompt2, "Retype new password: ")
MAKE_PSTR(password_prompt, "Password: ")
MAKE_PSTR(unset, "<unset>")
// command descriptions
MAKE_PSTR(info_cmd, "list all values")
MAKE_PSTR(commands_cmd, "list all commands")
MAKE_PSTR_WORD(number)
MAKE_PSTR_WORD(enum)
MAKE_PSTR_WORD(text)
@@ -336,8 +340,8 @@ MAKE_PSTR_LIST(ID, F_(id))
// Boiler
// extra commands, no output
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"))
MAKE_PSTR_LIST(reset, F("reset"))
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"), F("turn on/off DHW by going into maintenance mode"))
MAKE_PSTR_LIST(reset, F("reset"), F("reset messages"))
// single mqtt topics
MAKE_PSTR_WORD(heating_active)
@@ -376,7 +380,7 @@ MAKE_PSTR_LIST(boilHystOff, F("boilhystoff"), F("hysteresis off temperature"))
MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("set flow temperature"))
MAKE_PSTR_LIST(setBurnPow, F("setburnpow"), F("burner set power"))
MAKE_PSTR_LIST(curBurnPow, F("curburnpow"), F("burner current power"))
MAKE_PSTR_LIST(burnStarts, F("burnstarts"), F("burner # starts"))
MAKE_PSTR_LIST(burnStarts, F("burnstarts"), F("# burner starts"))
MAKE_PSTR_LIST(burnWorkMin, F("burnworkmin"), F("total burner operating time"))
MAKE_PSTR_LIST(heatWorkMin, F("heatworkmin"), F("total heat operating time"))
MAKE_PSTR_LIST(UBAuptime, F("ubauptime"), F("total UBA operating time"))
@@ -409,7 +413,7 @@ MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("auxiliary ele
MAKE_PSTR_LIST(hpPower, F("hppower"), F("heatpump power"))
MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("water temperature condenser inlet (TC0)"))
MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("water temperture condenser output (TC1)"))
MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("water temperature condenser output (TC1)"))
MAKE_PSTR_LIST(hpTc3, F("hptc3"), F("condenser temperature (TC3)"))
MAKE_PSTR_LIST(hpTr3, F("hptr3"), F("refrigerant temperature liquid side (condenser output) (TR3)"))
MAKE_PSTR_LIST(hpTr4, F("hptr4"), F("evaporator inlet temperature (TR4)"))
@@ -429,7 +433,7 @@ MAKE_PSTR_LIST(wWMaxPower, F("wwmaxpower"), F("max power"))
MAKE_PSTR_LIST(wWCircPump, F("wwcircpump"), F("circulation pump available"))
MAKE_PSTR_LIST(wWChargeType, F("wwchargetype"), F("charging type"))
MAKE_PSTR_LIST(wWDisinfectionTemp, F("wwdisinfectiontemp"), F("disinfection temperature"))
MAKE_PSTR_LIST(wWCircMode, F("wwcircmode"), F("circulation pump freq"))
MAKE_PSTR_LIST(wWCircMode, F("wwcircmode"), F("circulation pump frequency"))
MAKE_PSTR_LIST(wWCirc, F("wwcirc"), F("circulation active"))
MAKE_PSTR_LIST(wWCurTemp, F("wwcurtemp"), F("current intern temperature"))
MAKE_PSTR_LIST(wWCurTemp2, F("wwcurtemp2"), F("current extern temperature"))
@@ -444,7 +448,7 @@ MAKE_PSTR_LIST(wWRecharging, F("wwrecharging"), F("recharging"))
MAKE_PSTR_LIST(wWTempOK, F("wwtempok"), F("temperature ok"))
MAKE_PSTR_LIST(wWActive, F("wwactive"), F("active"))
MAKE_PSTR_LIST(wWHeat, F("wwheat"), F("heating"))
MAKE_PSTR_LIST(wWSetPumpPower, F("wwsetpumppower"), F("pump set power"))
MAKE_PSTR_LIST(wWSetPumpPower, F("wwsetpumppower"), F("set pump power"))
MAKE_PSTR_LIST(mixerTemp, F("mixertemp"), F("mixer temperature"))
MAKE_PSTR_LIST(tankMiddleTemp, F("tankmiddletemp"), F("tank middle temperature (TS3)"))
MAKE_PSTR_LIST(wWStarts, F("wwstarts"), F("# starts"))
@@ -465,21 +469,20 @@ MAKE_PSTR_LIST(errorCode, F("errorcode"), F("error code"))
MAKE_PSTR_LIST(ibaMainDisplay, F("display"), F("display"))
MAKE_PSTR_LIST(ibaLanguage, F("language"), F("language"))
MAKE_PSTR_LIST(ibaClockOffset, F("clockoffset"), F("clock offset"))
MAKE_PSTR_LIST(ibaBuildingType, F("building"), F("building"))
MAKE_PSTR_LIST(ibaCalIntTemperature, F("intoffset"), F("offset internal temperature"))
MAKE_PSTR_LIST(ibaMinExtTemperature, F("minexttemp"), F("min external temperature"))
MAKE_PSTR_LIST(ibaMinExtTemperature, F("minexttemp"), F("minimal external temperature"))
MAKE_PSTR_LIST(tempsensor1, F("inttemp1"), F("temperature sensor 1"))
MAKE_PSTR_LIST(tempsensor2, F("inttemp2"), F("temperature sensor 2"))
MAKE_PSTR_LIST(dampedoutdoortemp, F("dampedoutdoortemp"), F("damped outdoor temperature"))
MAKE_PSTR_LIST(floordrystatus, F("floordry"), F("floor drying"))
MAKE_PSTR_LIST(dampedoutdoortemp2, F("dampedoutdoortemp"), F("damped outdoor temperature"))
MAKE_PSTR_LIST(floordrytemp, F("floordrytemp"), F("floor drying temperature"))
MAKE_PSTR_LIST(wwMode, F("wwmode"), F("mode"))
MAKE_PSTR_LIST(wwSetTemp, F("wwsettemp"), F("set temperature"))
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("set temperature low"))
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("set low temperature"))
MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("circuit 1 extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra"))
@@ -505,7 +508,7 @@ MAKE_PSTR_LIST(roominfluence, F("roominfluence"), F("room influence"))
MAKE_PSTR_LIST(nofrosttemp, F("nofrosttemp"), F("nofrost temperature"))
MAKE_PSTR_LIST(targetflowtemp, F("targetflowtemp"), F("target flow temperature"))
MAKE_PSTR_LIST(heatingtype, F("heatingtype"), F("heating type"))
MAKE_PSTR_LIST(summersetmode, F("summersetmode"), F("summer set mode"))
MAKE_PSTR_LIST(summersetmode, F("summersetmode"), F("set summer mode"))
MAKE_PSTR_LIST(controlmode, F("controlmode"), F("control mode"))
MAKE_PSTR_LIST(control, F("control"), F("control device"))
MAKE_PSTR_LIST(program, F("program"), F("program"))

View File

@@ -619,14 +619,15 @@ void System::system_check() {
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
// no individual subscribe for pin command because id is needed
void System::commands_init() {
Command::add(EMSdevice::DeviceType::SYSTEM, F_(pin), System::command_pin, MqttSubFlag::FLAG_NOSUB);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch);
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info);
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(pin), System::command_pin, F("set GPIO"), MqttSubFlag::FLAG_NOSUB);
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, F("send a telegram"));
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, F("force a MQTT publish"));
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, F("refresh all EMS values"));
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("system status"));
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings, F("list system settings"));
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("list system commands"));
#if defined(EMSESP_DEBUG)
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test);
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, F("run tests"));
#endif
}
@@ -777,6 +778,11 @@ bool System::check_upgrade() {
return false;
}
// list commands
bool System::command_commands(const char * value, const int8_t id, JsonObject & json) {
return Command::list(EMSdevice::DeviceType::SYSTEM, json);
}
// export all settings to JSON text
// e.g. http://ems-esp/api?device=system&cmd=settings
// value and id are ignored

View File

@@ -54,6 +54,7 @@ class System {
static bool command_fetch(const char * value, const int8_t id);
static bool command_info(const char * value, const int8_t id, JsonObject & json);
static bool command_settings(const char * value, const int8_t id, JsonObject & json);
static bool command_commands(const char * value, const int8_t id, JsonObject & json);
#if defined(EMSESP_DEBUG)
static bool command_test(const char * value, const int8_t id);
#endif