mirror of
https://github.com/esphome/esphome.git
synced 2025-09-02 11:22:24 +01:00
[web_server] Reduce flash usage by consolidating parameter parsing (#10154)
This commit is contained in:
@@ -635,15 +635,8 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc
|
|||||||
} else if (match.method_equals("turn_on") || match.method_equals("turn_off")) {
|
} else if (match.method_equals("turn_on") || match.method_equals("turn_off")) {
|
||||||
auto call = match.method_equals("turn_on") ? obj->turn_on() : obj->turn_off();
|
auto call = match.method_equals("turn_on") ? obj->turn_on() : obj->turn_off();
|
||||||
|
|
||||||
if (request->hasParam("speed_level")) {
|
parse_int_param_(request, "speed_level", call, &decltype(call)::set_speed);
|
||||||
auto speed_level = request->getParam("speed_level")->value();
|
|
||||||
auto val = parse_number<int>(speed_level.c_str());
|
|
||||||
if (!val.has_value()) {
|
|
||||||
ESP_LOGW(TAG, "Can't convert '%s' to number!", speed_level.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
call.set_speed(*val);
|
|
||||||
}
|
|
||||||
if (request->hasParam("oscillation")) {
|
if (request->hasParam("oscillation")) {
|
||||||
auto speed = request->getParam("oscillation")->value();
|
auto speed = request->getParam("oscillation")->value();
|
||||||
auto val = parse_on_off(speed.c_str());
|
auto val = parse_on_off(speed.c_str());
|
||||||
@@ -715,69 +708,26 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method_equals("turn_on")) {
|
} else if (match.method_equals("turn_on")) {
|
||||||
auto call = obj->turn_on();
|
auto call = obj->turn_on();
|
||||||
if (request->hasParam("brightness")) {
|
|
||||||
auto brightness = parse_number<float>(request->getParam("brightness")->value().c_str());
|
// Parse color parameters
|
||||||
if (brightness.has_value()) {
|
parse_light_param_(request, "brightness", call, &decltype(call)::set_brightness, 255.0f);
|
||||||
call.set_brightness(*brightness / 255.0f);
|
parse_light_param_(request, "r", call, &decltype(call)::set_red, 255.0f);
|
||||||
}
|
parse_light_param_(request, "g", call, &decltype(call)::set_green, 255.0f);
|
||||||
}
|
parse_light_param_(request, "b", call, &decltype(call)::set_blue, 255.0f);
|
||||||
if (request->hasParam("r")) {
|
parse_light_param_(request, "white_value", call, &decltype(call)::set_white, 255.0f);
|
||||||
auto r = parse_number<float>(request->getParam("r")->value().c_str());
|
parse_light_param_(request, "color_temp", call, &decltype(call)::set_color_temperature);
|
||||||
if (r.has_value()) {
|
|
||||||
call.set_red(*r / 255.0f);
|
// Parse timing parameters
|
||||||
}
|
parse_light_param_uint_(request, "flash", call, &decltype(call)::set_flash_length, 1000);
|
||||||
}
|
parse_light_param_uint_(request, "transition", call, &decltype(call)::set_transition_length, 1000);
|
||||||
if (request->hasParam("g")) {
|
|
||||||
auto g = parse_number<float>(request->getParam("g")->value().c_str());
|
parse_string_param_(request, "effect", call, &decltype(call)::set_effect);
|
||||||
if (g.has_value()) {
|
|
||||||
call.set_green(*g / 255.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("b")) {
|
|
||||||
auto b = parse_number<float>(request->getParam("b")->value().c_str());
|
|
||||||
if (b.has_value()) {
|
|
||||||
call.set_blue(*b / 255.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("white_value")) {
|
|
||||||
auto white_value = parse_number<float>(request->getParam("white_value")->value().c_str());
|
|
||||||
if (white_value.has_value()) {
|
|
||||||
call.set_white(*white_value / 255.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("color_temp")) {
|
|
||||||
auto color_temp = parse_number<float>(request->getParam("color_temp")->value().c_str());
|
|
||||||
if (color_temp.has_value()) {
|
|
||||||
call.set_color_temperature(*color_temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("flash")) {
|
|
||||||
auto flash = parse_number<uint32_t>(request->getParam("flash")->value().c_str());
|
|
||||||
if (flash.has_value()) {
|
|
||||||
call.set_flash_length(*flash * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("transition")) {
|
|
||||||
auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
|
|
||||||
if (transition.has_value()) {
|
|
||||||
call.set_transition_length(*transition * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("effect")) {
|
|
||||||
const char *effect = request->getParam("effect")->value().c_str();
|
|
||||||
call.set_effect(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method_equals("turn_off")) {
|
} else if (match.method_equals("turn_off")) {
|
||||||
auto call = obj->turn_off();
|
auto call = obj->turn_off();
|
||||||
if (request->hasParam("transition")) {
|
parse_light_param_uint_(request, "transition", call, &decltype(call)::set_transition_length, 1000);
|
||||||
auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
|
|
||||||
if (transition.has_value()) {
|
|
||||||
call.set_transition_length(*transition * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
} else {
|
||||||
@@ -850,18 +800,8 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->hasParam("position")) {
|
parse_float_param_(request, "position", call, &decltype(call)::set_position);
|
||||||
auto position = parse_number<float>(request->getParam("position")->value().c_str());
|
parse_float_param_(request, "tilt", call, &decltype(call)::set_tilt);
|
||||||
if (position.has_value()) {
|
|
||||||
call.set_position(*position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request->hasParam("tilt")) {
|
|
||||||
auto tilt = parse_number<float>(request->getParam("tilt")->value().c_str());
|
|
||||||
if (tilt.has_value()) {
|
|
||||||
call.set_tilt(*tilt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -915,11 +855,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
if (request->hasParam("value")) {
|
parse_float_param_(request, "value", call, &decltype(call)::set_value);
|
||||||
auto value = parse_number<float>(request->getParam("value")->value().c_str());
|
|
||||||
if (value.has_value())
|
|
||||||
call.set_value(*value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -991,10 +927,7 @@ void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMat
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->hasParam("value")) {
|
parse_string_param_(request, "value", call, &decltype(call)::set_date);
|
||||||
std::string value = request->getParam("value")->value().c_str(); // NOLINT
|
|
||||||
call.set_date(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1050,10 +983,7 @@ void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMat
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->hasParam("value")) {
|
parse_string_param_(request, "value", call, &decltype(call)::set_time);
|
||||||
std::string value = request->getParam("value")->value().c_str(); // NOLINT
|
|
||||||
call.set_time(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1108,10 +1038,7 @@ void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const Ur
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->hasParam("value")) {
|
parse_string_param_(request, "value", call, &decltype(call)::set_datetime);
|
||||||
std::string value = request->getParam("value")->value().c_str(); // NOLINT
|
|
||||||
call.set_datetime(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1162,10 +1089,7 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
if (request->hasParam("value")) {
|
parse_string_param_(request, "value", call, &decltype(call)::set_value);
|
||||||
String value = request->getParam("value")->value();
|
|
||||||
call.set_value(value.c_str()); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1224,11 +1148,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
|
parse_string_param_(request, "option", call, &decltype(call)::set_option);
|
||||||
if (request->hasParam("option")) {
|
|
||||||
auto option = request->getParam("option")->value();
|
|
||||||
call.set_option(option.c_str()); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1284,38 +1204,15 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
|
|||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
|
|
||||||
if (request->hasParam("mode")) {
|
// Parse string mode parameters
|
||||||
auto mode = request->getParam("mode")->value();
|
parse_string_param_(request, "mode", call, &decltype(call)::set_mode);
|
||||||
call.set_mode(mode.c_str()); // NOLINT
|
parse_string_param_(request, "fan_mode", call, &decltype(call)::set_fan_mode);
|
||||||
}
|
parse_string_param_(request, "swing_mode", call, &decltype(call)::set_swing_mode);
|
||||||
|
|
||||||
if (request->hasParam("fan_mode")) {
|
// Parse temperature parameters
|
||||||
auto mode = request->getParam("fan_mode")->value();
|
parse_float_param_(request, "target_temperature_high", call, &decltype(call)::set_target_temperature_high);
|
||||||
call.set_fan_mode(mode.c_str()); // NOLINT
|
parse_float_param_(request, "target_temperature_low", call, &decltype(call)::set_target_temperature_low);
|
||||||
}
|
parse_float_param_(request, "target_temperature", call, &decltype(call)::set_target_temperature);
|
||||||
|
|
||||||
if (request->hasParam("swing_mode")) {
|
|
||||||
auto mode = request->getParam("swing_mode")->value();
|
|
||||||
call.set_swing_mode(mode.c_str()); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->hasParam("target_temperature_high")) {
|
|
||||||
auto target_temperature_high = parse_number<float>(request->getParam("target_temperature_high")->value().c_str());
|
|
||||||
if (target_temperature_high.has_value())
|
|
||||||
call.set_target_temperature_high(*target_temperature_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->hasParam("target_temperature_low")) {
|
|
||||||
auto target_temperature_low = parse_number<float>(request->getParam("target_temperature_low")->value().c_str());
|
|
||||||
if (target_temperature_low.has_value())
|
|
||||||
call.set_target_temperature_low(*target_temperature_low);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->hasParam("target_temperature")) {
|
|
||||||
auto target_temperature = parse_number<float>(request->getParam("target_temperature")->value().c_str());
|
|
||||||
if (target_temperature.has_value())
|
|
||||||
call.set_target_temperature(*target_temperature);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1506,12 +1403,7 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->hasParam("position")) {
|
parse_float_param_(request, "position", call, &decltype(call)::set_position);
|
||||||
auto position = parse_number<float>(request->getParam("position")->value().c_str());
|
|
||||||
if (position.has_value()) {
|
|
||||||
call.set_position(*position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->defer([call]() mutable { call.perform(); });
|
this->defer([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -1559,9 +1451,7 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
if (request->hasParam("code")) {
|
parse_string_param_(request, "code", call, &decltype(call)::set_code);
|
||||||
call.set_code(request->getParam("code")->value().c_str()); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match.method_equals("disarm")) {
|
if (match.method_equals("disarm")) {
|
||||||
call.disarm();
|
call.disarm();
|
||||||
@@ -1659,6 +1549,19 @@ std::string WebServer::event_json(event::Event *obj, const std::string &event_ty
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
|
static const char *update_state_to_string(update::UpdateState state) {
|
||||||
|
switch (state) {
|
||||||
|
case update::UPDATE_STATE_NO_UPDATE:
|
||||||
|
return "NO UPDATE";
|
||||||
|
case update::UPDATE_STATE_AVAILABLE:
|
||||||
|
return "UPDATE AVAILABLE";
|
||||||
|
case update::UPDATE_STATE_INSTALLING:
|
||||||
|
return "INSTALLING";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebServer::on_update(update::UpdateEntity *obj) {
|
void WebServer::on_update(update::UpdateEntity *obj) {
|
||||||
if (this->events_.empty())
|
if (this->events_.empty())
|
||||||
return;
|
return;
|
||||||
@@ -1698,20 +1601,7 @@ std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_c
|
|||||||
return json::build_json([this, obj, start_config](JsonObject root) {
|
return json::build_json([this, obj, start_config](JsonObject root) {
|
||||||
set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
|
set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
|
||||||
root["value"] = obj->update_info.latest_version;
|
root["value"] = obj->update_info.latest_version;
|
||||||
switch (obj->state) {
|
root["state"] = update_state_to_string(obj->state);
|
||||||
case update::UPDATE_STATE_NO_UPDATE:
|
|
||||||
root["state"] = "NO UPDATE";
|
|
||||||
break;
|
|
||||||
case update::UPDATE_STATE_AVAILABLE:
|
|
||||||
root["state"] = "UPDATE AVAILABLE";
|
|
||||||
break;
|
|
||||||
case update::UPDATE_STATE_INSTALLING:
|
|
||||||
root["state"] = "INSTALLING";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
root["state"] = "UNKNOWN";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (start_config == DETAIL_ALL) {
|
if (start_config == DETAIL_ALL) {
|
||||||
root["current_version"] = obj->update_info.current_version;
|
root["current_version"] = obj->update_info.current_version;
|
||||||
root["title"] = obj->update_info.title;
|
root["title"] = obj->update_info.title;
|
||||||
|
@@ -498,6 +498,66 @@ class WebServer : public Controller, public Component, public AsyncWebHandler {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void add_sorting_info_(JsonObject &root, EntityBase *entity);
|
void add_sorting_info_(JsonObject &root, EntityBase *entity);
|
||||||
|
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
// Helper to parse and apply a float parameter with optional scaling
|
||||||
|
template<typename T, typename Ret>
|
||||||
|
void parse_light_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(float),
|
||||||
|
float scale = 1.0f) {
|
||||||
|
if (request->hasParam(param_name)) {
|
||||||
|
auto value = parse_number<float>(request->getParam(param_name)->value().c_str());
|
||||||
|
if (value.has_value()) {
|
||||||
|
(call.*setter)(*value / scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to parse and apply a uint32_t parameter with optional scaling
|
||||||
|
template<typename T, typename Ret>
|
||||||
|
void parse_light_param_uint_(AsyncWebServerRequest *request, const char *param_name, T &call,
|
||||||
|
Ret (T::*setter)(uint32_t), uint32_t scale = 1) {
|
||||||
|
if (request->hasParam(param_name)) {
|
||||||
|
auto value = parse_number<uint32_t>(request->getParam(param_name)->value().c_str());
|
||||||
|
if (value.has_value()) {
|
||||||
|
(call.*setter)(*value * scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Generic helper to parse and apply a float parameter
|
||||||
|
template<typename T, typename Ret>
|
||||||
|
void parse_float_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(float)) {
|
||||||
|
if (request->hasParam(param_name)) {
|
||||||
|
auto value = parse_number<float>(request->getParam(param_name)->value().c_str());
|
||||||
|
if (value.has_value()) {
|
||||||
|
(call.*setter)(*value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic helper to parse and apply an int parameter
|
||||||
|
template<typename T, typename Ret>
|
||||||
|
void parse_int_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(int)) {
|
||||||
|
if (request->hasParam(param_name)) {
|
||||||
|
auto value = parse_number<int>(request->getParam(param_name)->value().c_str());
|
||||||
|
if (value.has_value()) {
|
||||||
|
(call.*setter)(*value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic helper to parse and apply a string parameter
|
||||||
|
template<typename T, typename Ret>
|
||||||
|
void parse_string_param_(AsyncWebServerRequest *request, const char *param_name, T &call,
|
||||||
|
Ret (T::*setter)(const std::string &)) {
|
||||||
|
if (request->hasParam(param_name)) {
|
||||||
|
// .c_str() is required for Arduino framework where value() returns Arduino String instead of std::string
|
||||||
|
std::string value = request->getParam(param_name)->value().c_str(); // NOLINT(readability-redundant-string-cstr)
|
||||||
|
(call.*setter)(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
web_server_base::WebServerBase *base_;
|
web_server_base::WebServerBase *base_;
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
DeferredUpdateEventSourceList events_;
|
DeferredUpdateEventSourceList events_;
|
||||||
|
Reference in New Issue
Block a user