This commit is contained in:
MichaelDvP
2022-10-11 09:34:56 +02:00
13 changed files with 146 additions and 156 deletions

View File

@@ -443,7 +443,6 @@ bool SyslogService::transmit(const QueuedLogMessage & message) {
udp_.print('-'); udp_.print('-');
} }
// TODO should use flash?
udp_.printf_P(PSTR(" %s %s - - - "), hostname_.c_str(), (message.content_->name)); udp_.printf_P(PSTR(" %s %s - - - "), hostname_.c_str(), (message.content_->name));
char id_c_str[15]; char id_c_str[15];

View File

@@ -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 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; 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 // see if there is a command registered
auto cf = find_command(device_type, cmd); 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 ((device_type > EMSdevice::DeviceType::SYSTEM) && (!value || !strlen(value))) {
if (!cf || !cf->cmdfunction_json_) { if (!cf || !cf->cmdfunction_json_) {
#if defined(EMSESP_DEBUG) #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 #endif
return EMSESP::get_device_value_info(output, cmd, id, device_type) ? CommandRet::OK : CommandRet::ERROR; // entity = cmd 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 return CommandRet::NOT_ALLOWED; // command not allowed
} }
auto description = Helpers::translated_word(cf->description_);
if ((value == nullptr) || (strlen(value) == 0)) { if ((value == nullptr) || (strlen(value) == 0)) {
if (EMSESP::system_.readonly_mode()) { 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 { } 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 { } else {
if (EMSESP::system_.readonly_mode()) { 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 { } 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_) { 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.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)) { 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 { } 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(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW));
shell.print(' '); shell.print(' ');
} }
shell.print(Helpers::translated_fullname(cf.description_)); shell.print(Helpers::translated_word(cf.description_));
if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) { if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) {
shell.print(' '); shell.print(' ');
shell.print(COLOR_BRIGHT_RED); shell.print(COLOR_BRIGHT_RED);
@@ -478,19 +480,19 @@ bool Command::device_has_commands(const uint8_t device_type) {
// list sensors and EMS devices // list sensors and EMS devices
void Command::show_devices(uuid::console::Shell & shell) { 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()) { 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()) { 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 & device_class : EMSFactory::device_handlers()) {
for (const auto & emsdevice : EMSESP::emsdevices) { for (const auto & emsdevice : EMSESP::emsdevices) {
if (emsdevice && (emsdevice->device_type() == device_class.first) && (device_has_commands(device_class.first))) { 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) 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 // show system first
shell.print(COLOR_BOLD_ON); shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW); 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); shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::SYSTEM, true); show(shell, EMSdevice::DeviceType::SYSTEM, true);
@@ -514,14 +516,14 @@ void Command::show_all(uuid::console::Shell & shell) {
if (EMSESP::dallassensor_.have_sensors()) { if (EMSESP::dallassensor_.have_sensors()) {
shell.print(COLOR_BOLD_ON); shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW); 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); shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::DALLASSENSOR, true); show(shell, EMSdevice::DeviceType::DALLASSENSOR, true);
} }
if (EMSESP::analogsensor_.have_sensors()) { if (EMSESP::analogsensor_.have_sensors()) {
shell.print(COLOR_BOLD_ON); shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW); 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); shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::ANALOGSENSOR, true); 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)) { if (Command::device_has_commands(device_class.first)) {
shell.print(COLOR_BOLD_ON); shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW); 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); shell.print(COLOR_RESET);
show(shell, device_class.first, true); show(shell, device_class.first, true);
} }

View File

