mirror of
https://github.com/esphome/esphome.git
synced 2026-03-01 02:14:19 -07:00
Merge remote-tracking branch 'origin/web_server' into integration
This commit is contained in:
@@ -12,7 +12,14 @@ AlarmControlPanelCall::AlarmControlPanelCall(AlarmControlPanel *parent) : parent
|
||||
|
||||
AlarmControlPanelCall &AlarmControlPanelCall::set_code(const char *code) {
|
||||
if (code != nullptr) {
|
||||
this->code_ = std::string(code);
|
||||
return this->set_code(code, strlen(code));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AlarmControlPanelCall &AlarmControlPanelCall::set_code(const char *code, size_t len) {
|
||||
if (code != nullptr) {
|
||||
this->code_ = std::string(code, len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ class AlarmControlPanelCall {
|
||||
AlarmControlPanelCall(AlarmControlPanel *parent);
|
||||
|
||||
AlarmControlPanelCall &set_code(const char *code);
|
||||
AlarmControlPanelCall &set_code(const std::string &code) { return this->set_code(code.c_str()); }
|
||||
AlarmControlPanelCall &set_code(const char *code, size_t len);
|
||||
AlarmControlPanelCall &set_code(const std::string &code) { return this->set_code(code.c_str(), code.size()); }
|
||||
AlarmControlPanelCall &arm_away();
|
||||
AlarmControlPanelCall &arm_home();
|
||||
AlarmControlPanelCall &arm_night();
|
||||
|
||||
@@ -879,7 +879,7 @@ uint16_t APIConnection::try_send_text_info(EntityBase *entity, APIConnection *co
|
||||
}
|
||||
void APIConnection::on_text_command_request(const TextCommandRequest &msg) {
|
||||
ENTITY_COMMAND_MAKE_CALL(text::Text, text, text)
|
||||
call.set_value(msg.state);
|
||||
call.set_value(msg.state.c_str(), msg.state.size());
|
||||
call.perform();
|
||||
}
|
||||
#endif
|
||||
@@ -1350,7 +1350,7 @@ void APIConnection::on_alarm_control_panel_command_request(const AlarmControlPan
|
||||
call.pending();
|
||||
break;
|
||||
}
|
||||
call.set_code(msg.code);
|
||||
call.set_code(msg.code.c_str(), msg.code.size());
|
||||
call.perform();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -173,14 +173,17 @@ ClimateCall &ClimateCall::set_mode(ClimateMode mode) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClimateCall &ClimateCall::set_mode(const std::string &mode) {
|
||||
ClimateCall &ClimateCall::set_mode(const std::string &mode) { return this->set_mode(mode.c_str(), mode.size()); }
|
||||
|
||||
ClimateCall &ClimateCall::set_mode(const char *mode, size_t len) {
|
||||
StringRef mode_ref(mode, len);
|
||||
for (const auto &mode_entry : CLIMATE_MODES_BY_STR) {
|
||||
if (str_equals_case_insensitive(mode, mode_entry.str)) {
|
||||
if (str_equals_case_insensitive(mode_ref, mode_entry.str)) {
|
||||
this->set_mode(static_cast<ClimateMode>(mode_entry.value));
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized mode %s", this->parent_->get_name().c_str(), mode.c_str());
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized mode %.*s", this->parent_->get_name().c_str(), (int) len, mode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -266,13 +269,18 @@ ClimateCall &ClimateCall::set_swing_mode(ClimateSwingMode swing_mode) {
|
||||
}
|
||||
|
||||
ClimateCall &ClimateCall::set_swing_mode(const std::string &swing_mode) {
|
||||
return this->set_swing_mode(swing_mode.c_str(), swing_mode.size());
|
||||
}
|
||||
|
||||
ClimateCall &ClimateCall::set_swing_mode(const char *swing_mode, size_t len) {
|
||||
StringRef mode_ref(swing_mode, len);
|
||||
for (const auto &mode_entry : CLIMATE_SWING_MODES_BY_STR) {
|
||||
if (str_equals_case_insensitive(swing_mode, mode_entry.str)) {
|
||||
if (str_equals_case_insensitive(mode_ref, mode_entry.str)) {
|
||||
this->set_swing_mode(static_cast<ClimateSwingMode>(mode_entry.value));
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %s", this->parent_->get_name().c_str(), swing_mode.c_str());
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %.*s", this->parent_->get_name().c_str(), (int) len, swing_mode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ class ClimateCall {
|
||||
ClimateCall &set_mode(optional<ClimateMode> mode);
|
||||
/// Set the mode of the climate device based on a string.
|
||||
ClimateCall &set_mode(const std::string &mode);
|
||||
/// Set the mode of the climate device based on a C string.
|
||||
ClimateCall &set_mode(const char *mode, size_t len);
|
||||
/// Set the target temperature of the climate device.
|
||||
ClimateCall &set_target_temperature(float target_temperature);
|
||||
/// Set the target temperature of the climate device.
|
||||
@@ -87,6 +89,8 @@ class ClimateCall {
|
||||
ClimateCall &set_swing_mode(optional<ClimateSwingMode> swing_mode);
|
||||
/// Set the swing mode of the climate device based on a string.
|
||||
ClimateCall &set_swing_mode(const std::string &swing_mode);
|
||||
/// Set the swing mode of the climate device based on a C string.
|
||||
ClimateCall &set_swing_mode(const char *swing_mode, size_t len);
|
||||
/// Set the preset of the climate device.
|
||||
ClimateCall &set_preset(ClimatePreset preset);
|
||||
/// Set the preset of the climate device.
|
||||
|
||||
@@ -11,6 +11,11 @@ TextCall &TextCall::set_value(const std::string &value) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
TextCall &TextCall::set_value(const char *value, size_t len) {
|
||||
this->value_ = std::string(value, len);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TextCall::validate_() {
|
||||
const auto *name = this->parent_->get_name().c_str();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ class TextCall {
|
||||
void perform();
|
||||
|
||||
TextCall &set_value(const std::string &value);
|
||||
TextCall &set_value(const char *value, size_t len);
|
||||
|
||||
protected:
|
||||
Text *const parent_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
namespace esphome::water_heater {
|
||||
|
||||
@@ -23,23 +24,25 @@ WaterHeaterCall &WaterHeaterCall::set_mode(WaterHeaterMode mode) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
WaterHeaterCall &WaterHeaterCall::set_mode(const char *mode) {
|
||||
if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("OFF")) == 0) {
|
||||
WaterHeaterCall &WaterHeaterCall::set_mode(const char *mode) { return this->set_mode(mode, strlen(mode)); }
|
||||
|
||||
WaterHeaterCall &WaterHeaterCall::set_mode(const char *mode, size_t len) {
|
||||
if (len == 3 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("OFF"), 3) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_OFF);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("ECO")) == 0) {
|
||||
} else if (len == 3 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("ECO"), 3) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_ECO);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("ELECTRIC")) == 0) {
|
||||
} else if (len == 8 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("ELECTRIC"), 8) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_ELECTRIC);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("PERFORMANCE")) == 0) {
|
||||
} else if (len == 11 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("PERFORMANCE"), 11) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_PERFORMANCE);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("HIGH_DEMAND")) == 0) {
|
||||
} else if (len == 11 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("HIGH_DEMAND"), 11) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_HIGH_DEMAND);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("HEAT_PUMP")) == 0) {
|
||||
} else if (len == 9 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("HEAT_PUMP"), 9) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_HEAT_PUMP);
|
||||
} else if (ESPHOME_strcasecmp_P(mode, ESPHOME_PSTR("GAS")) == 0) {
|
||||
} else if (len == 3 && ESPHOME_strncasecmp_P(mode, ESPHOME_PSTR("GAS"), 3) == 0) {
|
||||
this->set_mode(WATER_HEATER_MODE_GAS);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized mode %s", this->parent_->get_name().c_str(), mode);
|
||||
ESP_LOGW(TAG, "'%s' - Unrecognized mode %.*s", this->parent_->get_name().c_str(), (int) len, mode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ class WaterHeaterCall {
|
||||
|
||||
WaterHeaterCall &set_mode(WaterHeaterMode mode);
|
||||
WaterHeaterCall &set_mode(const char *mode);
|
||||
WaterHeaterCall &set_mode(const std::string &mode) { return this->set_mode(mode.c_str()); }
|
||||
WaterHeaterCall &set_mode(const char *mode, size_t len);
|
||||
WaterHeaterCall &set_mode(const std::string &mode) { return this->set_mode(mode.c_str(), mode.size()); }
|
||||
WaterHeaterCall &set_target_temperature(float temperature);
|
||||
WaterHeaterCall &set_target_temperature_low(float temperature);
|
||||
WaterHeaterCall &set_target_temperature_high(float temperature);
|
||||
|
||||
@@ -970,7 +970,9 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
|
||||
parse_light_param_uint_(request, ESPHOME_F("transition"), call, &decltype(call)::set_transition_length, 1000);
|
||||
|
||||
if (is_on) {
|
||||
parse_string_param_(request, ESPHOME_F("effect"), call, &decltype(call)::set_effect);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("effect"), call,
|
||||
static_cast<light::LightCall &(light::LightCall::*) (const char *, size_t)>(&decltype(call)::set_effect));
|
||||
}
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
@@ -1369,7 +1371,9 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_value);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("value"), call,
|
||||
static_cast<text::TextCall &(text::TextCall::*) (const char *, size_t)>(&decltype(call)::set_value));
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
request->send(200);
|
||||
@@ -1427,7 +1431,9 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("option"), call, &decltype(call)::set_option);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("option"), call,
|
||||
static_cast<select::SelectCall &(select::SelectCall::*) (const char *, size_t)>(&decltype(call)::set_option));
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
request->send(200);
|
||||
@@ -1488,10 +1494,18 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
|
||||
auto call = obj->make_call();
|
||||
|
||||
// Parse string mode parameters
|
||||
parse_string_param_(request, ESPHOME_F("mode"), call, &decltype(call)::set_mode);
|
||||
parse_string_param_(request, ESPHOME_F("fan_mode"), call, &decltype(call)::set_fan_mode);
|
||||
parse_string_param_(request, ESPHOME_F("swing_mode"), call, &decltype(call)::set_swing_mode);
|
||||
parse_string_param_(request, ESPHOME_F("preset"), call, &decltype(call)::set_preset);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(&decltype(call)::set_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("fan_mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_fan_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("swing_mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_swing_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("preset"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_preset));
|
||||
|
||||
// Parse temperature parameters
|
||||
// static_cast needed to disambiguate overloaded setters (float vs optional<float>)
|
||||
@@ -1820,7 +1834,10 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("code"), call, &decltype(call)::set_code);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("code"), call,
|
||||
static_cast<alarm_control_panel::AlarmControlPanelCall &(
|
||||
alarm_control_panel::AlarmControlPanelCall::*) (const char *, size_t)>(&decltype(call)::set_code));
|
||||
|
||||
// Lookup table for alarm control panel methods
|
||||
static const struct {
|
||||
@@ -1908,7 +1925,10 @@ void WebServer::handle_water_heater_request(AsyncWebServerRequest *request, cons
|
||||
water_heater::WaterHeaterCall &base_call = call;
|
||||
|
||||
// Parse mode parameter
|
||||
parse_string_param_(request, ESPHOME_F("mode"), base_call, &water_heater::WaterHeaterCall::set_mode);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("mode"), base_call,
|
||||
static_cast<water_heater::WaterHeaterCall &(water_heater::WaterHeaterCall::*) (const char *, size_t)>(
|
||||
&water_heater::WaterHeaterCall::set_mode));
|
||||
|
||||
// Parse temperature parameters
|
||||
parse_num_param_(request, ESPHOME_F("target_temperature"), base_call,
|
||||
|
||||
@@ -533,13 +533,13 @@ class WebServer final : public Controller, public Component, public AsyncWebHand
|
||||
}
|
||||
}
|
||||
|
||||
// Generic helper to parse and apply a string parameter
|
||||
// Generic helper to parse and apply a string parameter using const char* setter (avoids std::string allocation)
|
||||
template<typename T, typename Ret>
|
||||
void parse_string_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call,
|
||||
Ret (T::*setter)(const std::string &)) {
|
||||
void parse_cstr_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call,
|
||||
Ret (T::*setter)(const char *, size_t)) {
|
||||
if (request->hasArg(param_name)) {
|
||||
const auto &value = request->arg(param_name);
|
||||
(call.*setter)(std::string(value.c_str(), value.length()));
|
||||
(call.*setter)(value.c_str(), value.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user