mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
refactor out console context menus - #510
This commit is contained in:
@@ -52,7 +52,7 @@ void EMSESPAPIService::emsespAPIService(AsyncWebServerRequest * request) {
|
|||||||
String cmd = request->getParam(F_(cmd))->value();
|
String cmd = request->getParam(F_(cmd))->value();
|
||||||
|
|
||||||
// look up command in our list
|
// look up command in our list
|
||||||
if (!Command::find(device_type, cmd.c_str())) {
|
if (!Command::find_command(device_type, cmd.c_str())) {
|
||||||
request->send(400, "text/plain", F("Invalid cmd"));
|
request->send(400, "text/plain", F("Invalid cmd"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
163
src/command.cpp
163
src/command.cpp
@@ -77,7 +77,7 @@ void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see if a command exists for that device type
|
// see if a command exists for that device type
|
||||||
bool Command::find(const uint8_t device_type, const char * cmd) {
|
bool Command::find_command(const uint8_t device_type, const char * cmd) {
|
||||||
for (const auto & cf : cmdfunctions_) {
|
for (const auto & cf : cmdfunctions_) {
|
||||||
if (strcmp(cmd, uuid::read_flash_string(cf.cmd_).c_str()) == 0) {
|
if (strcmp(cmd, uuid::read_flash_string(cf.cmd_).c_str()) == 0) {
|
||||||
return true;
|
return true;
|
||||||
@@ -88,6 +88,10 @@ bool Command::find(const uint8_t device_type, const char * cmd) {
|
|||||||
|
|
||||||
// output list of all commands to console for a specific DeviceType
|
// output list of all commands to console for a specific DeviceType
|
||||||
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
|
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
|
||||||
|
if (commands().empty()) {
|
||||||
|
shell.println(F("No commands"));
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto & cf : Command::commands()) {
|
for (const auto & cf : Command::commands()) {
|
||||||
if (cf.device_type_ == device_type) {
|
if (cf.device_type_ == device_type) {
|
||||||
shell.printf("%s ", uuid::read_flash_string(cf.cmd_).c_str());
|
shell.printf("%s ", uuid::read_flash_string(cf.cmd_).c_str());
|
||||||
@@ -96,128 +100,71 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
|
|||||||
shell.println();
|
shell.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
// determines the device_type from the shell context we're in
|
// see if a device_type is active and has associated commands
|
||||||
uint8_t Command::context_2_device_type(unsigned int context) {
|
bool Command::device_has_commands(const uint8_t device_type) {
|
||||||
// if (context == ShellContext::MAIN) {
|
if (device_type == EMSdevice::DeviceType::UNKNOWN) {
|
||||||
// return EMSdevice::DeviceType::SERVICEKEY;
|
return false;
|
||||||
// }
|
|
||||||
if (context == ShellContext::BOILER) {
|
|
||||||
return EMSdevice::DeviceType::BOILER;
|
|
||||||
}
|
|
||||||
if (context == ShellContext::MIXING) {
|
|
||||||
return EMSdevice::DeviceType::MIXING;
|
|
||||||
}
|
|
||||||
if (context == ShellContext::SOLAR) {
|
|
||||||
return EMSdevice::DeviceType::SOLAR;
|
|
||||||
}
|
|
||||||
if (context == ShellContext::SYSTEM) {
|
|
||||||
return EMSdevice::DeviceType::SERVICEKEY;
|
|
||||||
}
|
|
||||||
if (context == ShellContext::THERMOSTAT) {
|
|
||||||
return EMSdevice::DeviceType::THERMOSTAT;
|
|
||||||
}
|
|
||||||
if (context == ShellContext::SENSOR) {
|
|
||||||
return EMSdevice::DeviceType::SENSOR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EMSdevice::DeviceType::UNKNOWN; // unknown type
|
if (device_type == EMSdevice::DeviceType::SYSTEM) {
|
||||||
|
return true; // we always have System
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_type == EMSdevice::DeviceType::SENSOR) {
|
||||||
|
return true; // we always have Sensor, but should check if there are actual sensors attached!
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
|
if ((emsdevice) && (emsdevice->device_type() == device_type)) {
|
||||||
|
// device found, now see if it has any commands
|
||||||
|
for (const auto & cf : Command::commands()) {
|
||||||
|
if (cf.device_type_ == device_type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show command per current context
|
void Command::show_devices(uuid::console::Shell & shell) {
|
||||||
void Command::show(uuid::console::Shell & shell) {
|
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM).c_str());
|
||||||
show(shell, context_2_device_type(shell.context()));
|
|
||||||
|
if (EMSESP::have_sensors()) {
|
||||||
|
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SENSOR).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shell.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
// output list of all commands to console
|
// output list of all commands to console
|
||||||
void Command::show_all(uuid::console::Shell & shell) {
|
void Command::show_all(uuid::console::Shell & shell) {
|
||||||
|
shell.println(F("Available commands per device: "));
|
||||||
|
|
||||||
// show system first
|
// show system first
|
||||||
shell.printf("%s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SERVICEKEY).c_str());
|
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM).c_str());
|
||||||
show(shell, EMSdevice::DeviceType::SERVICEKEY);
|
show(shell, EMSdevice::DeviceType::SYSTEM);
|
||||||
|
|
||||||
|
// show sensor
|
||||||
|
if (EMSESP::have_sensors()) {
|
||||||
|
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SENSOR).c_str());
|
||||||
|
show(shell, EMSdevice::DeviceType::SENSOR);
|
||||||
|
}
|
||||||
|
|
||||||
// do this in the order of factory classes to keep a consistent order when displaying
|
// 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 & device_class : EMSFactory::device_handlers()) {
|
||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
if (Command::device_has_commands(device_class.first)) {
|
||||||
if ((emsdevice) && (emsdevice->device_type() == device_class.first)) {
|
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(device_class.first).c_str());
|
||||||
shell.printf("%s: ", EMSdevice::device_type_2_device_name(device_class.first).c_str());
|
|
||||||
show(shell, device_class.first);
|
show(shell, device_class.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
if ((context == ShellContext::THERMOSTAT) || (context == ShellContext::MIXING)) {
|
|
||||||
params = flash_string_vector{F_(cmd_optional), F_(data_optional), F_(hc_optional)};
|
|
||||||
} else if ((context == ShellContext::MAIN) || (context == ShellContext::SYSTEM)) {
|
|
||||||
params = flash_string_vector{F_(cmd_optional), F_(data_optional), F_(n_optional)};
|
|
||||||
} else {
|
|
||||||
params = flash_string_vector{F_(cmd_optional), F_(data_optional)};
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(
|
|
||||||
context,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(call)},
|
|
||||||
params,
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments) {
|
|
||||||
if (arguments.empty()) {
|
|
||||||
// list options
|
|
||||||
shell.print("Available commands: ");
|
|
||||||
show(shell);
|
|
||||||
shell.println();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, just the cmd
|
|
||||||
ok = Command::call(device_type, cmd, nullptr, -1, output);
|
|
||||||
} else if (arguments.size() == 2) {
|
|
||||||
// has a value but no id
|
|
||||||
ok = Command::call(device_type, cmd, arguments.back().c_str(), -1, output);
|
|
||||||
} else {
|
|
||||||
// use value, which could be an id or hc
|
|
||||||
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> {
|
|
||||||
if (arguments.size() > 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
std::vector<std::string> commands;
|
|
||||||
uint8_t device_type = context_2_device_type(shell.context());
|
|
||||||
for (const auto & cf : Command::commands()) {
|
|
||||||
if (cf.device_type_ == device_type) {
|
|
||||||
commands.emplace_back(uuid::read_flash_string(cf.cmd_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return commands;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -61,17 +61,15 @@ class Command {
|
|||||||
static void add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
static void add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
||||||
static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb);
|
static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb);
|
||||||
static void show_all(uuid::console::Shell & shell);
|
static void show_all(uuid::console::Shell & shell);
|
||||||
static void show(uuid::console::Shell & shell);
|
static bool find_command(const uint8_t device_type, const char * cmd);
|
||||||
static void add_context_commands(unsigned int context);
|
static void show(uuid::console::Shell & shell, uint8_t device_type);
|
||||||
static bool find(const uint8_t device_type, const char * cmd);
|
static void show_devices(uuid::console::Shell & shell);
|
||||||
|
static bool device_has_commands(const uint8_t device_type);
|
||||||
|
|
||||||
static std::vector<CmdFunction> cmdfunctions_; // list of commands
|
static std::vector<CmdFunction> cmdfunctions_; // list of commands
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
static void show(uuid::console::Shell & shell, uint8_t device_type);
|
|
||||||
static uint8_t context_2_device_type(unsigned int context);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
253
src/console.cpp
253
src/console.cpp
@@ -118,6 +118,15 @@ void EMSESPShell::add_console_commands() {
|
|||||||
EMSESP::fetch_device_values();
|
EMSESP::fetch_device_values();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
commands->add_command(ShellContext::MAIN,
|
||||||
|
CommandFlags::ADMIN,
|
||||||
|
flash_string_vector{F_(publish)},
|
||||||
|
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||||
|
shell.printfln(F("Publishing all data to MQTT"));
|
||||||
|
EMSESP::publish_all();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
commands->add_command(ShellContext::MAIN,
|
commands->add_command(ShellContext::MAIN,
|
||||||
CommandFlags::USER,
|
CommandFlags::USER,
|
||||||
flash_string_vector{F_(show)},
|
flash_string_vector{F_(show)},
|
||||||
@@ -247,6 +256,10 @@ void EMSESPShell::add_console_commands() {
|
|||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
||||||
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
||||||
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
|
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
|
||||||
|
char buffer[4];
|
||||||
|
shell.printfln(F_(master_thermostat_fmt),
|
||||||
|
settings.master_thermostat == 0 ? uuid::read_flash_string(F_(auto)).c_str()
|
||||||
|
: Helpers::hextoa(buffer, settings.master_thermostat));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -261,6 +274,163 @@ void EMSESPShell::add_console_commands() {
|
|||||||
EMSESP::send_read_request(type_id, device_id);
|
EMSESP::send_read_request(type_id, device_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
commands->add_command(ShellContext::MAIN,
|
||||||
|
CommandFlags::ADMIN,
|
||||||
|
flash_string_vector{F_(set), F_(master), F_(thermostat)},
|
||||||
|
flash_string_vector{F_(deviceid_mandatory)},
|
||||||
|
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
|
uint8_t value = Helpers::hextoint(arguments.front().c_str());
|
||||||
|
EMSESP::emsespSettingsService.update(
|
||||||
|
[&](EMSESPSettings & settings) {
|
||||||
|
settings.master_thermostat = value;
|
||||||
|
EMSESP::actual_master_thermostat(value); // set the internal value too
|
||||||
|
char buffer[5];
|
||||||
|
shell.printfln(F_(master_thermostat_fmt),
|
||||||
|
!value ? uuid::read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, value));
|
||||||
|
return StateUpdateResult::CHANGED;
|
||||||
|
},
|
||||||
|
"local");
|
||||||
|
});
|
||||||
|
|
||||||
|
commands->add_command(ShellContext::MAIN,
|
||||||
|
CommandFlags::ADMIN,
|
||||||
|
flash_string_vector{F_(send), F_(telegram)},
|
||||||
|
flash_string_vector{F_(data_mandatory)},
|
||||||
|
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||||
|
EMSESP::send_raw_telegram(arguments.front().c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
commands->add_command(ShellContext::MAIN,
|
||||||
|
CommandFlags::USER,
|
||||||
|
flash_string_vector{F_(watch)},
|
||||||
|
flash_string_vector{F_(watch_format_optional), F_(watchid_optional)},
|
||||||
|
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
|
uint16_t watch_id = WATCH_ID_NONE;
|
||||||
|
|
||||||
|
if (!arguments.empty()) {
|
||||||
|
// get raw/pretty
|
||||||
|
if (arguments[0] == read_flash_string(F_(raw))) {
|
||||||
|
emsesp::EMSESP::watch(EMSESP::WATCH_RAW); // raw
|
||||||
|
} else if (arguments[0] == read_flash_string(F_(on))) {
|
||||||
|
emsesp::EMSESP::watch(EMSESP::WATCH_ON); // on
|
||||||
|
} else if (arguments[0] == read_flash_string(F_(off))) {
|
||||||
|
emsesp::EMSESP::watch(EMSESP::WATCH_OFF); // off
|
||||||
|
} else if (emsesp::EMSESP::watch() == EMSESP::WATCH_OFF) {
|
||||||
|
shell.printfln(F_(invalid_watch));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
watch_id = Helpers::hextoint(arguments[0].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.size() == 2) {
|
||||||
|
// get the watch_id if its set
|
||||||
|
watch_id = Helpers::hextoint(arguments[1].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
emsesp::EMSESP::watch_id(watch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t watch = emsesp::EMSESP::watch();
|
||||||
|
if (watch == EMSESP::WATCH_OFF) {
|
||||||
|
shell.printfln(F("Watching telegrams is off"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if logging is off, the watch won't show anything, show force it back to NOTICE
|
||||||
|
if (!shell.logger().enabled(Level::NOTICE)) {
|
||||||
|
shell.log_level(Level::NOTICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (watch == EMSESP::WATCH_ON) {
|
||||||
|
shell.printfln(F("Watching incoming telegrams, displayed in decoded format"));
|
||||||
|
} else {
|
||||||
|
shell.printfln(F("Watching incoming telegrams, displayed as raw bytes")); // WATCH_RAW
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_id = emsesp::EMSESP::watch_id();
|
||||||
|
if (watch_id > 0x80) {
|
||||||
|
shell.printfln(F("Filtering only telegrams that match a telegram type of 0x%02X"), watch_id);
|
||||||
|
} else if (watch_id != WATCH_ID_NONE) {
|
||||||
|
shell.printfln(F("Filtering only telegrams that match a device ID or telegram type of 0x%02X"), watch_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
commands->add_command(
|
||||||
|
ShellContext::MAIN,
|
||||||
|
CommandFlags::ADMIN,
|
||||||
|
flash_string_vector{F_(call)},
|
||||||
|
flash_string_vector{F_(device_type_optional), F_(cmd_optional), F_(data_optional), F_(n_optional)},
|
||||||
|
[&](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
|
if (arguments.empty()) {
|
||||||
|
Command::show_all(shell); // list options
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the device_type
|
||||||
|
uint8_t device_type = EMSdevice::device_name_2_device_type(arguments[0].c_str());
|
||||||
|
if (!Command::device_has_commands(device_type)) {
|
||||||
|
shell.print(F("Invalid device. Available devices are: "));
|
||||||
|
Command::show_devices(shell);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the command
|
||||||
|
const char * cmd = arguments[1].c_str();
|
||||||
|
if (!Command::find_command(device_type, cmd)) {
|
||||||
|
shell.print(F("Unknown command. Available commands are: "));
|
||||||
|
Command::show(shell, device_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE);
|
||||||
|
JsonObject output = doc.to<JsonObject>();
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
if (arguments.size() == 2) {
|
||||||
|
// no value specified, just the cmd
|
||||||
|
ok = Command::call(device_type, cmd, nullptr, -1, output);
|
||||||
|
} else if (arguments.size() == 3) {
|
||||||
|
// has a value but no id
|
||||||
|
ok = Command::call(device_type, cmd, arguments.back().c_str(), -1, output);
|
||||||
|
} else {
|
||||||
|
// use value, which could be an id or hc
|
||||||
|
ok = Command::call(device_type, cmd, arguments[2].c_str(), atoi(arguments[3].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> {
|
||||||
|
if (arguments.size() == 0) {
|
||||||
|
std::vector<std::string> devices_list;
|
||||||
|
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM));
|
||||||
|
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SENSOR));
|
||||||
|
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||||
|
if (Command::device_has_commands(device_class.first)) {
|
||||||
|
devices_list.emplace_back(EMSdevice::device_type_2_device_name(device_class.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return devices_list;
|
||||||
|
} else if (arguments.size() == 1) {
|
||||||
|
std::vector<std::string> command_list;
|
||||||
|
uint8_t device_type = EMSdevice::device_name_2_device_type(arguments[0].c_str());
|
||||||
|
if (!Command::device_has_commands(device_type)) {
|
||||||
|
for (const auto & cf : Command::commands()) {
|
||||||
|
if (cf.device_type_ == device_type) {
|
||||||
|
command_list.emplace_back(uuid::read_flash_string(cf.cmd_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return command_list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add all the submenu contexts...
|
* add all the submenu contexts...
|
||||||
*/
|
*/
|
||||||
@@ -273,10 +443,6 @@ void EMSESPShell::add_console_commands() {
|
|||||||
System::console_commands(shell, ShellContext::SYSTEM);
|
System::console_commands(shell, ShellContext::SYSTEM);
|
||||||
});
|
});
|
||||||
|
|
||||||
// add all the context menus for the connected devices
|
|
||||||
// this assumes they devices have been detected and pre-registered
|
|
||||||
EMSESP::add_context_menus();
|
|
||||||
|
|
||||||
Console::load_standard_commands(ShellContext::MAIN);
|
Console::load_standard_commands(ShellContext::MAIN);
|
||||||
|
|
||||||
console_commands_loaded_ = true;
|
console_commands_loaded_ = true;
|
||||||
@@ -400,76 +566,6 @@ void Console::load_standard_commands(unsigned int context) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(context,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(send), F_(telegram)},
|
|
||||||
flash_string_vector{F_(data_mandatory)},
|
|
||||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
|
||||||
EMSESP::send_raw_telegram(arguments.front().c_str());
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(context,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(watch)},
|
|
||||||
flash_string_vector{F_(watch_format_optional), F_(watchid_optional)},
|
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
|
||||||
uint16_t watch_id = WATCH_ID_NONE;
|
|
||||||
|
|
||||||
if (!arguments.empty()) {
|
|
||||||
// get raw/pretty
|
|
||||||
if (arguments[0] == read_flash_string(F_(raw))) {
|
|
||||||
emsesp::EMSESP::watch(EMSESP::WATCH_RAW); // raw
|
|
||||||
} else if (arguments[0] == read_flash_string(F_(on))) {
|
|
||||||
emsesp::EMSESP::watch(EMSESP::WATCH_ON); // on
|
|
||||||
} else if (arguments[0] == read_flash_string(F_(off))) {
|
|
||||||
emsesp::EMSESP::watch(EMSESP::WATCH_OFF); // off
|
|
||||||
} else if (emsesp::EMSESP::watch() == EMSESP::WATCH_OFF) {
|
|
||||||
shell.printfln(F_(invalid_watch));
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
watch_id = Helpers::hextoint(arguments[0].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.size() == 2) {
|
|
||||||
// get the watch_id if its set
|
|
||||||
watch_id = Helpers::hextoint(arguments[1].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
emsesp::EMSESP::watch_id(watch_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t watch = emsesp::EMSESP::watch();
|
|
||||||
if (watch == EMSESP::WATCH_OFF) {
|
|
||||||
shell.printfln(F("Watching telegrams is off"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if logging is off, the watch won't show anything, show force it back to NOTICE
|
|
||||||
if (!shell.logger().enabled(Level::NOTICE)) {
|
|
||||||
shell.log_level(Level::NOTICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (watch == EMSESP::WATCH_ON) {
|
|
||||||
shell.printfln(F("Watching incoming telegrams, displayed in decoded format"));
|
|
||||||
} else {
|
|
||||||
shell.printfln(F("Watching incoming telegrams, displayed as raw bytes")); // WATCH_RAW
|
|
||||||
}
|
|
||||||
|
|
||||||
watch_id = emsesp::EMSESP::watch_id();
|
|
||||||
if (watch_id > 0x80) {
|
|
||||||
shell.printfln(F("Filtering only telegrams that match a telegram type of 0x%02X"), watch_id);
|
|
||||||
} else if (watch_id != WATCH_ID_NONE) {
|
|
||||||
shell.printfln(F("Filtering only telegrams that match a device ID or telegram type of 0x%02X"), watch_id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// load the commands (console & mqtt topics) for this specific context
|
|
||||||
// unless it's main (the root)
|
|
||||||
if (context != ShellContext::MAIN) {
|
|
||||||
Command::add_context_commands(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// prompt, change per context
|
// prompt, change per context
|
||||||
@@ -478,18 +574,9 @@ std::string EMSESPShell::context_text() {
|
|||||||
case ShellContext::MAIN:
|
case ShellContext::MAIN:
|
||||||
return std::string{'/'};
|
return std::string{'/'};
|
||||||
|
|
||||||
case ShellContext::BOILER:
|
|
||||||
return std::string{"/boiler"};
|
|
||||||
|
|
||||||
case ShellContext::SYSTEM:
|
case ShellContext::SYSTEM:
|
||||||
return std::string{"/system"};
|
return std::string{"/system"};
|
||||||
|
|
||||||
case ShellContext::THERMOSTAT:
|
|
||||||
return std::string{"/thermostat"};
|
|
||||||
|
|
||||||
case ShellContext::SENSOR:
|
|
||||||
return std::string{"/sensor"};
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return std::string{};
|
return std::string{};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,11 +76,6 @@ enum ShellContext : uint8_t {
|
|||||||
|
|
||||||
MAIN = 0,
|
MAIN = 0,
|
||||||
SYSTEM,
|
SYSTEM,
|
||||||
BOILER,
|
|
||||||
THERMOSTAT,
|
|
||||||
SOLAR,
|
|
||||||
MIXING,
|
|
||||||
SENSOR
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -84,16 +84,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// add submenu context
|
|
||||||
void Boiler::add_context_menu() {
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(boiler)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
|
||||||
Boiler::console_commands(shell, ShellContext::BOILER);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the config topic for Home Assistant MQTT Discovery
|
// create the config topic for Home Assistant MQTT Discovery
|
||||||
// homeassistant/sensor/ems-esp/boiler
|
// homeassistant/sensor/ems-esp/boiler
|
||||||
// state is /state
|
// state is /state
|
||||||
@@ -1070,25 +1060,4 @@ bool Boiler::set_warmwater_circulation(const char * value, const int8_t id) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Boiler::console_commands(Shell & shell, unsigned int context) {
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(read)},
|
|
||||||
flash_string_vector{F_(typeid_mandatory)},
|
|
||||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
|
||||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::set_read_id(type_id);
|
|
||||||
EMSESP::send_read_request(type_id, device_id());
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(show)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
|
||||||
|
|
||||||
// enter the context
|
|
||||||
Console::enter_custom_context(shell, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -42,12 +42,10 @@ class Boiler : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands(Shell & shell, unsigned int context);
|
|
||||||
void register_mqtt_ha_config();
|
void register_mqtt_ha_config();
|
||||||
void check_active();
|
void check_active();
|
||||||
bool export_values(JsonObject & doc);
|
bool export_values(JsonObject & doc);
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, con
|
|||||||
void Connect::device_info_web(JsonArray & root) {
|
void Connect::device_info_web(JsonArray & root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connect::add_context_menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// display all values into the shell console
|
// display all values into the shell console
|
||||||
void Connect::show_values(uuid::console::Shell & shell) {
|
void Connect::show_values(uuid::console::Shell & shell) {
|
||||||
// EMSdevice::show_values(shell); // always call this to show header
|
// EMSdevice::show_values(shell); // always call this to show header
|
||||||
@@ -48,8 +45,4 @@ bool Connect::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Connect::console_commands() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -39,12 +39,9 @@ class Connect : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::add_context_menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::device_info_web(JsonArray & root) {
|
void Controller::device_info_web(JsonArray & root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +45,4 @@ bool Controller::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Controller::console_commands() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -39,12 +39,10 @@ class Controller : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, con
|
|||||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gateway::add_context_menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gateway::device_info_web(JsonArray & root) {
|
void Gateway::device_info_web(JsonArray & root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +45,4 @@ bool Gateway::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Gateway::console_commands() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -39,12 +39,10 @@ class Gateway : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -33,10 +33,6 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
|||||||
register_telegram_type(0x042B, F("HP2"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor2(t); });
|
register_telegram_type(0x042B, F("HP2"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor2(t); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// context submenu
|
|
||||||
void Heatpump::add_context_menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Heatpump::device_info_web(JsonArray & root) {
|
void Heatpump::device_info_web(JsonArray & root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +50,6 @@ bool Heatpump::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Heatpump::console_commands() {
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
|
|||||||
@@ -39,13 +39,10 @@ class Heatpump : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
|
|
||||||
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_HPMonitor2(std::shared_ptr<const Telegram> telegram);
|
void process_HPMonitor2(std::shared_ptr<const Telegram> telegram);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -60,19 +60,6 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// add context submenu
|
|
||||||
void Mixing::add_context_menu() {
|
|
||||||
// TODO support for multiple mixing units from a single menu, similar to set master with thermostat
|
|
||||||
/*
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(mixing)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
|
||||||
Mixing::console_commands(shell, ShellContext::MIXING);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// output json to web UI
|
// output json to web UI
|
||||||
void Mixing::device_info_web(JsonArray & root) {
|
void Mixing::device_info_web(JsonArray & root) {
|
||||||
if (type_ == Type::NONE) {
|
if (type_ == Type::NONE) {
|
||||||
@@ -102,27 +89,6 @@ bool Mixing::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Mixing::console_commands(Shell & shell, unsigned int context) {
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MIXING,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(read)},
|
|
||||||
flash_string_vector{F_(typeid_mandatory)},
|
|
||||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
|
||||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::set_read_id(type_id);
|
|
||||||
EMSESP::send_read_request(type_id, device_id());
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MIXING,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(show)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
|
||||||
|
|
||||||
// enter the context
|
|
||||||
Console::enter_custom_context(shell, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// display all values into the shell console
|
// display all values into the shell console
|
||||||
void Mixing::show_values(uuid::console::Shell & shell) {
|
void Mixing::show_values(uuid::console::Shell & shell) {
|
||||||
EMSdevice::show_values(shell); // always call this to show header
|
EMSdevice::show_values(shell); // always call this to show header
|
||||||
|
|||||||
@@ -40,12 +40,10 @@ class Mixing : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands(Shell & shell, unsigned int context);
|
|
||||||
bool export_values(JsonObject & doc);
|
bool export_values(JsonObject & doc);
|
||||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||||
|
|
||||||
|
|||||||
@@ -58,19 +58,6 @@ bool Solar::command_info(const char * value, const int8_t id, JsonObject & outpu
|
|||||||
return (export_values(output));
|
return (export_values(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
// context submenu
|
|
||||||
void Solar::add_context_menu() {
|
|
||||||
// TODO support for multiple solar units from a single menu, similar to set master with thermostat
|
|
||||||
/*
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(solar)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
|
||||||
Solar::console_commands(shell, ShellContext::SOLAR);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// print to web
|
// print to web
|
||||||
void Solar::device_info_web(JsonArray & root) {
|
void Solar::device_info_web(JsonArray & root) {
|
||||||
render_value_json(root, "", F("Collector temperature (TS1)"), collectorTemp_, F_(degrees), 10);
|
render_value_json(root, "", F("Collector temperature (TS1)"), collectorTemp_, F_(degrees), 10);
|
||||||
@@ -206,27 +193,6 @@ bool Solar::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Solar::console_commands(Shell & shell, unsigned int context) {
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::SOLAR,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(read)},
|
|
||||||
flash_string_vector{F_(typeid_mandatory)},
|
|
||||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
|
||||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::set_read_id(type_id);
|
|
||||||
EMSESP::send_read_request(type_id, device_id());
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::SOLAR,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(show)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
|
||||||
|
|
||||||
// enter the context
|
|
||||||
Console::enter_custom_context(shell, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SM10Monitor - type 0x97
|
// SM10Monitor - type 0x97
|
||||||
void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||||
changed_ |= telegram->read_value(collectorTemp_, 2); // collector temp from SM10, is *10
|
changed_ |= telegram->read_value(collectorTemp_, 2); // collector temp from SM10, is *10
|
||||||
|
|||||||
@@ -40,12 +40,10 @@ class Solar : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands(Shell & shell, unsigned int context);
|
|
||||||
bool export_values(JsonObject & doc);
|
bool export_values(JsonObject & doc);
|
||||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
|||||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Switch::add_context_menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Switch::device_info_web(JsonArray & root) {
|
void Switch::device_info_web(JsonArray & root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +45,4 @@ bool Switch::updated_values() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Switch::console_commands() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -39,12 +39,10 @@ class Switch : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -219,21 +219,6 @@ void Thermostat::device_info_web(JsonArray & root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// context menu "thermostat"
|
|
||||||
void Thermostat::add_context_menu() {
|
|
||||||
// only add it once, to prevent conflicts when there are multiple thermostats
|
|
||||||
if (this->device_id() != EMSESP::actual_master_thermostat()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(thermostat)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
|
||||||
Thermostat::console_commands(shell, ShellContext::THERMOSTAT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function is called post the telegram handler function has been executed
|
// this function is called post the telegram handler function has been executed
|
||||||
// we check if any of the thermostat values have changed and then republish if necessary
|
// we check if any of the thermostat values have changed and then republish if necessary
|
||||||
bool Thermostat::updated_values() {
|
bool Thermostat::updated_values() {
|
||||||
@@ -1167,58 +1152,6 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add console commands
|
|
||||||
void Thermostat::console_commands(Shell & shell, unsigned int context) {
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::THERMOSTAT,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(set), F_(master)},
|
|
||||||
flash_string_vector{F_(deviceid_mandatory)},
|
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
|
||||||
uint8_t value = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::emsespSettingsService.update(
|
|
||||||
[&](EMSESPSettings & settings) {
|
|
||||||
settings.master_thermostat = value;
|
|
||||||
EMSESP::actual_master_thermostat(value); // set the internal value too
|
|
||||||
char buffer[5];
|
|
||||||
shell.printfln(F_(master_thermostat_fmt),
|
|
||||||
!value ? uuid::read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, value));
|
|
||||||
return StateUpdateResult::CHANGED;
|
|
||||||
},
|
|
||||||
"local");
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::THERMOSTAT,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(read)},
|
|
||||||
flash_string_vector{F_(typeid_mandatory)},
|
|
||||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
|
||||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::set_read_id(type_id);
|
|
||||||
EMSESP::send_read_request(type_id, this->device_id());
|
|
||||||
});
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::THERMOSTAT,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(show)},
|
|
||||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
|
||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::THERMOSTAT,
|
|
||||||
CommandFlags::USER,
|
|
||||||
flash_string_vector{F_(set)},
|
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
|
||||||
char buffer[4];
|
|
||||||
shell.printfln(F_(master_thermostat_fmt),
|
|
||||||
settings.master_thermostat == 0 ? uuid::read_flash_string(F_(auto)).c_str()
|
|
||||||
: Helpers::hextoa(buffer, settings.master_thermostat));
|
|
||||||
shell.println();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// enter the context
|
|
||||||
Console::enter_custom_context(shell, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0xA5 - Set minimum external temperature
|
// 0xA5 - Set minimum external temperature
|
||||||
bool Thermostat::set_minexttemp(const char * value, const int8_t id) {
|
bool Thermostat::set_minexttemp(const char * value, const int8_t id) {
|
||||||
int mt = 0;
|
int mt = 0;
|
||||||
|
|||||||
@@ -101,12 +101,10 @@ class Thermostat : public EMSdevice {
|
|||||||
virtual void publish_values();
|
virtual void publish_values();
|
||||||
virtual void device_info_web(JsonArray & root);
|
virtual void device_info_web(JsonArray & root);
|
||||||
virtual bool updated_values();
|
virtual bool updated_values();
|
||||||
virtual void add_context_menu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void console_commands(Shell & shell, unsigned int context);
|
|
||||||
void add_commands();
|
void add_commands();
|
||||||
bool export_values(uint8_t mqtt_format, JsonObject & doc);
|
bool export_values(uint8_t mqtt_format, JsonObject & doc);
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ std::string EMSdevice::brand_to_string() const {
|
|||||||
// returns the name of the MQTT topic to use for a specific device
|
// returns the name of the MQTT topic to use for a specific device
|
||||||
std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
||||||
switch (device_type) {
|
switch (device_type) {
|
||||||
case DeviceType::SERVICEKEY:
|
case DeviceType::SYSTEM:
|
||||||
return read_flash_string(F("system"));
|
return read_flash_string(F("system"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -79,6 +79,18 @@ std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
|||||||
return read_flash_string(F("mixing"));
|
return read_flash_string(F("mixing"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DeviceType::SENSOR:
|
||||||
|
return read_flash_string(F("sensor"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType::CONTROLLER:
|
||||||
|
return read_flash_string(F("controller"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType::SWITCH:
|
||||||
|
return read_flash_string(F("switch"));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return std::string{};
|
return std::string{};
|
||||||
break;
|
break;
|
||||||
@@ -96,7 +108,7 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(topic, "system") == 0) {
|
if (strcmp(topic, "system") == 0) {
|
||||||
return DeviceType::SERVICEKEY;
|
return DeviceType::SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(topic, "heatpump") == 0) {
|
if (strcmp(topic, "heatpump") == 0) {
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ class EMSdevice {
|
|||||||
virtual void show_values(uuid::console::Shell & shell) = 0;
|
virtual void show_values(uuid::console::Shell & shell) = 0;
|
||||||
virtual void publish_values() = 0;
|
virtual void publish_values() = 0;
|
||||||
virtual bool updated_values() = 0;
|
virtual bool updated_values() = 0;
|
||||||
virtual void add_context_menu() = 0;
|
|
||||||
virtual void device_info_web(JsonArray & root) = 0;
|
virtual void device_info_web(JsonArray & root) = 0;
|
||||||
|
|
||||||
std::string telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
std::string telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
||||||
@@ -228,7 +227,7 @@ class EMSdevice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum DeviceType : uint8_t {
|
enum DeviceType : uint8_t {
|
||||||
SERVICEKEY = 0, // this is us (EMS-ESP)
|
SYSTEM = 0, // this is us (EMS-ESP)
|
||||||
SENSOR, // for internal dallas sensors
|
SENSOR, // for internal dallas sensors
|
||||||
BOILER,
|
BOILER,
|
||||||
THERMOSTAT,
|
THERMOSTAT,
|
||||||
@@ -279,7 +278,7 @@ class EMSdevice {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t unique_id_;
|
uint8_t unique_id_;
|
||||||
uint8_t device_type_ = DeviceType::SERVICEKEY;
|
uint8_t device_type_ = DeviceType::SYSTEM;
|
||||||
uint8_t device_id_ = 0;
|
uint8_t device_id_ = 0;
|
||||||
uint8_t product_id_ = 0;
|
uint8_t product_id_ = 0;
|
||||||
std::string version_;
|
std::string version_;
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
|||||||
|
|
||||||
// show Dallas temperature sensors
|
// show Dallas temperature sensors
|
||||||
void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||||
if (sensor_devices().empty()) {
|
if (!have_sensors()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +288,17 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
|||||||
shell.println();
|
shell.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MQTT publish everything, immediately
|
||||||
|
void EMSESP::publish_all() {
|
||||||
|
publish_device_values(EMSdevice::DeviceType::BOILER);
|
||||||
|
publish_device_values(EMSdevice::DeviceType::THERMOSTAT);
|
||||||
|
publish_device_values(EMSdevice::DeviceType::SOLAR);
|
||||||
|
publish_device_values(EMSdevice::DeviceType::MIXING);
|
||||||
|
publish_other_values();
|
||||||
|
publish_sensor_values(true);
|
||||||
|
system_.send_heartbeat();
|
||||||
|
}
|
||||||
|
|
||||||
void EMSESP::publish_device_values(uint8_t device_type) {
|
void EMSESP::publish_device_values(uint8_t device_type) {
|
||||||
if (Mqtt::connected()) {
|
if (Mqtt::connected()) {
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
@@ -432,7 +443,9 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
|
|||||||
* e.g. 08 00 07 00 0B 80 00 00 00 00 00 00 00 00 00 00 00
|
* e.g. 08 00 07 00 0B 80 00 00 00 00 00 00 00 00 00 00 00
|
||||||
* Junkers has 15 bytes of data
|
* Junkers has 15 bytes of data
|
||||||
* each byte is a bitmask for which devices are active
|
* each byte is a bitmask for which devices are active
|
||||||
* byte 1 = range 0x08 - 0x0F, byte 2=0x10 - 0x17 etc...
|
* byte 1 = 0x08 - 0x0F, byte 2 = 0x10 - 0x17, etc...
|
||||||
|
* e.g. in example above 1st byte = x0B = b1011 so we have device ids 0x08, 0x09, 0x011
|
||||||
|
* and 2nd byte = x80 = b1000 b0000 = device id 0x17
|
||||||
*/
|
*/
|
||||||
void EMSESP::process_UBADevices(std::shared_ptr<const Telegram> telegram) {
|
void EMSESP::process_UBADevices(std::shared_ptr<const Telegram> telegram) {
|
||||||
// exit it length is incorrect (must be 13 or 15 bytes long)
|
// exit it length is incorrect (must be 13 or 15 bytes long)
|
||||||
@@ -589,15 +602,6 @@ bool EMSESP::device_exists(const uint8_t device_id) {
|
|||||||
return false; // not found
|
return false; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each device add its context menu for the console
|
|
||||||
void EMSESP::add_context_menus() {
|
|
||||||
for (const auto & emsdevice : emsdevices) {
|
|
||||||
if (emsdevice) {
|
|
||||||
emsdevice->add_context_menu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for each associated EMS device go and get its system information
|
// for each associated EMS device go and get its system information
|
||||||
void EMSESP::show_devices(uuid::console::Shell & shell) {
|
void EMSESP::show_devices(uuid::console::Shell & shell) {
|
||||||
if (emsdevices.empty()) {
|
if (emsdevices.empty()) {
|
||||||
@@ -609,7 +613,7 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
|||||||
shell.printfln(F("These EMS devices are currently active:"));
|
shell.printfln(F("These EMS devices are currently active:"));
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
// for all device objects from emsdevice.h (UNKNOWN, SERVICEKEY, BOILER, THERMOSTAT, MIXING, SOLAR, HEATPUMP, GATEWAY, SWITCH, CONTROLLER, CONNECT)
|
// for all device objects from emsdevice.h (UNKNOWN, SYSTEM, BOILER, THERMOSTAT, MIXING, SOLAR, HEATPUMP, GATEWAY, SWITCH, CONTROLLER, CONNECT)
|
||||||
// so we keep a consistent order
|
// so we keep a consistent order
|
||||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||||
// shell.printf(F("[factory ID: %d] "), device_class.first);
|
// shell.printf(F("[factory ID: %d] "), device_class.first);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ class EMSESP {
|
|||||||
static void publish_device_values(uint8_t device_type);
|
static void publish_device_values(uint8_t device_type);
|
||||||
static void publish_other_values();
|
static void publish_other_values();
|
||||||
static void publish_sensor_values(const bool force = false);
|
static void publish_sensor_values(const bool force = false);
|
||||||
|
static void publish_all();
|
||||||
|
|
||||||
#ifdef EMSESP_STANDALONE
|
#ifdef EMSESP_STANDALONE
|
||||||
static void run_test(uuid::console::Shell & shell, const std::string & command); // only for testing
|
static void run_test(uuid::console::Shell & shell, const std::string & command); // only for testing
|
||||||
@@ -102,8 +103,6 @@ class EMSESP {
|
|||||||
static void show_devices(uuid::console::Shell & shell);
|
static void show_devices(uuid::console::Shell & shell);
|
||||||
static void show_ems(uuid::console::Shell & shell);
|
static void show_ems(uuid::console::Shell & shell);
|
||||||
|
|
||||||
static void add_context_menus();
|
|
||||||
|
|
||||||
static void init_tx();
|
static void init_tx();
|
||||||
|
|
||||||
static void incoming_telegram(uint8_t * data, const uint8_t length);
|
static void incoming_telegram(uint8_t * data, const uint8_t length);
|
||||||
@@ -112,6 +111,10 @@ class EMSESP {
|
|||||||
return sensor_.devices();
|
return sensor_.devices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool have_sensors() {
|
||||||
|
return (!(sensor_.devices().empty()));
|
||||||
|
}
|
||||||
|
|
||||||
enum Watch : uint8_t { WATCH_OFF, WATCH_ON, WATCH_RAW };
|
enum Watch : uint8_t { WATCH_OFF, WATCH_ON, WATCH_RAW };
|
||||||
static void watch_id(uint16_t id);
|
static void watch_id(uint16_t id);
|
||||||
static uint16_t watch_id() {
|
static uint16_t watch_id() {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ MAKE_PSTR_WORD(heartbeat)
|
|||||||
MAKE_PSTR_WORD(users)
|
MAKE_PSTR_WORD(users)
|
||||||
MAKE_PSTR_WORD(master)
|
MAKE_PSTR_WORD(master)
|
||||||
MAKE_PSTR_WORD(pin)
|
MAKE_PSTR_WORD(pin)
|
||||||
|
MAKE_PSTR_WORD(publish)
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
MAKE_PSTR_WORD(test)
|
MAKE_PSTR_WORD(test)
|
||||||
@@ -117,6 +118,7 @@ MAKE_PSTR(n_optional, "[n]")
|
|||||||
MAKE_PSTR(data_optional, "[data]")
|
MAKE_PSTR(data_optional, "[data]")
|
||||||
MAKE_PSTR(typeid_mandatory, "<type ID>")
|
MAKE_PSTR(typeid_mandatory, "<type ID>")
|
||||||
MAKE_PSTR(deviceid_mandatory, "<device ID>")
|
MAKE_PSTR(deviceid_mandatory, "<device ID>")
|
||||||
|
MAKE_PSTR(device_type_optional, "[device]")
|
||||||
MAKE_PSTR(invalid_log_level, "Invalid log level")
|
MAKE_PSTR(invalid_log_level, "Invalid log level")
|
||||||
MAKE_PSTR(log_level_fmt, "Log level = %s")
|
MAKE_PSTR(log_level_fmt, "Log level = %s")
|
||||||
MAKE_PSTR(log_level_optional, "[level]")
|
MAKE_PSTR(log_level_optional, "[level]")
|
||||||
|
|||||||
17
src/mqtt.cpp
17
src/mqtt.cpp
@@ -100,9 +100,7 @@ void Mqtt::resubscribe() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main MQTT loop
|
// Main MQTT loop - sends out top item on publish queue
|
||||||
// Checks for connection, establishes a connection if not
|
|
||||||
// sends out top item on publish queue
|
|
||||||
void Mqtt::loop() {
|
void Mqtt::loop() {
|
||||||
// exit if MQTT is not enabled or if there is no WIFI
|
// exit if MQTT is not enabled or if there is no WIFI
|
||||||
if (!connected()) {
|
if (!connected()) {
|
||||||
@@ -116,26 +114,32 @@ void Mqtt::loop() {
|
|||||||
last_publish_boiler_ = currentMillis;
|
last_publish_boiler_ = currentMillis;
|
||||||
EMSESP::publish_device_values(EMSdevice::DeviceType::BOILER);
|
EMSESP::publish_device_values(EMSdevice::DeviceType::BOILER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publish_time_thermostat_ && (currentMillis - last_publish_thermostat_ > publish_time_thermostat_)) {
|
if (publish_time_thermostat_ && (currentMillis - last_publish_thermostat_ > publish_time_thermostat_)) {
|
||||||
last_publish_thermostat_ = currentMillis;
|
last_publish_thermostat_ = currentMillis;
|
||||||
EMSESP::publish_device_values(EMSdevice::DeviceType::THERMOSTAT);
|
EMSESP::publish_device_values(EMSdevice::DeviceType::THERMOSTAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publish_time_solar_ && (currentMillis - last_publish_solar_ > publish_time_solar_)) {
|
if (publish_time_solar_ && (currentMillis - last_publish_solar_ > publish_time_solar_)) {
|
||||||
last_publish_solar_ = currentMillis;
|
last_publish_solar_ = currentMillis;
|
||||||
EMSESP::publish_device_values(EMSdevice::DeviceType::SOLAR);
|
EMSESP::publish_device_values(EMSdevice::DeviceType::SOLAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publish_time_mixing_ && (currentMillis - last_publish_mixing_ > publish_time_mixing_)) {
|
if (publish_time_mixing_ && (currentMillis - last_publish_mixing_ > publish_time_mixing_)) {
|
||||||
last_publish_mixing_ = currentMillis;
|
last_publish_mixing_ = currentMillis;
|
||||||
EMSESP::publish_device_values(EMSdevice::DeviceType::MIXING);
|
EMSESP::publish_device_values(EMSdevice::DeviceType::MIXING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) {
|
if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) {
|
||||||
last_publish_other_ = currentMillis;
|
last_publish_other_ = currentMillis;
|
||||||
EMSESP::publish_other_values();
|
EMSESP::publish_other_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMillis - last_publish_sensor_ > publish_time_sensor_) {
|
if (currentMillis - last_publish_sensor_ > publish_time_sensor_) {
|
||||||
last_publish_sensor_ = currentMillis;
|
last_publish_sensor_ = currentMillis;
|
||||||
EMSESP::publish_sensor_values(publish_time_sensor_ != 0);
|
EMSESP::publish_sensor_values(publish_time_sensor_ != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish top item from MQTT queue to stop flooding
|
// publish top item from MQTT queue to stop flooding
|
||||||
if ((uint32_t)(currentMillis - last_mqtt_poll_) > MQTT_PUBLISH_WAIT) {
|
if ((uint32_t)(currentMillis - last_mqtt_poll_) > MQTT_PUBLISH_WAIT) {
|
||||||
last_mqtt_poll_ = currentMillis;
|
last_mqtt_poll_ = currentMillis;
|
||||||
@@ -316,7 +320,7 @@ void Mqtt::on_publish(uint16_t packetId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mqtt_message.packet_id_ != packetId) {
|
if (mqtt_message.packet_id_ != packetId) {
|
||||||
LOG_DEBUG(F("Mismatch, expecting PID %d, got %d"), mqtt_message.packet_id_, packetId);
|
LOG_ERROR(F("Mismatch, expecting PID %d, got %d"), mqtt_message.packet_id_, packetId);
|
||||||
mqtt_publish_fails_++; // increment error count
|
mqtt_publish_fails_++; // increment error count
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,13 +474,14 @@ std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation,
|
|||||||
if ((strncmp(topic.c_str(), "homeassistant/", 13) == 0)) {
|
if ((strncmp(topic.c_str(), "homeassistant/", 13) == 0)) {
|
||||||
// leave topic as it is
|
// leave topic as it is
|
||||||
// message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
// message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
||||||
message = std::make_shared<MqttMessage>(operation, topic, payload, retain);
|
message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// prefix the hostname
|
// prefix the hostname
|
||||||
std::string full_topic(50, '\0');
|
std::string full_topic(50, '\0');
|
||||||
snprintf_P(&full_topic[0], full_topic.capacity() + 1, PSTR("%s/%s"), Mqtt::hostname_.c_str(), topic.c_str());
|
snprintf_P(&full_topic[0], full_topic.capacity() + 1, PSTR("%s/%s"), Mqtt::hostname_.c_str(), topic.c_str());
|
||||||
message = std::make_shared<MqttMessage>(operation, full_topic, payload, retain);
|
// message = std::make_shared<MqttMessage>(operation, full_topic, std::move(payload), retain);
|
||||||
|
message = std::make_shared<MqttMessage>(operation, full_topic, std::move(payload), retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the queue is full, make room but removing the last one
|
// if the queue is full, make room but removing the last one
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ struct MqttMessage {
|
|||||||
const std::string payload;
|
const std::string payload;
|
||||||
const bool retain;
|
const bool retain;
|
||||||
|
|
||||||
// MqttMessage(const uint8_t operation, const std::string & topic, const std::string && payload, bool retain)
|
// MqttMessage(const uint8_t operation, const std::string & topic, const std::string & payload, bool retain)
|
||||||
MqttMessage(const uint8_t operation, const std::string & topic, const std::string & payload, bool retain)
|
MqttMessage(const uint8_t operation, const std::string & topic, const std::string && payload, bool retain)
|
||||||
: operation(operation)
|
: operation(operation)
|
||||||
, topic(topic)
|
, topic(topic)
|
||||||
, payload(payload)
|
, payload(payload)
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ class Shower {
|
|||||||
static constexpr uint32_t SHOWER_COLDSHOT_DURATION = 10; // in seconds. 10 seconds for cold water before turning back hot water
|
static constexpr uint32_t SHOWER_COLDSHOT_DURATION = 10; // in seconds. 10 seconds for cold water before turning back hot water
|
||||||
static constexpr uint32_t SHOWER_MAX_DURATION = 420000; // in ms. 7 minutes, before trigger a shot of cold water
|
static constexpr uint32_t SHOWER_MAX_DURATION = 420000; // in ms. 7 minutes, before trigger a shot of cold water
|
||||||
|
|
||||||
void console_commands();
|
|
||||||
|
|
||||||
void publish_values();
|
void publish_values();
|
||||||
void shower_alert_start();
|
void shower_alert_start();
|
||||||
void shower_alert_stop();
|
void shower_alert_stop();
|
||||||
|
|||||||
@@ -157,9 +157,9 @@ void System::start() {
|
|||||||
|
|
||||||
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
||||||
Command::add(EMSdevice::DeviceType::SERVICEKEY, settings.ems_bus_id, F("pin"), System::command_pin);
|
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F("pin"), System::command_pin);
|
||||||
Command::add(EMSdevice::DeviceType::SERVICEKEY, settings.ems_bus_id, F("send"), System::command_send);
|
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F("send"), System::command_send);
|
||||||
Command::add_with_json(EMSdevice::DeviceType::SERVICEKEY, F("info"), System::command_info);
|
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F("info"), System::command_info);
|
||||||
});
|
});
|
||||||
|
|
||||||
EMSESP::init_tx(); // start UART
|
EMSESP::init_tx(); // start UART
|
||||||
@@ -523,7 +523,7 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
|
|
||||||
EMSESPShell::commands->add_command(ShellContext::SYSTEM,
|
EMSESPShell::commands->add_command(ShellContext::SYSTEM,
|
||||||
CommandFlags::USER,
|
CommandFlags::USER,
|
||||||
flash_string_vector{F_(show)},
|
flash_string_vector{F_(show), F_(system)},
|
||||||
[=](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
[=](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||||
show_system(shell);
|
show_system(shell);
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|||||||
@@ -206,8 +206,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03});
|
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03});
|
||||||
|
|
||||||
shell.invoke_command("show");
|
shell.invoke_command("show");
|
||||||
// shell.invoke_command("system");
|
|
||||||
// shell.invoke_command("show mqtt");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "thermostat") {
|
if (command == "thermostat") {
|
||||||
@@ -409,11 +407,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
shell.loop_all();
|
shell.loop_all();
|
||||||
EMSESP::show_device_values(shell);
|
EMSESP::show_device_values(shell);
|
||||||
|
|
||||||
shell.invoke_command("thermostat");
|
shell.invoke_command("call thermostat mode auto");
|
||||||
shell.loop_all();
|
|
||||||
|
|
||||||
// shell.invoke_command("set temp 20");
|
|
||||||
shell.invoke_command("set mode auto");
|
|
||||||
|
|
||||||
shell.loop_all();
|
shell.loop_all();
|
||||||
EMSESP::show_ems(shell);
|
EMSESP::show_ems(shell);
|
||||||
@@ -576,12 +570,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
|
|
||||||
EMSESP::add_context_menus(); // need to add this as it happens later in the code
|
|
||||||
shell.invoke_command("su");
|
shell.invoke_command("su");
|
||||||
shell.invoke_command("system");
|
|
||||||
shell.invoke_command("call");
|
shell.invoke_command("call");
|
||||||
shell.invoke_command("call info");
|
shell.invoke_command("call system info");
|
||||||
shell.invoke_command("exit");
|
|
||||||
|
|
||||||
char system_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char system_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
strcpy(system_topic, "ems-esp/system");
|
strcpy(system_topic, "ems-esp/system");
|
||||||
@@ -595,24 +586,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x70, 0x00, 0xCF, 0x22, 0x2F, 0x10, 0x00, 0x2E, 0x24,
|
uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x70, 0x00, 0xCF, 0x22, 0x2F, 0x10, 0x00, 0x2E, 0x24,
|
||||||
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC2
|
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC2
|
||||||
uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); // HC3
|
uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); // HC3
|
||||||
EMSESP::add_context_menus(); // need to add this as it happens later in the code
|
|
||||||
shell.invoke_command("thermostat");
|
|
||||||
shell.invoke_command("show");
|
|
||||||
shell.invoke_command("call");
|
|
||||||
shell.invoke_command("call info");
|
|
||||||
shell.invoke_command("exit");
|
|
||||||
shell.invoke_command("show mqtt");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "pin") {
|
if (command == "pin") {
|
||||||
shell.printfln(F("Testing pin..."));
|
shell.printfln(F("Testing pin..."));
|
||||||
|
|
||||||
EMSESP::add_context_menus(); // need to add this as it happens later in the code
|
|
||||||
shell.invoke_command("su");
|
shell.invoke_command("su");
|
||||||
shell.invoke_command("system");
|
shell.invoke_command("call system pin");
|
||||||
shell.invoke_command("help");
|
shell.invoke_command("call system pin 1 true");
|
||||||
shell.invoke_command("pin");
|
|
||||||
shell.invoke_command("pin 1 true");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "mqtt") {
|
if (command == "mqtt") {
|
||||||
@@ -678,14 +659,12 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
// EMSESP::txservice_.show_tx_queue();
|
// EMSESP::txservice_.show_tx_queue();
|
||||||
// EMSESP::publish_all_values();
|
// EMSESP::publish_all_values();
|
||||||
|
|
||||||
EMSESP::add_context_menus(); // need to add this as it happens later in the code
|
|
||||||
shell.invoke_command("su");
|
shell.invoke_command("su");
|
||||||
shell.invoke_command("thermostat");
|
|
||||||
shell.invoke_command("help");
|
shell.invoke_command("help");
|
||||||
shell.invoke_command("call");
|
shell.invoke_command("call");
|
||||||
shell.invoke_command("call wwmode");
|
shell.invoke_command("call thermostat wwmode");
|
||||||
shell.invoke_command("call mode auto 2");
|
shell.invoke_command("call thermostat mode auto 2");
|
||||||
shell.invoke_command("call temp 22.56");
|
shell.invoke_command("call thermostat temp 22.56");
|
||||||
|
|
||||||
Mqtt::resubscribe();
|
Mqtt::resubscribe();
|
||||||
Mqtt::show_mqtt(shell); // show queue
|
Mqtt::show_mqtt(shell); // show queue
|
||||||
@@ -745,7 +724,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
// check for error "[emsesp] No telegram type handler found for ID 0x255 (src 0x20, dest 0x00)"
|
// check for error "[emsesp] No telegram type handler found for ID 0x255 (src 0x20, dest 0x00)"
|
||||||
rx_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A});
|
rx_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A});
|
||||||
|
|
||||||
EMSESP::add_context_menus(); // need to add this as it happens later in the code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally dump to console
|
// finally dump to console
|
||||||
|
|||||||
Reference in New Issue
Block a user