diff --git a/lib/uuid-syslog/src/syslog.cpp b/lib/uuid-syslog/src/syslog.cpp index 2d9bcd4e8..327b0c7d7 100644 --- a/lib/uuid-syslog/src/syslog.cpp +++ b/lib/uuid-syslog/src/syslog.cpp @@ -443,7 +443,6 @@ bool SyslogService::transmit(const QueuedLogMessage & message) { udp_.print('-'); } - // TODO should use flash? udp_.printf_P(PSTR(" %s %s - - - "), hostname_.c_str(), (message.content_->name)); char id_c_str[15]; diff --git a/src/command.cpp b/src/command.cpp index b4d85dd4c..47d3c2661 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -238,7 +238,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * value, const bool is_admin, const int8_t id, JsonObject & output) { uint8_t return_code = CommandRet::OK; - std::string dname = EMSdevice::device_type_2_device_name(device_type); + auto dname = EMSdevice::device_type_2_device_name(device_type); // see if there is a command registered auto cf = find_command(device_type, cmd); @@ -248,7 +248,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * if ((device_type > EMSdevice::DeviceType::SYSTEM) && (!value || !strlen(value))) { if (!cf || !cf->cmdfunction_json_) { #if defined(EMSESP_DEBUG) - LOG_DEBUG("[DEBUG] Calling %s command '%s' to retrieve attributes", dname.c_str(), cmd); + LOG_DEBUG("[DEBUG] Calling %s command '%s' to retrieve attributes", dname, cmd); #endif return EMSESP::get_device_value_info(output, cmd, id, device_type) ? CommandRet::OK : CommandRet::ERROR; // entity = cmd } @@ -262,17 +262,19 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * return CommandRet::NOT_ALLOWED; // command not allowed } + auto description = Helpers::translated_word(cf->description_); + if ((value == nullptr) || (strlen(value) == 0)) { if (EMSESP::system_.readonly_mode()) { - LOG_INFO("[readonly] Calling command '%s/%s' (%s)", dname.c_str(), cmd, Helpers::translated_word(cf->description_).c_str()); + LOG_INFO(("[readonly] Calling command '%s/%s' (%s)"), dname, cmd, description); } else { - LOG_DEBUG("Calling command '%s/%s' (%s)", dname.c_str(), cmd, Helpers::translated_word(cf->description_).c_str()); + LOG_DEBUG(("Calling command '%s/%s' (%s)"), dname, cmd, description); } } else { if (EMSESP::system_.readonly_mode()) { - LOG_INFO("[readonly] Calling command '%s/%s' (%s) with value %s", dname.c_str(), cmd, Helpers::translated_word(cf->description_).c_str(), value); + LOG_INFO(("[readonly] Calling command '%s/%s' (%s) with value %s"), dname, cmd, description, value); } else { - LOG_DEBUG("Calling command '%s/%s' (%s) with value %s", dname.c_str(), cmd, Helpers::translated_word(cf->description_).c_str(), value); + LOG_DEBUG(("Calling command '%s/%s' (%s) with value %s"), dname, cmd, description, value); } } @@ -366,9 +368,9 @@ bool Command::list(const uint8_t device_type, JsonObject & output) { for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { if (cf.has_flags(CommandFlag::MQTT_SUB_FLAG_WW)) { - output[cl] = EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW) + " " + Helpers::translated_fullname(cf.description_); + output[cl] = EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW) + " " + Helpers::translated_word(cf.description_); } else { - output[cl] = Helpers::translated_fullname(cf.description_); + output[cl] = Helpers::translated_word(cf.description_); } } } @@ -428,7 +430,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo shell.print(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW)); shell.print(' '); } - shell.print(Helpers::translated_fullname(cf.description_)); + shell.print(Helpers::translated_word(cf.description_)); if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) { shell.print(' '); shell.print(COLOR_BRIGHT_RED); @@ -478,19 +480,19 @@ bool Command::device_has_commands(const uint8_t device_type) { // list sensors and EMS devices void Command::show_devices(uuid::console::Shell & shell) { - shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM).c_str()); + shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM)); if (EMSESP::dallassensor_.have_sensors()) { - shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR).c_str()); + shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR)); } if (EMSESP::analogsensor_.have_sensors()) { - shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR).c_str()); + shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR)); } for (const auto & device_class : EMSFactory::device_handlers()) { for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice && (emsdevice->device_type() == device_class.first) && (device_has_commands(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)); break; // we only want to show one (not multiple of the same device types) } } @@ -506,7 +508,7 @@ void Command::show_all(uuid::console::Shell & shell) { // show system first shell.print(COLOR_BOLD_ON); shell.print(COLOR_YELLOW); - shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM).c_str()); + shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM)); shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::SYSTEM, true); @@ -514,14 +516,14 @@ void Command::show_all(uuid::console::Shell & shell) { if (EMSESP::dallassensor_.have_sensors()) { shell.print(COLOR_BOLD_ON); shell.print(COLOR_YELLOW); - shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR).c_str()); + shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR)); shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::DALLASSENSOR, true); } if (EMSESP::analogsensor_.have_sensors()) { shell.print(COLOR_BOLD_ON); shell.print(COLOR_YELLOW); - shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR).c_str()); + shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR)); shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::ANALOGSENSOR, true); } @@ -531,7 +533,7 @@ void Command::show_all(uuid::console::Shell & shell) { if (Command::device_has_commands(device_class.first)) { shell.print(COLOR_BOLD_ON); shell.print(COLOR_YELLOW); - 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)); shell.print(COLOR_RESET); show(shell, device_class.first, true); } diff --git a/src/console.cpp b/src/console.cpp index a973babe7..1cba1e74d 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -270,15 +270,16 @@ void EMSESPShell::add_console_commands() { [](Shell & shell, const std::vector & arguments) { uint16_t watch_id = WATCH_ID_NONE; + // only use english commands, not the translations if (!arguments.empty()) { // get raw/pretty if (arguments[0] == (F_(raw))) { EMSESP::watch(EMSESP::WATCH_RAW); // raw - } else if (arguments[0] == Helpers::translated_word(FL_(on), true) || arguments[0] == (FL_(on)[0])) { + } else if (arguments[0] == (FL_(on)[0])) { EMSESP::watch(EMSESP::WATCH_ON); // on - } else if (arguments[0] == Helpers::translated_word(FL_(off), true) || arguments[0] == (FL_(off)[0])) { + } else if (arguments[0] == (FL_(off)[0])) { EMSESP::watch(EMSESP::WATCH_OFF); // off - } else if (arguments[0] == Helpers::translated_word(FL_(unknown), true) || arguments[0] == (FL_(unknown)[0])) { + } else if (arguments[0] == (FL_(unknown)[0])) { EMSESP::watch(EMSESP::WATCH_UNKNOWN); // unknown watch_id = WATCH_ID_NONE; } else { diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index d0fd39459..dba21e39b 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -2227,7 +2227,7 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) { std::string s; if (Helpers::value2string(value, s)) { - if (s == Helpers::translated_word(FL_(reset))) { + if (s == std::string(Helpers::translated_word(FL_(reset)))) { // LOG_INFO("Reset boiler maintenance message"); write_command(0x05, 0x08, 0xFF, 0x1C); return true; diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 5b12d7661..e496c3d75 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -594,7 +594,6 @@ void Thermostat::process_RC20Timer(std::shared_ptr telegram) { // we use EN settings for the day abbreviation std::string sday = (FL_(enum_dayOfWeek)[day][0]); - // std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]); if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); @@ -796,19 +795,10 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { char data[sizeof(wwSwitchTime_)]; // we use EN settings for the day abbreviation std::string sday = (FL_(enum_dayOfWeek)[day][0]); - // std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]); if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); } else { - snprintf(data, - sizeof(data), - "%02d %s %02d:%02d %s", - no, - sday.c_str(), - time / 6, - 10 * (time % 6), - // on ? (Helpers::translated_word(FL_(on))).c_str() : (Helpers::translated_word(FL_(off))).c_str()); - on ? "on" : "off"); + snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off"); } if (telegram->type_id == 0x38) { has_update(wwSwitchTime_, data, sizeof(wwSwitchTime_)); @@ -1275,7 +1265,6 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { // we use EN settings for the day abbreviation std::string sday = (FL_(enum_dayOfWeek)[day][0]); - // std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]); if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); } else if (model() == EMS_DEVICE_FLAG_RC30) { @@ -2214,82 +2203,93 @@ bool Thermostat::set_roominfl_factor(const char * value, const int8_t id) { return true; } -// sets the thermostat working mode, where mode is a string -// converts string mode to HeatingCircuit::Mode +// sets the thermostat working mode bool Thermostat::set_mode(const char * value, const int8_t id) { if ((value == nullptr) || (strlen(value) >= 20)) { return false; } - std::string mode; - - if (value[0] >= '0' && value[0] <= '9') { - uint8_t num = value[0] - '0'; - switch (model()) { - case EMSdevice::EMS_DEVICE_FLAG_RC10: - mode = Helpers::translated_word(FL_(enum_mode6)[num], true); - break; - case EMSdevice::EMS_DEVICE_FLAG_RC20: - case EMSdevice::EMS_DEVICE_FLAG_RC20_N: - mode = Helpers::translated_word(FL_(enum_mode2)[num], true); - break; - case EMSdevice::EMS_DEVICE_FLAG_RC25: - case EMSdevice::EMS_DEVICE_FLAG_RC30: - case EMSdevice::EMS_DEVICE_FLAG_RC35: - case EMSdevice::EMS_DEVICE_FLAG_RC30_N: - mode = Helpers::translated_word(FL_(enum_mode3)[num], true); - break; - case EMSdevice::EMS_DEVICE_FLAG_RC300: - case EMSdevice::EMS_DEVICE_FLAG_RC100: - mode = Helpers::translated_word(FL_(enum_mode)[num], true); - break; - case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: - mode = Helpers::translated_word(FL_(enum_mode4)[num], true); - break; - case EMSdevice::EMS_DEVICE_FLAG_CRF: - mode = Helpers::translated_word(FL_(enum_mode5)[num], true); - break; - default: - return false; - } - } else if (!Helpers::value2string(value, mode)) { + // first determine which enum we are using + const char * const ** mode_list = nullptr; // points to a translated list of modes + switch (model()) { + case EMSdevice::EMS_DEVICE_FLAG_RC10: + mode_list = FL_(enum_mode6); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC20: + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: + mode_list = FL_(enum_mode2); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC25: + case EMSdevice::EMS_DEVICE_FLAG_RC30: + case EMSdevice::EMS_DEVICE_FLAG_RC35: + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: + mode_list = FL_(enum_mode3); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_RC100: + mode_list = FL_(enum_mode); + break; + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: + mode_list = FL_(enum_mode4); + break; + case EMSdevice::EMS_DEVICE_FLAG_CRF: + mode_list = FL_(enum_mode5); + break; + default: return false; } - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + uint8_t enum_index = 0; - if (Helpers::translated_word(FL_(off), true) == mode) { - return set_mode_n(HeatingCircuit::Mode::OFF, hc_num); + // check for a mode number as a string with a single digit (0..9) + if (value[0] >= '0' && value[0] <= '9') { + enum_index = value[0] - '0'; + if (enum_index >= Helpers::count_items(mode_list)) { + return false; // invalid number, not in enum + } + } else { + // check for the mode being a full string name + if (!Helpers::value2enum(value, enum_index, mode_list)) { + return false; // not found + } } - if (Helpers::translated_word(FL_(manual), true) == mode) { - return set_mode_n(HeatingCircuit::Mode::MANUAL, hc_num); - } - if (Helpers::translated_word(FL_(auto), true) == mode) { + + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; // heating circuit + + // compare the english string + auto mode = mode_list[enum_index][0]; + if (!strcmp(mode, FL_(auto)[0])) { return set_mode_n(HeatingCircuit::Mode::AUTO, hc_num); } - if (Helpers::translated_word(FL_(day), true) == mode) { + if (!strcmp(mode, FL_(off)[0])) { + return set_mode_n(HeatingCircuit::Mode::OFF, hc_num); + } + if (!strcmp(mode, FL_(manual)[0])) { + return set_mode_n(HeatingCircuit::Mode::MANUAL, hc_num); + } + if (!strcmp(mode, FL_(day)[0])) { return set_mode_n(HeatingCircuit::Mode::DAY, hc_num); } - if (Helpers::translated_word(FL_(night), true) == mode) { + if (!strcmp(mode, FL_(night)[0])) { return set_mode_n(HeatingCircuit::Mode::NIGHT, hc_num); } - if (Helpers::translated_word(FL_(heat), true) == mode) { + if (!strcmp(mode, FL_(heat)[0])) { return set_mode_n(HeatingCircuit::Mode::HEAT, hc_num); } - if (Helpers::translated_word(FL_(nofrost), true) == mode) { + if (!strcmp(mode, FL_(nofrost)[0])) { return set_mode_n(HeatingCircuit::Mode::NOFROST, hc_num); } - if (Helpers::translated_word(FL_(eco), true) == mode) { + if (!strcmp(mode, FL_(eco)[0])) { return set_mode_n(HeatingCircuit::Mode::ECO, hc_num); } - if (Helpers::translated_word(FL_(holiday), true) == mode) { + if (!strcmp(mode, FL_(holiday)[0])) { return set_mode_n(HeatingCircuit::Mode::HOLIDAY, hc_num); } - if (Helpers::translated_word(FL_(comfort), true) == mode) { + if (!strcmp(mode, FL_(comfort)[0])) { return set_mode_n(HeatingCircuit::Mode::COMFORT, hc_num); } - return false; + return false; // not found } // Set the thermostat working mode @@ -2312,14 +2312,12 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { case HeatingCircuit::Mode::OFF: set_mode_value = 0; break; - case HeatingCircuit::Mode::DAY: case HeatingCircuit::Mode::HEAT: case HeatingCircuit::Mode::MANUAL: case HeatingCircuit::Mode::NOFROST: set_mode_value = 1; break; - default: // AUTO & ECO set_mode_value = 2; break; @@ -2684,11 +2682,6 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (!strncmp(&value[3], (FL_(enum_dayOfWeek)[i][0]), 2)) { day = i; } - - // auto translated_dow = Helpers::translated_word(FL_(enum_dayOfWeek)[i]); - // if (!strncmp(&value[3], translated_dow.c_str(), translated_dow.length())) { - // day = i; - // } } } if (strlen(value) > 10) { @@ -2728,14 +2721,12 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (data[0] != 0xE7) { // we use EN settings for the day abbreviation std::string sday = (FL_(enum_dayOfWeek)[day][0]); - // std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]); if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off"); } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), on); } else { std::string son = (FL_(enum_switchmode)[on][0]); - // std::string son = Helpers::translated_word(FL_(enum_switchmode)[on]); snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), son.c_str()); } } else { diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 0b2850807..29104e414 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -81,7 +81,7 @@ std::string EMSdevice::brand_to_string() const { } // returns the name of the MQTT topic to use for a specific device, without the base -std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) { +const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) { switch (device_type) { case DeviceType::SYSTEM: return F_(system); @@ -259,7 +259,7 @@ bool EMSdevice::has_tag(const uint8_t tag) const { // called from the command 'entities' void EMSdevice::list_device_entries(JsonObject & output) const { for (const auto & dv : devicevalues_) { - std::string fullname = dv.get_fullname(); + auto fullname = dv.get_fullname(); if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && !fullname.empty()) { // if we have a tag prefix it char key[50]; @@ -637,9 +637,9 @@ void EMSdevice::publish_value(void * value_p) const { char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; if (Mqtt::publish_single2cmd()) { if (dv.tag >= DeviceValueTAG::TAG_HC1) { - snprintf(topic, sizeof(topic), "%s/%s/%s", device_type_2_device_name(device_type_).c_str(), tag_to_mqtt(dv.tag).c_str(), dv.short_name); + snprintf(topic, sizeof(topic), "%s/%s/%s", device_type_2_device_name(device_type_), tag_to_mqtt(dv.tag).c_str(), dv.short_name); } else { - snprintf(topic, sizeof(topic), "%s/%s", device_type_2_device_name(device_type_).c_str(), dv.short_name); + snprintf(topic, sizeof(topic), "%s/%s", device_type_2_device_name(device_type_), (dv.short_name)); } } else if (Mqtt::is_nested() && dv.tag >= DeviceValueTAG::TAG_HC1) { snprintf(topic, sizeof(topic), "%s/%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), tag_to_mqtt(dv.tag).c_str(), dv.short_name); @@ -662,7 +662,7 @@ void EMSdevice::publish_value(void * value_p) const { Helpers::render_value(payload, *(uint8_t *)(value_p), 0); } else { auto enum_str = Helpers::translated_word(dv.options[*(uint8_t *)(value_p)]); - strlcpy(payload, enum_str.c_str(), sizeof(payload)); + strlcpy(payload, enum_str, sizeof(payload)); } } break; @@ -714,9 +714,9 @@ std::string EMSdevice::get_value_uom(const char * key) const { for (uint8_t i = 0; i < DeviceValue::tag_count; i++) { auto tag = Helpers::translated_word(DeviceValue::DeviceValueTAG_s[i]); - if (tag.empty()) { + if (tag) { std::string key2 = key; // copy string to a std::string so we can use the find function - uint8_t length = tag.length(); + uint8_t length = strlen(tag); if ((key2.find(tag) != std::string::npos) && (key[length] == ' ')) { key_p += length + 1; // remove the tag break; @@ -823,7 +823,7 @@ void EMSdevice::generate_values_web(JsonObject & output) { JsonArray l = obj.createNestedArray("l"); for (uint8_t i = 0; i < dv.options_size; i++) { auto enum_str = Helpers::translated_word(dv.options[i]); - if (!enum_str.empty()) { + if (enum_str) { l.add(enum_str); } } @@ -917,12 +917,12 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) { // don't add the fullname if its a command auto fullname = Helpers::translated_word(dv.fullname); if (dv.type != DeviceValueType::CMD) { - if (!fullname.empty()) { + if (fullname) { if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { obj["n"] = fullname; } else { char name[50]; - snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), fullname.c_str()); + snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), fullname); obj["n"] = name; } } @@ -933,7 +933,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) { obj["cn"] = custom_fullname; } } else { - obj["n"] = "!" + fullname; // prefix commands with a ! + obj["n"] = "!" + std::string(fullname); // prefix commands with a ! } obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble @@ -1357,11 +1357,11 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c sizeof(time_s), "%d %s %d %s %d %s", (time_value / 1440), - Helpers::translated_word(FL_(days)).c_str(), + Helpers::translated_word(FL_(days)), ((time_value % 1440) / 60), - Helpers::translated_word(FL_(hours)).c_str(), + Helpers::translated_word(FL_(hours)), (time_value % 60), - Helpers::translated_word(FL_(minutes)).c_str()); + Helpers::translated_word(FL_(minutes))); json[name] = time_s; } else { json[name] = time_value; diff --git a/src/emsdevice.h b/src/emsdevice.h index d4ea9ad0d..6a582e982 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -46,11 +46,11 @@ class EMSdevice { std::string device_type_name() const; - static std::string device_type_2_device_name(const uint8_t device_type); - static uint8_t device_name_2_device_type(const char * topic); - static std::string uom_to_string(uint8_t uom); - static std::string tag_to_string(uint8_t tag); - static std::string tag_to_mqtt(uint8_t tag); + static const char * device_type_2_device_name(const uint8_t device_type); + static uint8_t device_name_2_device_type(const char * topic); + static std::string uom_to_string(uint8_t uom); + static std::string tag_to_string(uint8_t tag); + static std::string tag_to_mqtt(uint8_t tag); bool has_tag(const uint8_t tag) const; diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index 3d30f23b4..29d4e7d2e 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -74,7 +74,7 @@ DeviceValue::DeviceValue(uint8_t device_type, Serial.print(custom_fullname.c_str()); Serial.print(COLOR_RESET); } else { - Serial.print(Helpers::translated_word(fullname).c_str()); + Serial.print(Helpers::translated_word(fullname)); } Serial.print(" (#options="); Serial.print(options_size); @@ -88,7 +88,7 @@ DeviceValue::DeviceValue(uint8_t device_type, Serial.print(i + 1); Serial.print(":"); auto str = Helpers::translated_word(options[i]); - Serial.print((str.c_str())); + Serial.print(str); i++; } } else if (options_single != nullptr) { diff --git a/src/emsesp.cpp b/src/emsesp.cpp index c761df689..b4aed3c7f 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1039,7 +1039,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const fetch_device_values(device_id); // go and fetch its data // Print to LOG showing we've added a new device - LOG_INFO("Recognized new %s with deviceID 0x%02X", EMSdevice::device_type_2_device_name(device_type).c_str(), device_id); + LOG_INFO("Recognized new %s with deviceID 0x%02X", EMSdevice::device_type_2_device_name(device_type), device_id); // add command commands for all devices, except for connect, controller and gateway if ((device_type == DeviceType::CONNECT) || (device_type == DeviceType::CONTROLLER) || (device_type == DeviceType::GATEWAY)) { @@ -1073,7 +1073,8 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const FL_(entities_cmd)); // MQTT subscribe to the device e.g. "ems-esp/boiler/#" - Mqtt::subscribe(device_type, EMSdevice::device_type_2_device_name(device_type) + "/#", nullptr); + auto topic = std::string(EMSdevice::device_type_2_device_name(device_type)) + "/#"; + Mqtt::subscribe(device_type, topic, nullptr); return true; } diff --git a/src/helpers.cpp b/src/helpers.cpp index 2a248bce2..ce2ea6eb3 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -179,9 +179,9 @@ char * Helpers::render_boolean(char * result, const bool value, const bool dashb uint8_t bool_format_ = dashboard ? EMSESP::system_.bool_dashboard() : EMSESP::system_.bool_format(); if (bool_format_ == BOOL_FORMAT_ONOFF_STR) { - strlcpy(result, value ? translated_word(FL_(on)).c_str() : translated_word(FL_(off)).c_str(), 5); + strlcpy(result, value ? translated_word(FL_(on)) : translated_word(FL_(off)), 5); } else if (bool_format_ == BOOL_FORMAT_ONOFF_STR_CAP) { - strlcpy(result, value ? translated_word(FL_(ON)).c_str() : translated_word(FL_(OFF)).c_str(), 5); + strlcpy(result, value ? translated_word(FL_(ON)) : translated_word(FL_(OFF)), 5); } else if ((bool_format_ == BOOL_FORMAT_10) || (bool_format_ == BOOL_FORMAT_10_STR)) { strlcpy(result, value ? "1" : "0", 2); } else { @@ -593,12 +593,12 @@ bool Helpers::value2bool(const char * value, bool & value_b) { std::string bool_str = toLower(value); // convert to lower case - if ((bool_str == Helpers::translated_word(FL_(on))) || (bool_str == "on") || (bool_str == "1") || (bool_str == "true")) { + if ((bool_str == std::string(Helpers::translated_word(FL_(on)))) || (bool_str == "on") || (bool_str == "1") || (bool_str == "true")) { value_b = true; return true; // is a bool } - if ((bool_str == Helpers::translated_word(FL_(off))) || (bool_str == "off") || (bool_str == "0") || (bool_str == "false")) { + if ((bool_str == std::string(Helpers::translated_word(FL_(off)))) || (bool_str == "off") || (bool_str == "0") || (bool_str == "false")) { value_b = false; return true; // is a bool } @@ -615,7 +615,7 @@ bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * co std::string str = toLower(value); for (value_ui = 0; strs[value_ui]; value_ui++) { - std::string str1 = toLower(Helpers::translated_word(strs[value_ui])); + std::string str1 = toLower(std::string(Helpers::translated_word(strs[value_ui]))); std::string str2 = toLower((strs[value_ui][0])); // also check for default language if ((str1 != "") && ((str2 == "off" && str == "false") || (str2 == "on" && str == "true") || (str == str1) || (str == str2) @@ -627,19 +627,25 @@ bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * co return false; } -// checks to see if a string is member of a vector and return the index, also allow true/false for on/off +// finds the string (value) of a list vector (strs) +// returns true if found, and sets the value_ui to the index, else false +// also allow true/false for on/off bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * const * strs) { if ((value == nullptr) || (strlen(value) == 0)) { return false; } std::string str = toLower(value); + std::string s_on = Helpers::translated_word(FL_(on)); + std::string s_off = Helpers::translated_word(FL_(off)); + + // stops when a nullptr is found, which is the end delimeter of a MAKE_PSTR_LIST() + // could use count_items() to avoid buffer over-run but this works for (value_ui = 0; strs[value_ui]; value_ui++) { std::string enum_str = toLower((strs[value_ui])); if ((enum_str != "") - && ((enum_str == "off" && (str == Helpers::translated_word(FL_(off)) || str == "false")) - || (enum_str == "on" && (str == Helpers::translated_word(FL_(on)) || str == "true")) || (str == enum_str) + && ((enum_str == "off" && (str == s_off || str == "false")) || (enum_str == "on" && (str == s_on || str == "true")) || (str == enum_str) || (value[0] == ('0' + value_ui) && value[1] == '\0'))) { return true; } @@ -702,31 +708,13 @@ uint8_t Helpers::count_items(const char * const ** list) { return list_size; } -// return translated string as a std::string, optionally converting to lowercase (for console commands) -std::string Helpers::translated_word(const char * const * strings, bool to_lower) { - uint8_t language_index = EMSESP::system_.language_index(); - uint8_t index = 0; - - // check for empty - if (!strings) { - return ""; // it's a nullptr with no translations, return empty to prevent unwanted crash - } - - // see how many translations we have for this entity. if there is no translation for this, revert to EN - if (Helpers::count_items(strings) >= language_index + 1 && strlen(strings[language_index])) { - index = language_index; - } - return to_lower ? toLower((strings[index])) : (strings[index]); -} - // returns char pointer to translated description or fullname -const char * Helpers::translated_fullname(const char * const * strings) { +const char * Helpers::translated_word(const char * const * strings) { uint8_t language_index = EMSESP::system_.language_index(); uint8_t index = 0; - // check for empty if (!strings) { - return nullptr; // it's a nullptr with no translations, return empty to prevent unwanted crash + return ""; // no translations } // see how many translations we have for this entity. if there is no translation for this, revert to EN diff --git a/src/helpers.h b/src/helpers.h index 0c164f283..95fa7a5db 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -77,9 +77,7 @@ class Helpers { static uint8_t count_items(const char * const ** list); static uint8_t count_items(const char * const * list); - static std::string translated_word(const char * const * strings, bool to_lower = false); - static const char * translated_fullname(const char * const * strings); - + static const char * translated_word(const char * const * strings); #ifdef EMSESP_STANDALONE static char * ultostr(char * ptr, uint32_t value, const uint8_t base); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 18e042339..251dafdd4 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -899,15 +899,16 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model, StaticJsonDocument dev_json; // always create the ids - JsonArray ids = dev_json.createNestedArray("ids"); - char ha_device[40]; - std::string device_type_name = EMSdevice::device_type_2_device_name(dv.device_type); - snprintf(ha_device, sizeof(ha_device), "ems-esp-%s", device_type_name.c_str()); + JsonArray ids = dev_json.createNestedArray("ids"); + char ha_device[40]; + auto device_type_name = EMSdevice::device_type_2_device_name(dv.device_type); + snprintf(ha_device, sizeof(ha_device), "ems-esp-%s", device_type_name); ids.add(ha_device); if (create_device_config) { - device_type_name[0] = toupper(device_type_name[0]); // capitalize - dev_json["name"] = "EMS-ESP " + device_type_name; + auto cap_name = strdup(device_type_name); + cap_name[0] = toupper(cap_name[0]); // capitalize + dev_json["name"] = std::string("EMS-ESP ") + cap_name; dev_json["mf"] = brand; dev_json["mdl"] = model; dev_json["via_device"] = "ems-esp"; @@ -972,8 +973,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice } // create the device name - char device_name[50]; - strlcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str(), sizeof(device_name)); + auto device_name = EMSdevice::device_type_2_device_name(device_type); // create entity by add the hc/wwc tag if present, separating with a . char new_entity[50]; @@ -1341,11 +1341,13 @@ std::string Mqtt::tag_to_topic(uint8_t device_type, uint8_t tag) { return EMSdevice::tag_to_mqtt(tag); } + std::string topic = EMSdevice::device_type_2_device_name(device_type); + // if there is a tag add it if (!EMSdevice::tag_to_mqtt(tag).empty() && ((tag == DeviceValueTAG::TAG_BOILER_DATA_WW) || (!is_nested() && tag >= DeviceValueTAG::TAG_HC1))) { - return EMSdevice::device_type_2_device_name(device_type) + "_data_" + EMSdevice::tag_to_mqtt(tag); + return topic + "_data_" + EMSdevice::tag_to_mqtt(tag); } else { - return EMSdevice::device_type_2_device_name(device_type) + "_data"; + return topic + "_data"; } } diff --git a/src/test/test.cpp b/src/test/test.cpp index be722d6df..f791b5f9d 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -246,6 +246,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("show mqtt"); } + if (command == "modes") { + shell.printfln("Testing thermostat modes..."); + run_test("general"); + shell.invoke_command("call thermostat mode auto"); + shell.invoke_command("call thermostat mode Manuell"); // DE + shell.invoke_command("call thermostat mode 1"); + } + if (command == "render") { shell.printfln("Testing render...");