1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

add parse_bool_param_, add missing macros

This commit is contained in:
J. Nick Koston
2026-01-09 14:19:12 -10:00
parent e3a7587917
commit 6131e18388
2 changed files with 111 additions and 82 deletions

View File

@@ -841,10 +841,10 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc
}
auto call = is_on ? obj->turn_on() : obj->turn_off();
parse_int_param_(request, "speed_level", call, &decltype(call)::set_speed);
parse_int_param_(request, ESPHOME_F("speed_level"), call, &decltype(call)::set_speed);
if (request->hasParam("oscillation")) {
auto speed = request->getParam("oscillation")->value();
if (request->hasParam(ESPHOME_F("oscillation"))) {
auto speed = request->getParam(ESPHOME_F("oscillation"))->value();
auto val = parse_on_off(speed.c_str());
switch (val) {
case PARSE_ON:
@@ -924,20 +924,20 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
if (is_on) {
// Parse color parameters
parse_light_param_(request, "brightness", call, &decltype(call)::set_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);
parse_light_param_(request, "white_value", call, &decltype(call)::set_white, 255.0f);
parse_light_param_(request, "color_temp", call, &decltype(call)::set_color_temperature);
parse_light_param_(request, ESPHOME_F("brightness"), call, &decltype(call)::set_brightness, 255.0f);
parse_light_param_(request, ESPHOME_F("r"), call, &decltype(call)::set_red, 255.0f);
parse_light_param_(request, ESPHOME_F("g"), call, &decltype(call)::set_green, 255.0f);
parse_light_param_(request, ESPHOME_F("b"), call, &decltype(call)::set_blue, 255.0f);
parse_light_param_(request, ESPHOME_F("white_value"), call, &decltype(call)::set_white, 255.0f);
parse_light_param_(request, ESPHOME_F("color_temp"), call, &decltype(call)::set_color_temperature);
// Parse timing parameters
parse_light_param_uint_(request, "flash", call, &decltype(call)::set_flash_length, 1000);
parse_light_param_uint_(request, ESPHOME_F("flash"), call, &decltype(call)::set_flash_length, 1000);
}
parse_light_param_uint_(request, "transition", call, &decltype(call)::set_transition_length, 1000);
parse_light_param_uint_(request, ESPHOME_F("transition"), call, &decltype(call)::set_transition_length, 1000);
if (is_on) {
parse_string_param_(request, "effect", call, &decltype(call)::set_effect);
parse_string_param_(request, ESPHOME_F("effect"), call, &decltype(call)::set_effect);
}
this->defer([call]() mutable { call.perform(); });
@@ -1020,14 +1020,14 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
}
auto traits = obj->get_traits();
if ((request->hasParam("position") && !traits.get_supports_position()) ||
(request->hasParam("tilt") && !traits.get_supports_tilt())) {
if ((request->hasParam(ESPHOME_F("position")) && !traits.get_supports_position()) ||
(request->hasParam(ESPHOME_F("tilt")) && !traits.get_supports_tilt())) {
request->send(409);
return;
}
parse_float_param_(request, "position", call, &decltype(call)::set_position);
parse_float_param_(request, "tilt", call, &decltype(call)::set_tilt);
parse_float_param_(request, ESPHOME_F("position"), call, &decltype(call)::set_position);
parse_float_param_(request, ESPHOME_F("tilt"), call, &decltype(call)::set_tilt);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1086,7 +1086,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
}
auto call = obj->make_call();
parse_float_param_(request, "value", call, &decltype(call)::set_value);
parse_float_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_value);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1154,12 +1154,12 @@ void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMat
auto call = obj->make_call();
if (!request->hasParam("value")) {
if (!request->hasParam(ESPHOME_F("value"))) {
request->send(409);
return;
}
parse_string_param_(request, "value", call, &decltype(call)::set_date);
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_date);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1218,12 +1218,12 @@ void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMat
auto call = obj->make_call();
if (!request->hasParam("value")) {
if (!request->hasParam(ESPHOME_F("value"))) {
request->send(409);
return;
}
parse_string_param_(request, "value", call, &decltype(call)::set_time);
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_time);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1281,12 +1281,12 @@ void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const Ur
auto call = obj->make_call();
if (!request->hasParam("value")) {
if (!request->hasParam(ESPHOME_F("value"))) {
request->send(409);
return;
}
parse_string_param_(request, "value", call, &decltype(call)::set_datetime);
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_datetime);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1346,7 +1346,7 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat
}
auto call = obj->make_call();
parse_string_param_(request, "value", call, &decltype(call)::set_value);
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_value);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1404,7 +1404,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
}
auto call = obj->make_call();
parse_string_param_(request, "option", call, &decltype(call)::set_option);
parse_string_param_(request, ESPHOME_F("option"), call, &decltype(call)::set_option);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1464,14 +1464,15 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
auto call = obj->make_call();
// Parse string mode parameters
parse_string_param_(request, "mode", call, &decltype(call)::set_mode);
parse_string_param_(request, "fan_mode", call, &decltype(call)::set_fan_mode);
parse_string_param_(request, "swing_mode", call, &decltype(call)::set_swing_mode);
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 temperature parameters
parse_float_param_(request, "target_temperature_high", call, &decltype(call)::set_target_temperature_high);
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);
parse_float_param_(request, ESPHOME_F("target_temperature_high"), call,
&decltype(call)::set_target_temperature_high);
parse_float_param_(request, ESPHOME_F("target_temperature_low"), call, &decltype(call)::set_target_temperature_low);
parse_float_param_(request, ESPHOME_F("target_temperature"), call, &decltype(call)::set_target_temperature);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1710,12 +1711,12 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa
}
auto traits = obj->get_traits();
if (request->hasParam("position") && !traits.get_supports_position()) {
if (request->hasParam(ESPHOME_F("position")) && !traits.get_supports_position()) {
request->send(409);
return;
}
parse_float_param_(request, "position", call, &decltype(call)::set_position);
parse_float_param_(request, ESPHOME_F("position"), call, &decltype(call)::set_position);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1768,7 +1769,7 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
}
auto call = obj->make_call();
parse_string_param_(request, "code", call, &decltype(call)::set_code);
parse_string_param_(request, ESPHOME_F("code"), call, &decltype(call)::set_code);
// Lookup table for alarm control panel methods
static const struct {
@@ -1851,13 +1852,24 @@ void WebServer::handle_water_heater_request(AsyncWebServerRequest *request, cons
request->send(404);
return;
}
water_heater::WaterHeaterCall call = obj->make_call();
this->parse_float_param_(request, "target_temperature", call,
&water_heater::WaterHeaterCall::set_target_temperature);
if (request->hasParam("mode")) {
const char *mode = request->getParam("mode")->value().c_str();
call.set_mode(mode);
}
auto call = obj->make_call();
// Parse mode parameter
parse_string_param_(request, ESPHOME_F("mode"), call, &water_heater::WaterHeaterCall::set_mode);
// Parse temperature parameters
parse_float_param_(request, ESPHOME_F("target_temperature"), call,
&water_heater::WaterHeaterCall::set_target_temperature);
parse_float_param_(request, ESPHOME_F("target_temperature_low"), call,
&water_heater::WaterHeaterCall::set_target_temperature_low);
parse_float_param_(request, ESPHOME_F("target_temperature_high"), call,
&water_heater::WaterHeaterCall::set_target_temperature_high);
// Parse away mode parameter
parse_bool_param_(request, ESPHOME_F("away"), call, &water_heater::WaterHeaterCall::set_away);
// Parse on/off parameter
parse_bool_param_(request, ESPHOME_F("is_on"), call, &water_heater::WaterHeaterCall::set_on);
this->defer([call]() mutable { call.perform(); });
request->send(200);
@@ -1875,53 +1887,53 @@ std::string WebServer::water_heater_all_json_generator(WebServer *web_server, vo
std::string WebServer::water_heater_json_(water_heater::WaterHeater *obj, JsonDetail start_config) {
json::JsonBuilder builder;
JsonObject root = builder.root();
char buf[PSTR_LOCAL_SIZE];
const auto mode = obj->get_mode();
const char *mode_s;
switch (mode) {
case water_heater::WATER_HEATER_MODE_OFF:
mode_s = "OFF";
break;
case water_heater::WATER_HEATER_MODE_ECO:
mode_s = "ECO";
break;
case water_heater::WATER_HEATER_MODE_ELECTRIC:
mode_s = "ELECTRIC";
break;
case water_heater::WATER_HEATER_MODE_PERFORMANCE:
mode_s = "PERFORMANCE";
break;
case water_heater::WATER_HEATER_MODE_HIGH_DEMAND:
mode_s = "HIGH_DEMAND";
break;
case water_heater::WATER_HEATER_MODE_HEAT_PUMP:
mode_s = "HEAT_PUMP";
break;
case water_heater::WATER_HEATER_MODE_GAS:
mode_s = "GAS";
break;
default:
mode_s = "UNKNOWN";
break;
}
const char *mode_s = PSTR_LOCAL(water_heater::water_heater_mode_to_string(mode));
set_json_icon_state_value(root, obj, "water-heater", mode_s, mode, start_config);
float current = obj->get_current_temperature();
if (!std::isnan(current))
root["current_temperature"] = current;
root["target_temperature"] = obj->get_target_temperature();
auto traits = obj->get_traits();
root["min_temperature"] = traits.get_min_temperature();
root["max_temperature"] = traits.get_max_temperature();
if (start_config == DETAIL_ALL) {
JsonArray modes = root[ESPHOME_F("modes")].to<JsonArray>();
for (auto m : traits.get_supported_modes())
modes.add(PSTR_LOCAL(water_heater::water_heater_mode_to_string(m)));
this->add_sorting_info_(root, obj);
}
if (traits.get_supports_current_temperature()) {
float current = obj->get_current_temperature();
if (!std::isnan(current))
root[ESPHOME_F("current_temperature")] = current;
}
if (traits.get_supports_two_point_target_temperature()) {
float low = obj->get_target_temperature_low();
float high = obj->get_target_temperature_high();
if (!std::isnan(low))
root[ESPHOME_F("target_temperature_low")] = low;
if (!std::isnan(high))
root[ESPHOME_F("target_temperature_high")] = high;
} else {
float target = obj->get_target_temperature();
if (!std::isnan(target))
root[ESPHOME_F("target_temperature")] = target;
}
root[ESPHOME_F("min_temperature")] = traits.get_min_temperature();
root[ESPHOME_F("max_temperature")] = traits.get_max_temperature();
root[ESPHOME_F("step")] = traits.get_target_temperature_step();
if (traits.get_supports_away_mode()) {
root[ESPHOME_F("away")] = obj->is_away();
}
if (traits.has_feature_flags(water_heater::WATER_HEATER_SUPPORTS_ON_OFF)) {
root[ESPHOME_F("is_on")] = obj->is_on();
}
return builder.serialize();
}
#endif

View File

@@ -35,6 +35,13 @@ extern const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE;
namespace esphome::web_server {
// Type for parameter names that can be stored in flash on ESP8266
#ifdef USE_ESP8266
using ParamNameType = const __FlashStringHelper *;
#else
using ParamNameType = const char *;
#endif
/// Result of matching a URL against an entity
struct EntityMatchResult {
bool matched; ///< True if entity matched the URL
@@ -482,7 +489,7 @@ class WebServer : public Controller,
#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),
void parse_light_param_(AsyncWebServerRequest *request, ParamNameType 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());
@@ -494,7 +501,7 @@ class WebServer : public Controller,
// 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,
void parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType 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());
@@ -507,7 +514,7 @@ class WebServer : public Controller,
// 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)) {
void parse_float_param_(AsyncWebServerRequest *request, ParamNameType 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()) {
@@ -518,7 +525,7 @@ class WebServer : public Controller,
// 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)) {
void parse_int_param_(AsyncWebServerRequest *request, ParamNameType 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()) {
@@ -529,7 +536,7 @@ class WebServer : public Controller,
// 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,
void parse_string_param_(AsyncWebServerRequest *request, ParamNameType 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
@@ -538,6 +545,16 @@ class WebServer : public Controller,
}
}
// Generic helper to parse and apply a bool parameter
template<typename T, typename Ret>
void parse_bool_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret (T::*setter)(bool)) {
if (request->hasParam(param_name)) {
auto param_value = request->getParam(param_name)->value();
bool value = param_value == "true" || param_value == "1";
(call.*setter)(value);
}
}
web_server_base::WebServerBase *base_;
#ifdef USE_ESP32
AsyncEventSource events_{"/events", this};