@@ -270,15 +270,16 @@ void EMSESPShell::add_console_commands() {
[](Shell & shell, const std::vector<std::string> & arguments) { [](Shell & shell, const std::vector<std::string> & arguments) {
uint16_t watch_id = WATCH_ID_NONE; uint16_t watch_id = WATCH_ID_NONE;
// only use english commands, not the translations
if (!arguments.empty()) { if (!arguments.empty()) {
// get raw/pretty // get raw/pretty
if (arguments[0] == (F_(raw))) { if (arguments[0] == (F_(raw))) {
EMSESP::watch(EMSESP::WATCH_RAW); // 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 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 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 EMSESP::watch(EMSESP::WATCH_UNKNOWN); // unknown
watch_id = WATCH_ID_NONE; watch_id = WATCH_ID_NONE;
} else { } else {

View File

@@ -2227,7 +2227,7 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
std::string s; std::string s;
if (Helpers::value2string(value, 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"); // LOG_INFO("Reset boiler maintenance message");
write_command(0x05, 0x08, 0xFF, 0x1C); write_command(0x05, 0x08, 0xFF, 0x1C);
return true; return true;

View File

@@ -594,7 +594,6 @@ void Thermostat::process_RC20Timer(std::shared_ptr<const Telegram> telegram) {
// we use EN settings for the day abbreviation // we use EN settings for the day abbreviation
std::string sday = (FL_(enum_dayOfWeek)[day][0]); std::string sday = (FL_(enum_dayOfWeek)[day][0]);
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
@@ -796,19 +795,10 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr<const Telegram> telegram) {
char data[sizeof(wwSwitchTime_)]; char data[sizeof(wwSwitchTime_)];
// we use EN settings for the day abbreviation // we use EN settings for the day abbreviation
std::string sday = (FL_(enum_dayOfWeek)[day][0]); std::string sday = (FL_(enum_dayOfWeek)[day][0]);
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else { } else {
snprintf(data, snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off");
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");
} }
if (telegram->type_id == 0x38) { if (telegram->type_id == 0x38) {
has_update(wwSwitchTime_, data, sizeof(wwSwitchTime_)); has_update(wwSwitchTime_, data, sizeof(wwSwitchTime_));
@@ -1275,7 +1265,6 @@ void Thermostat::process_RC35Timer(std::shared_ptr<const Telegram> telegram) {
// we use EN settings for the day abbreviation // we use EN settings for the day abbreviation
std::string sday = (FL_(enum_dayOfWeek)[day][0]); std::string sday = (FL_(enum_dayOfWeek)[day][0]);
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else if (model() == EMS_DEVICE_FLAG_RC30) { } 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; return true;
} }
// sets the thermostat working mode, where mode is a string // sets the thermostat working mode
// converts string mode to HeatingCircuit::Mode
bool Thermostat::set_mode(const char * value, const int8_t id) { bool Thermostat::set_mode(const char * value, const int8_t id) {
if ((value == nullptr) || (strlen(value) >= 20)) { if ((value == nullptr) || (strlen(value) >= 20)) {
return false; return false;
} }
std::string mode; // first determine which enum we are using
const char * const ** mode_list = nullptr; // points to a translated list of modes
if (value[0] >= '0' && value[0] <= '9') {
uint8_t num = value[0] - '0';
switch (model()) { switch (model()) {
case EMSdevice::EMS_DEVICE_FLAG_RC10: case EMSdevice::EMS_DEVICE_FLAG_RC10:
mode = Helpers::translated_word(FL_(enum_mode6)[num], true); mode_list = FL_(enum_mode6);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC20: case EMSdevice::EMS_DEVICE_FLAG_RC20:
case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC20_N:
mode = Helpers::translated_word(FL_(enum_mode2)[num], true); mode_list = FL_(enum_mode2);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC25: case EMSdevice::EMS_DEVICE_FLAG_RC25:
case EMSdevice::EMS_DEVICE_FLAG_RC30: case EMSdevice::EMS_DEVICE_FLAG_RC30:
case EMSdevice::EMS_DEVICE_FLAG_RC35: case EMSdevice::EMS_DEVICE_FLAG_RC35:
case EMSdevice::EMS_DEVICE_FLAG_RC30_N: case EMSdevice::EMS_DEVICE_FLAG_RC30_N:
mode = Helpers::translated_word(FL_(enum_mode3)[num], true); mode_list = FL_(enum_mode3);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC300:
case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC100:
mode = Helpers::translated_word(FL_(enum_mode)[num], true); mode_list = FL_(enum_mode);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: case EMSdevice::EMS_DEVICE_FLAG_JUNKERS:
mode = Helpers::translated_word(FL_(enum_mode4)[num], true); mode_list = FL_(enum_mode4);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_CRF: case EMSdevice::EMS_DEVICE_FLAG_CRF:
mode = Helpers::translated_word(FL_(enum_mode5)[num], true); mode_list = FL_(enum_mode5);
break; break;
default: default:
return false; return false;
} }
} else if (!Helpers::value2string(value, mode)) {
return false; uint8_t enum_index = 0;
// 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
}
} }
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; // heating circuit
if (Helpers::translated_word(FL_(off), true) == mode) { // compare the english string
return set_mode_n(HeatingCircuit::Mode::OFF, hc_num); auto mode = mode_list[enum_index][0];
} if (!strcmp(mode, FL_(auto)[0])) {
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) {
return set_mode_n(HeatingCircuit::Mode::AUTO, hc_num); 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); 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); 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); 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); 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); 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); 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 set_mode_n(HeatingCircuit::Mode::COMFORT, hc_num);
} }
return false; return false; // not found
} }
// Set the thermostat working mode // 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: case HeatingCircuit::Mode::OFF:
set_mode_value = 0; set_mode_value = 0;
break; break;
case HeatingCircuit::Mode::DAY: case HeatingCircuit::Mode::DAY:
case HeatingCircuit::Mode::HEAT: case HeatingCircuit::Mode::HEAT:
case HeatingCircuit::Mode::MANUAL: case HeatingCircuit::Mode::MANUAL:
case HeatingCircuit::Mode::NOFROST: case HeatingCircuit::Mode::NOFROST:
set_mode_value = 1; set_mode_value = 1;
break; break;
default: // AUTO & ECO default: // AUTO & ECO
set_mode_value = 2; set_mode_value = 2;
break; 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)) { if (!strncmp(&value[3], (FL_(enum_dayOfWeek)[i][0]), 2)) {
day = i; 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) { 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) { if (data[0] != 0xE7) {
// we use EN settings for the day abbreviation // we use EN settings for the day abbreviation
std::string sday = (FL_(enum_dayOfWeek)[day][0]); 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) { 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"); 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)) { } 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); snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), on);
} else { } else {
std::string son = (FL_(enum_switchmode)[on][0]); 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()); snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), son.c_str());
} }
} else { } else {

View File

@@ -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 // 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) { switch (device_type) {
case DeviceType::SYSTEM: case DeviceType::SYSTEM:
return F_(system); return F_(system);
@@ -259,7 +259,7 @@ bool EMSdevice::has_tag(const uint8_t tag) const {
// called from the command 'entities' // called from the command 'entities'
void EMSdevice::list_device_entries(JsonObject & output) const { void EMSdevice::list_device_entries(JsonObject & output) const {
for (const auto & dv : devicevalues_) { 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 (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && !fullname.empty()) {
// if we have a tag prefix it // if we have a tag prefix it
char key[50]; char key[50];
@@ -637,9 +637,9 @@ void EMSdevice::publish_value(void * value_p) const {
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
if (Mqtt::publish_single2cmd()) { if (Mqtt::publish_single2cmd()) {
if (dv.tag >= DeviceValueTAG::TAG_HC1) { 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 { } 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) { } 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); 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); Helpers::render_value(payload, *(uint8_t *)(value_p), 0);
} else { } else {
auto enum_str = Helpers::translated_word(dv.options[*(uint8_t *)(value_p)]); 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; 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++) { for (uint8_t i = 0; i < DeviceValue::tag_count; i++) {
auto tag = Helpers::translated_word(DeviceValue::DeviceValueTAG_s[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 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] == ' ')) { if ((key2.find(tag) != std::string::npos) && (key[length] == ' ')) {
key_p += length + 1; // remove the tag key_p += length + 1; // remove the tag
break; break;
@@ -823,7 +823,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
JsonArray l = obj.createNestedArray("l"); JsonArray l = obj.createNestedArray("l");
for (uint8_t i = 0; i < dv.options_size; i++) { for (uint8_t i = 0; i < dv.options_size; i++) {
auto enum_str = Helpers::translated_word(dv.options[i]); auto enum_str = Helpers::translated_word(dv.options[i]);
if (!enum_str.empty()) { if (enum_str) {
l.add(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 // don't add the fullname if its a command
auto fullname = Helpers::translated_word(dv.fullname); auto fullname = Helpers::translated_word(dv.fullname);
if (dv.type != DeviceValueType::CMD) { if (dv.type != DeviceValueType::CMD) {
if (!fullname.empty()) { if (fullname) {
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["n"] = fullname; obj["n"] = fullname;
} else { } else {
char name[50]; 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; obj["n"] = name;
} }
} }
@@ -933,7 +933,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
obj["cn"] = custom_fullname; obj["cn"] = custom_fullname;
} }
} else { } 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 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), sizeof(time_s),
"%d %s %d %s %d %s", "%d %s %d %s %d %s",
(time_value / 1440), (time_value / 1440),
Helpers::translated_word(FL_(days)).c_str(), Helpers::translated_word(FL_(days)),
((time_value % 1440) / 60), ((time_value % 1440) / 60),
Helpers::translated_word(FL_(hours)).c_str(), Helpers::translated_word(FL_(hours)),
(time_value % 60), (time_value % 60),
Helpers::translated_word(FL_(minutes)).c_str()); Helpers::translated_word(FL_(minutes)));
json[name] = time_s; json[name] = time_s;
} else { } else {
json[name] = time_value; json[name] = time_value;

View File

@@ -46,7 +46,7 @@ class EMSdevice {
std::string device_type_name() const; std::string device_type_name() const;
static std::string device_type_2_device_name(const uint8_t device_type); 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 uint8_t device_name_2_device_type(const char * topic);
static std::string uom_to_string(uint8_t uom); static std::string uom_to_string(uint8_t uom);
static std::string tag_to_string(uint8_t tag); static std::string tag_to_string(uint8_t tag);

View File

@@ -74,7 +74,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
Serial.print(custom_fullname.c_str()); Serial.print(custom_fullname.c_str());
Serial.print(COLOR_RESET); Serial.print(COLOR_RESET);
} else { } else {
Serial.print(Helpers::translated_word(fullname).c_str()); Serial.print(Helpers::translated_word(fullname));
} }
Serial.print(" (#options="); Serial.print(" (#options=");
Serial.print(options_size); Serial.print(options_size);
@@ -88,7 +88,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
Serial.print(i + 1); Serial.print(i + 1);
Serial.print(":"); Serial.print(":");
auto str = Helpers::translated_word(options[i]); auto str = Helpers::translated_word(options[i]);
Serial.print((str.c_str())); Serial.print(str);
i++; i++;
} }
} else if (options_single != nullptr) { } else if (options_single != nullptr) {

View File

@@ -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 fetch_device_values(device_id); // go and fetch its data
// Print to LOG showing we've added a new device // 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 // 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)) { 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)); FL_(entities_cmd));
// MQTT subscribe to the device e.g. "ems-esp/boiler/#" // 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; return true;
} }

View File

@@ -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(); uint8_t bool_format_ = dashboard ? EMSESP::system_.bool_dashboard() : EMSESP::system_.bool_format();
if (bool_format_ == BOOL_FORMAT_ONOFF_STR) { 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) { } 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)) { } else if ((bool_format_ == BOOL_FORMAT_10) || (bool_format_ == BOOL_FORMAT_10_STR)) {
strlcpy(result, value ? "1" : "0", 2); strlcpy(result, value ? "1" : "0", 2);
} else { } else {
@@ -593,12 +593,12 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
std::string bool_str = toLower(value); // convert to lower case 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; value_b = true;
return true; // is a bool 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; value_b = false;
return true; // is a bool 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); std::string str = toLower(value);
for (value_ui = 0; strs[value_ui]; value_ui++) { 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 std::string str2 = toLower((strs[value_ui][0])); // also check for default language
if ((str1 != "") if ((str1 != "")
&& ((str2 == "off" && str == "false") || (str2 == "on" && str == "true") || (str == str1) || (str == str2) && ((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; 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) { bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * const * strs) {
if ((value == nullptr) || (strlen(value) == 0)) { if ((value == nullptr) || (strlen(value) == 0)) {
return false; return false;
} }
std::string str = toLower(value); 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++) { for (value_ui = 0; strs[value_ui]; value_ui++) {
std::string enum_str = toLower((strs[value_ui])); std::string enum_str = toLower((strs[value_ui]));
if ((enum_str != "") if ((enum_str != "")
&& ((enum_str == "off" && (str == Helpers::translated_word(FL_(off)) || str == "false")) && ((enum_str == "off" && (str == s_off || str == "false")) || (enum_str == "on" && (str == s_on || str == "true")) || (str == enum_str)
|| (enum_str == "on" && (str == Helpers::translated_word(FL_(on)) || str == "true")) || (str == enum_str)
|| (value[0] == ('0' + value_ui) && value[1] == '\0'))) { || (value[0] == ('0' + value_ui) && value[1] == '\0'))) {
return true; return true;
} }
@@ -702,31 +708,13 @@ uint8_t Helpers::count_items(const char * const ** list) {
return list_size; 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 // 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 language_index = EMSESP::system_.language_index();
uint8_t index = 0; uint8_t index = 0;
// check for empty
if (!strings) { 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 // see how many translations we have for this entity. if there is no translation for this, revert to EN

View File

@@ -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 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_word(const char * const * strings);
static const char * translated_fullname(const char * const * strings);
#ifdef EMSESP_STANDALONE #ifdef EMSESP_STANDALONE
static char * ultostr(char * ptr, uint32_t value, const uint8_t base); static char * ultostr(char * ptr, uint32_t value, const uint8_t base);

View File

@@ -901,13 +901,14 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
// always create the ids // always create the ids
JsonArray ids = dev_json.createNestedArray("ids"); JsonArray ids = dev_json.createNestedArray("ids");
char ha_device[40]; char ha_device[40];
std::string device_type_name = EMSdevice::device_type_2_device_name(dv.device_type); 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.c_str()); snprintf(ha_device, sizeof(ha_device), "ems-esp-%s", device_type_name);
ids.add(ha_device); ids.add(ha_device);
if (create_device_config) { if (create_device_config) {
device_type_name[0] = toupper(device_type_name[0]); // capitalize auto cap_name = strdup(device_type_name);
dev_json["name"] = "EMS-ESP " + 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["mf"] = brand;
dev_json["mdl"] = model; dev_json["mdl"] = model;
dev_json["via_device"] = "ems-esp"; dev_json["via_device"] = "ems-esp";
@@ -972,8 +973,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice
} }
// create the device name // create the device name
char device_name[50]; auto device_name = EMSdevice::device_type_2_device_name(device_type);
strlcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str(), sizeof(device_name));
// create entity by add the hc/wwc tag if present, separating with a . // create entity by add the hc/wwc tag if present, separating with a .
char new_entity[50]; 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); 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 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))) { 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 { } else {
return EMSdevice::device_type_2_device_name(device_type) + "_data"; return topic + "_data";
} }
} }

View File

@@ -246,6 +246,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
shell.invoke_command("show mqtt"); 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") { if (command == "render") {
shell.printfln("Testing render..."); shell.printfln("Testing render...");