14#if !defined(USE_ESP32) && defined(USE_ARDUINO)
15#include "StreamString.h"
32#ifdef USE_WATER_HEATER
36#ifdef USE_WEBSERVER_LOCAL
37#if USE_WEBSERVER_VERSION == 2
39#elif USE_WEBSERVER_VERSION == 3
46static const char *
const TAG =
"web_server";
49static constexpr size_t PSTR_LOCAL_SIZE = 18;
50#define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1)
58static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain,
bool is_post =
false) {
60 if (url_len < 2 || url_ptr[0] !=
'/')
63 const char *p = url_ptr + 1;
64 const char *
end = url_ptr + url_len;
67 auto next_segment = [&
end](
const char *start) ->
const char * {
68 const char *slash = (
const char *) memchr(start,
'/',
end - start);
69 return slash ? slash + 1 :
nullptr;
73 auto make_ref = [&
end](
const char *start,
const char *next_start) -> StringRef {
74 return StringRef(start, (next_start ? next_start - 1 :
end) - start);
79 const char *s2 = next_segment(s1);
86 match.domain = make_ref(s1, s2);
89 if (only_domain || s2 >=
end)
93 const char *s3 = next_segment(s2);
94 const char *s4 = s3 ? next_segment(s3) : nullptr;
96 StringRef seg2 = make_ref(s2, s3);
97 StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef();
98 StringRef seg4 = s4 ? make_ref(s4,
nullptr) : StringRef();
101 if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty()))
117 match.device_name = seg2;
128 match.device_name = seg2;
145 bool entity_has_device = (entity_device !=
nullptr);
148 if (url_has_device != entity_has_device) {
157 if (this->
id == entity->
get_name()) {
158 result.matched =
true;
163 char object_id_buf[OBJECT_ID_MAX_LEN];
165 if (this->
id == object_id) {
166 result.matched =
true;
170 if (device !=
nullptr) {
172 "Deprecated URL format: /%.*s/%.*s/%.*s - use entity name '/%.*s/%s/%s' instead. "
173 "Object ID URLs will be removed in 2026.7.0.",
174 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->device_name.size(),
175 this->device_name.c_str(), (
int) this->id.size(), this->id.c_str(), (
int) this->domain.size(),
181 "Deprecated URL format: /%.*s/%.*s - use entity name '/%.*s/%s' instead. "
182 "Object ID URLs will be removed in 2026.7.0.",
183 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->id.size(), this->id.c_str(),
184 (
int) this->domain.size(), this->domain.c_str(), entity->
get_name().
c_str());
191#if !defined(USE_ESP32) && defined(USE_ARDUINO)
194 DeferredEvent item(source, message_generator);
202 this->deferred_queue_.push_back(item);
209 if (this->send(
message.c_str(),
"state") != DISCARDED) {
221 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
240 if (this->count() == 0)
248 if (source ==
nullptr)
250 if (event_type ==
nullptr)
252 if (message_generator ==
nullptr)
255 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
256 ESP_LOGE(TAG,
"Can't defer non-state event");
266 if (this->send(
message.c_str(),
"state") == DISCARDED) {
276 uint32_t reconnect) {
277 this->send(
message, event,
id, reconnect);
297 uint32_t reconnect) {
307 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
311 es->handleRequest(request);
316 ws->
defer([ws, source]() {
322#ifdef USE_WEBSERVER_SORTING
325 JsonObject root = builder.
root();
326 root[ESPHOME_F(
"name")] = group.second.name;
327 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
349 this->remove(source);
357#ifdef USE_WEBSERVER_CSS_INCLUDE
360#ifdef USE_WEBSERVER_JS_INCLUDE
366 JsonObject root = builder.
root();
369 char comment_buffer[ESPHOME_COMMENT_SIZE];
371 root[ESPHOME_F(
"comment")] = comment_buffer;
372#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
373 root[ESPHOME_F(
"ota")] =
false;
375 root[ESPHOME_F(
"ota")] =
true;
378 root[ESPHOME_F(
"lang")] =
"en";
423#ifdef USE_WEBSERVER_LOCAL
426 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
428 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
430#ifdef USE_WEBSERVER_GZIP
431 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
433 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
435 request->send(response);
437#elif USE_WEBSERVER_VERSION >= 2
440 AsyncWebServerResponse *response =
443 AsyncWebServerResponse *response =
447 request->send(response);
451#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
453 AsyncWebServerResponse *response = request->beginResponse(200,
"");
454 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
455 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().c_str());
458 request->send(response);
462#ifdef USE_WEBSERVER_CSS_INCLUDE
465 AsyncWebServerResponse *response =
468 AsyncWebServerResponse *response =
471 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
472 request->send(response);
476#ifdef USE_WEBSERVER_JS_INCLUDE
479 AsyncWebServerResponse *response =
482 AsyncWebServerResponse *response =
485 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
486 request->send(response);
493static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
495 size_t prefix_len = strlen(prefix);
496 size_t name_len = name.
size();
500 const char *device_name = device ? device->
get_name() :
nullptr;
501 size_t device_len = device_name ? strlen(device_name) : 0;
510 static constexpr size_t ID_BUF_SIZE =
511 ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
513 static constexpr size_t ID_BUF_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
515 char id_buf[ID_BUF_SIZE];
517 memcpy(p, prefix, prefix_len);
522 memcpy(p, device_name, device_len);
527 memcpy(p, name.
c_str(), name_len);
532 root[ESPHOME_F(
"name_id")] = id_buf;
536 char legacy_buf[ESPHOME_DOMAIN_MAX_LEN + 1 + OBJECT_ID_MAX_LEN];
537 char *lp = legacy_buf;
538 memcpy(lp, prefix, prefix_len);
542 root[ESPHOME_F(
"id")] = legacy_buf;
545 root[ESPHOME_F(
"domain")] = prefix;
546 root[ESPHOME_F(
"name")] = name;
549 root[ESPHOME_F(
"device")] = device_name;
556 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
563static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
565 set_json_id(root, obj, prefix, start_config);
566 root[ESPHOME_F(
"value")] = value;
570static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const char *
state,
572 set_json_value(root, obj, prefix, value, start_config);
573 root[ESPHOME_F(
"state")] =
state;
577static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
578 auto *param = request->getParam(ESPHOME_F(
"detail"));
591 if (!entity_match.matched)
594 if (entity_match.action_is_empty) {
595 auto detail = get_request_detail(request);
596 std::string data = this->sensor_json_(obj, obj->state, detail);
597 request->send(200,
"application/json", data.c_str());
611 JsonObject root = builder.
root();
614 char buf[VALUE_ACCURACY_MAX_LEN];
615 const char *
state = std::isnan(value)
618 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
621 if (!uom_ref.empty())
622 root[ESPHOME_F(
"uom")] = uom_ref;
629#ifdef USE_TEXT_SENSOR
638 if (!entity_match.matched)
641 if (entity_match.action_is_empty) {
642 auto detail = get_request_detail(request);
643 std::string data = this->text_sensor_json_(obj, obj->
state, detail);
644 request->send(200,
"application/json", data.c_str());
661 JsonObject root = builder.
root();
663 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
681 if (!entity_match.matched)
684 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
685 auto detail = get_request_detail(request);
686 std::string data = this->switch_json_(obj, obj->
state, detail);
687 request->send(200,
"application/json", data.c_str());
692 enum SwitchAction { NONE, TOGGLE, TURN_ON, TURN_OFF };
693 SwitchAction action = NONE;
703 if (action != NONE) {
704 this->
defer([obj, action]() {
735 JsonObject root = builder.
root();
737 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
751 if (!entity_match.matched)
753 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
754 auto detail = get_request_detail(request);
755 std::string data = this->button_json_(obj, detail);
756 request->send(200,
"application/json", data.c_str());
758 this->
defer([obj]() { obj->press(); });
776 JsonObject root = builder.
root();
778 set_json_id(root, obj,
"button", start_config);
787#ifdef USE_BINARY_SENSOR
796 if (!entity_match.matched)
799 if (entity_match.action_is_empty) {
800 auto detail = get_request_detail(request);
801 std::string data = this->binary_sensor_json_(obj, obj->state, detail);
802 request->send(200,
"application/json", data.c_str());
818 JsonObject root = builder.
root();
820 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
838 if (!entity_match.matched)
841 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
842 auto detail = get_request_detail(request);
843 std::string data = this->fan_json_(obj, detail);
844 request->send(200,
"application/json", data.c_str());
846 this->
defer([obj]() { obj->toggle().perform(); });
851 if (!is_on && !is_off) {
855 auto call = is_on ? obj->turn_on() : obj->turn_off();
859 if (request->hasParam(ESPHOME_F(
"oscillation"))) {
860 auto speed = request->getParam(ESPHOME_F(
"oscillation"))->value();
864 call.set_oscillating(
true);
867 call.set_oscillating(
false);
870 call.set_oscillating(!obj->oscillating);
892 JsonObject root = builder.
root();
894 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
896 if (traits.supports_speed()) {
897 root[ESPHOME_F(
"speed_level")] = obj->
speed;
898 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
919 if (!entity_match.matched)
922 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
923 auto detail = get_request_detail(request);
924 std::string data = this->light_json_(obj, detail);
925 request->send(200,
"application/json", data.c_str());
932 if (!is_on && !is_off) {
971 JsonObject root = builder.
root();
973 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
977 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
980 opt.add(option->get_name());
998 if (!entity_match.matched)
1001 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1002 auto detail = get_request_detail(request);
1003 std::string data = this->cover_json_(obj, detail);
1004 request->send(200,
"application/json", data.c_str());
1011 static const struct {
1022 for (
const auto &method : METHODS) {
1024 (
call.*method.action)();
1036 if ((request->hasParam(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1037 (request->hasParam(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1059 JsonObject root = builder.
root();
1063 char buf[PSTR_LOCAL_SIZE];
1067 root[ESPHOME_F(
"position")] = obj->
position;
1069 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1085 for (
auto *obj :
App.get_numbers()) {
1087 if (!entity_match.matched)
1090 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1091 auto detail = get_request_detail(request);
1092 std::string data = this->number_json_(obj, obj->state, detail);
1093 request->send(200,
"application/json", data.c_str());
1119 JsonObject root = builder.
root();
1125 char val_buf[VALUE_ACCURACY_MAX_LEN];
1126 char state_buf[VALUE_ACCURACY_MAX_LEN];
1127 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1128 const char *state_str =
1130 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1137 if (!uom_ref.empty())
1138 root[ESPHOME_F(
"uom")] = uom_ref;
1146#ifdef USE_DATETIME_DATE
1153 for (
auto *obj :
App.get_dates()) {
1155 if (!entity_match.matched)
1157 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1158 auto detail = get_request_detail(request);
1159 std::string data = this->date_json_(obj, detail);
1160 request->send(200,
"application/json", data.c_str());
1170 if (!request->hasParam(ESPHOME_F(
"value"))) {
1192 JsonObject root = builder.
root();
1197 snprintf_P(value,
sizeof(value), PSTR(
"%d-%02d-%02d"), obj->
year, obj->
month, obj->
day);
1199 snprintf(value,
sizeof(value),
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1201 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1210#ifdef USE_DATETIME_TIME
1217 for (
auto *obj :
App.get_times()) {
1219 if (!entity_match.matched)
1221 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1222 auto detail = get_request_detail(request);
1223 std::string data = this->time_json_(obj, detail);
1224 request->send(200,
"application/json", data.c_str());
1234 if (!request->hasParam(ESPHOME_F(
"value"))) {
1255 JsonObject root = builder.
root();
1260 snprintf_P(value,
sizeof(value), PSTR(
"%02d:%02d:%02d"), obj->
hour, obj->
minute, obj->
second);
1262 snprintf(value,
sizeof(value),
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1264 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1273#ifdef USE_DATETIME_DATETIME
1280 for (
auto *obj :
App.get_datetimes()) {
1282 if (!entity_match.matched)
1284 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1285 auto detail = get_request_detail(request);
1286 std::string data = this->datetime_json_(obj, detail);
1287 request->send(200,
"application/json", data.c_str());
1297 if (!request->hasParam(ESPHOME_F(
"value"))) {
1318 JsonObject root = builder.
root();
1323 snprintf_P(value,
sizeof(value), PSTR(
"%d-%02d-%02d %02d:%02d:%02d"), obj->
year, obj->
month, obj->
day, obj->
hour,
1326 snprintf(value,
sizeof(value),
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour, obj->
minute,
1329 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1345 for (
auto *obj :
App.get_texts()) {
1347 if (!entity_match.matched)
1350 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1351 auto detail = get_request_detail(request);
1352 std::string data = this->text_json_(obj, obj->state, detail);
1353 request->send(200,
"application/json", data.c_str());
1377std::string WebServer::text_json_(
text::Text *obj,
const std::string &value,
JsonDetail start_config) {
1379 JsonObject root = builder.
root();
1382 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1402 for (
auto *obj :
App.get_selects()) {
1404 if (!entity_match.matched)
1407 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1408 auto detail = get_request_detail(request);
1409 std::string data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail);
1410 request->send(200,
"application/json", data.c_str());
1438 JsonObject root = builder.
root();
1441 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1443 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1461 for (
auto *obj :
App.get_climates()) {
1463 if (!entity_match.matched)
1466 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1467 auto detail = get_request_detail(request);
1468 std::string data = this->climate_json_(obj, detail);
1469 request->send(200,
"application/json", data.c_str());
1487 &
decltype(
call)::set_target_temperature_high);
1508 JsonObject root = builder.
root();
1509 set_json_id(root, obj,
"climate", start_config);
1512 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1513 char buf[PSTR_LOCAL_SIZE];
1514 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1517 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1520 if (!traits.get_supported_custom_fan_modes().empty()) {
1521 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1526 if (!traits.get_supported_custom_fan_modes().empty()) {
1527 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1528 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1531 if (traits.get_supports_swing_modes()) {
1532 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1533 for (
auto swing_mode : traits.get_supported_swing_modes())
1537 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1541 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1542 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1543 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1549 bool has_state =
false;
1551 root[ESPHOME_F(
"max_temp")] =
1553 root[ESPHOME_F(
"min_temp")] =
1555 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1558 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1570 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1573 if (traits.get_supports_swing_modes()) {
1577 root[ESPHOME_F(
"current_temperature")] =
1584 root[ESPHOME_F(
"target_temperature_low")] =
1586 root[ESPHOME_F(
"target_temperature_high")] =
1589 root[ESPHOME_F(
"state")] =
1595 root[ESPHOME_F(
"target_temperature")] =
1598 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1615 if (!entity_match.matched)
1618 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1619 auto detail = get_request_detail(request);
1620 std::string data = this->lock_json_(obj, obj->state, detail);
1621 request->send(200,
"application/json", data.c_str());
1626 enum LockAction { NONE, LOCK, UNLOCK, OPEN };
1627 LockAction action = NONE;
1637 if (action != NONE) {
1638 this->
defer([obj, action]() {
1669 JsonObject root = builder.
root();
1671 char buf[PSTR_LOCAL_SIZE];
1690 if (!entity_match.matched)
1693 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1694 auto detail = get_request_detail(request);
1695 std::string data = this->valve_json_(obj, detail);
1696 request->send(200,
"application/json", data.c_str());
1703 static const struct {
1714 for (
const auto &method : METHODS) {
1716 (
call.*method.action)();
1727 auto traits = obj->get_traits();
1728 if (request->hasParam(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1749 JsonObject root = builder.
root();
1753 char buf[PSTR_LOCAL_SIZE];
1757 root[ESPHOME_F(
"position")] = obj->
position;
1766#ifdef USE_ALARM_CONTROL_PANEL
1775 if (!entity_match.matched)
1778 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1779 auto detail = get_request_detail(request);
1780 std::string data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1781 request->send(200,
"application/json", data.c_str());
1789 static const struct {
1801 for (
const auto &method : METHODS) {
1803 (
call.*method.action)();
1834 JsonObject root = builder.
root();
1836 char buf[PSTR_LOCAL_SIZE];
1837 set_json_icon_state_value(root, obj,
"alarm-control-panel", PSTR_LOCAL(alarm_control_panel_state_to_string(value)),
1838 value, start_config);
1847#ifdef USE_WATER_HEATER
1856 if (!entity_match.matched)
1859 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1860 auto detail = get_request_detail(request);
1861 std::string data = this->water_heater_json_(obj, detail);
1862 request->send(200,
"application/json", data.c_str());
1906 JsonObject root = builder.
root();
1907 char buf[PSTR_LOCAL_SIZE];
1912 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1917 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1918 for (
auto m : traits.get_supported_modes())
1923 if (traits.get_supports_current_temperature()) {
1925 if (!std::isnan(current))
1926 root[ESPHOME_F(
"current_temperature")] = current;
1929 if (traits.get_supports_two_point_target_temperature()) {
1932 if (!std::isnan(low))
1933 root[ESPHOME_F(
"target_temperature_low")] = low;
1934 if (!std::isnan(high))
1935 root[ESPHOME_F(
"target_temperature_high")] = high;
1938 if (!std::isnan(target))
1939 root[ESPHOME_F(
"target_temperature")] = target;
1943 root[ESPHOME_F(
"max_temperature")] = traits.get_max_temperature();
1944 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
1946 if (traits.get_supports_away_mode()) {
1947 root[ESPHOME_F(
"away")] = obj->
is_away();
1951 root[ESPHOME_F(
"is_on")] = obj->
is_on();
1968 if (!entity_match.matched)
1972 if (entity_match.action_is_empty) {
1973 auto detail = get_request_detail(request);
1974 std::string data = this->event_json_(obj,
StringRef(), detail);
1975 request->send(200,
"application/json", data.c_str());
1986 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
1991 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
1995 JsonObject root = builder.
root();
1997 set_json_id(root, obj,
"event", start_config);
1998 if (!event_type.
empty()) {
1999 root[ESPHOME_F(
"event_type")] = event_type;
2002 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2004 event_types.add(event_type);
2019 return LOG_STR(
"NO UPDATE");
2021 return LOG_STR(
"UPDATE AVAILABLE");
2023 return LOG_STR(
"INSTALLING");
2025 return LOG_STR(
"UNKNOWN");
2035 if (!entity_match.matched)
2038 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2039 auto detail = get_request_detail(request);
2040 std::string data = this->update_json_(obj, detail);
2041 request->send(200,
"application/json", data.c_str());
2050 this->
defer([obj]()
mutable { obj->perform(); });
2067 JsonObject root = builder.
root();
2069 char buf[PSTR_LOCAL_SIZE];
2070 set_json_icon_state_value(root, obj,
"update", PSTR_LOCAL(update_state_to_string(obj->
state)),
2086 const auto &url = request->url();
2087 const auto method = request->method();
2090 static const char *
const STATIC_URLS[] = {
2092#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2095#ifdef USE_WEBSERVER_CSS_INCLUDE
2098#ifdef USE_WEBSERVER_JS_INCLUDE
2103 for (
const auto &static_url : STATIC_URLS) {
2104 if (url == static_url)
2108#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2109 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2114 UrlMatch match = match_url(url.c_str(), url.length(),
true);
2119 bool is_get = method == HTTP_GET;
2120 bool is_post = method == HTTP_POST;
2121 bool is_get_or_post = is_get || is_post;
2123 if (!is_get_or_post)
2127 static const char *
const GET_ONLY_DOMAINS[] = {
2131#ifdef USE_BINARY_SENSOR
2134#ifdef USE_TEXT_SENSOR
2142 static const char *
const GET_POST_DOMAINS[] = {
2161#ifdef USE_DATETIME_DATE
2164#ifdef USE_DATETIME_TIME
2167#ifdef USE_DATETIME_DATETIME
2185#ifdef USE_ALARM_CONTROL_PANEL
2186 "alarm_control_panel",
2191#ifdef USE_WATER_HEATER
2198 for (
const auto &domain : GET_ONLY_DOMAINS) {
2205 if (is_get_or_post) {
2206 for (
const auto &domain : GET_POST_DOMAINS) {
2215 const auto &url = request->url();
2223#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2224 if (url ==
"/events") {
2225 this->
events_.add_new_client(
this, request);
2230#ifdef USE_WEBSERVER_CSS_INCLUDE
2231 if (url ==
"/0.css") {
2237#ifdef USE_WEBSERVER_JS_INCLUDE
2238 if (url ==
"/0.js") {
2244#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2245 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2253 UrlMatch match = match_url(url.c_str(), url.length(),
false, request->method() == HTTP_POST);
2274#ifdef USE_BINARY_SENSOR
2289#ifdef USE_TEXT_SENSOR
2304#ifdef USE_DATETIME_DATE
2309#ifdef USE_DATETIME_TIME
2314#ifdef USE_DATETIME_DATETIME
2344#ifdef USE_ALARM_CONTROL_PANEL
2345 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2354#ifdef USE_WATER_HEATER
2361 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.c_str());
2362 request->send(404,
"text/plain",
"Not Found");
2369#ifdef USE_WEBSERVER_SORTING
2372 if (this->
sorting_groups_.find(this->sorting_entitys_[entity].group_id) != this->sorting_groups_.end()) {
2379#ifdef USE_WEBSERVER_SORTING
BedjetMode mode
BedJet operating mode.
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
const std::string & get_name() const
Get the name of this Application set by pre_setup().
void get_comment_string(std::span< char, ESPHOME_COMMENT_SIZE > buffer)
Copy the comment string into the provided buffer Buffer must be ESPHOME_COMMENT_SIZE bytes (compile-t...
auto & get_binary_sensors() const
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_interval(const std voi set_interval)(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
void begin(bool include_internal=false)
static void register_controller(Controller *controller)
Register a controller to receive entity state updates.
StringRef get_device_class_ref() const
Get the device class as StringRef.
StringRef get_unit_of_measurement_ref() const
Get the unit of measurement as StringRef.
const StringRef & get_name() const
StringRef get_icon_ref() const
size_t write_object_id_to(char *buf, size_t buf_size) const
Write object_id directly to buffer, returns length written (excluding null) Useful for building compo...
bool is_disabled_by_default() const
Device * get_device() const
EntityCategory get_entity_category() const
StringRef get_object_id_to(std::span< char, OBJECT_ID_MAX_LEN > buf) const
Get object_id with zero heap allocation For static case: returns StringRef to internal storage (buffe...
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
constexpr bool empty() const
constexpr size_type size() const
AlarmControlPanelCall & arm_night()
AlarmControlPanelCall & disarm()
AlarmControlPanelCall & arm_away()
AlarmControlPanelCall & arm_home()
AlarmControlPanelCall & arm_vacation()
AlarmControlPanelCall make_call()
Make a AlarmControlPanelCall.
Base class for all binary_sensor-type classes.
ClimateDevice - This is the base class for all climate integrations.
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
float target_temperature
The target temperature of the climate device.
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
bool has_custom_preset() const
Check if a custom preset is currently active.
float current_temperature
The current temperature of the climate device, as reported from the integration.
ClimateAction action
The active state of the climate device.
StringRef get_custom_preset() const
Get the active custom preset (read-only access). Returns StringRef.
bool has_custom_fan_mode() const
Check if a custom fan mode is currently active.
optional< ClimatePreset > preset
The active preset of the climate device.
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
StringRef get_custom_fan_mode() const
Get the active custom fan mode (read-only access). Returns StringRef.
int8_t get_target_temperature_accuracy_decimals() const
CoverCall & set_command_toggle()
Set the command to toggle the cover.
CoverCall & set_command_open()
Set the command to open the cover.
CoverCall & set_command_close()
Set the command to close the cover.
CoverCall & set_command_stop()
Set the command to stop the cover.
Base class for all cover devices.
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
CoverCall make_call()
Construct a new cover call used to control the cover.
float tilt
The current tilt value of the cover from 0.0 to 1.0.
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
bool is_fully_closed() const
Helper method to check if the cover is fully closed. Equivalent to comparing .position against 0....
virtual CoverTraits get_traits()=0
bool get_supports_position() const
bool get_supports_tilt() const
const FixedVector< const char * > & get_event_types() const
Return the event types supported by this event.
virtual FanTraits get_traits()=0
bool oscillating
The current oscillation state of the fan.
bool state
The current on/off state of the fan.
int speed
The current fan speed level.
bool supports_oscillation() const
Return if this fan supports oscillation.
Builder class for creating JSON documents without lambdas.
bool is_on() const
Get the binary true/false state of these light color values.
static void dump_json(LightState &state, JsonObject root)
Dump the state of a light as JSON.
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
LightColorValues remote_values
The remote color values reported to the frontend.
const FixedVector< LightEffect * > & get_effects() const
Get all effects for this light state.
Base class for all locks.
LockCall make_call()
Make a lock device control call, this is used to control the lock device, see the LockCall descriptio...
void add_log_listener(LogListener *listener)
Register a log listener to receive log messages.
Base-class for all numbers.
float get_min_value() const
float get_max_value() const
NumberMode get_mode() const
value_type const & value() const
Base-class for all selects.
SelectCall make_call()
Instantiate a SelectCall object to modify this select component's state.
const FixedVector< const char * > & get_options() const
Base-class for all sensors.
float state
This member variable stores the last state that has passed through all filters.
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Base class for all switches.
virtual bool assumed_state()
Return whether this switch uses an assumed state - i.e.
Base-class for all text inputs.
TextCall make_call()
Instantiate a TextCall object to modify this text component's state.
TextMode get_mode() const
int get_max_length() const
int get_min_length() const
const char * get_pattern_c_str() const
const UpdateState & state
const UpdateInfo & update_info
ValveCall & set_command_close()
Set the command to close the valve.
ValveCall & set_command_toggle()
Set the command to toggle the valve.
ValveCall & set_command_stop()
Set the command to stop the valve.
ValveCall & set_command_open()
Set the command to open the valve.
Base class for all valve devices.
bool is_fully_closed() const
Helper method to check if the valve is fully closed. Equivalent to comparing .position against 0....
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
ValveCall make_call()
Construct a new valve call used to control the valve.
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
virtual ValveTraits get_traits()=0
bool get_supports_position() const
WaterHeaterCall & set_away(bool away)
WaterHeaterCall & set_target_temperature_high(float temperature)
WaterHeaterCall & set_mode(WaterHeaterMode mode)
WaterHeaterCall & set_target_temperature_low(float temperature)
WaterHeaterCall & set_on(bool on)
WaterHeaterCall & set_target_temperature(float temperature)
float get_target_temperature_low() const
float get_target_temperature() const
bool is_on() const
Check if the water heater is on.
float get_current_temperature() const
bool is_away() const
Check if away mode is currently active.
WaterHeaterMode get_mode() const
virtual WaterHeaterTraits get_traits()
float get_target_temperature_high() const
float get_min_temperature() const
void process_deferred_queue_()
void try_send_nodefer(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
static constexpr uint16_t MAX_CONSECUTIVE_SEND_FAILURES
uint16_t consecutive_send_failures_
void deq_push_back_with_dedup_(void *source, message_generator_t *message_generator)
void deferrable_send_state(void *source, const char *event_type, message_generator_t *message_generator)
ListEntitiesIterator entities_iterator_
std::vector< DeferredEvent > deferred_queue_
void on_client_connect_(DeferredUpdateEventSource *source)
void add_new_client(WebServer *ws, AsyncWebServerRequest *request)
void deferrable_send_state(void *source, const char *event_type, message_generator_t *message_generator)
void try_send_nodefer(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
void on_client_disconnect_(DeferredUpdateEventSource *source)
This class allows users to create a web server with their ESP nodes.
static std::string water_heater_state_json_generator(WebServer *web_server, void *source)
void setup() override
Setup the internal web server and register handlers.
void on_update(update::UpdateEntity *obj) override
static std::string text_sensor_all_json_generator(WebServer *web_server, void *source)
void on_water_heater_update(water_heater::WaterHeater *obj) override
static std::string water_heater_all_json_generator(WebServer *web_server, void *source)
std::string get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static std::string binary_sensor_state_json_generator(WebServer *web_server, void *source)
void parse_string_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(const std::string &))
void on_text_update(text::Text *obj) override
static std::string button_state_json_generator(WebServer *web_server, void *source)
static std::string lock_all_json_generator(WebServer *web_server, void *source)
void on_light_update(light::LightState *obj) override
static std::string date_all_json_generator(WebServer *web_server, void *source)
void parse_float_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(float))
void on_cover_update(cover::Cover *obj) override
static std::string text_state_json_generator(WebServer *web_server, void *source)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
static std::string event_state_json_generator(WebServer *web_server, void *source)
void handle_water_heater_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a water_heater request under '/water_heater/<id>/<mode/set>'.
static std::string datetime_all_json_generator(WebServer *web_server, void *source)
static std::string sensor_all_json_generator(WebServer *web_server, void *source)
bool isRequestHandlerTrivial() const override
This web handle is not trivial.
WebServer(web_server_base::WebServerBase *base)
void handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a switch request under '/switch/<id>/</turn_on/turn_off/toggle>'.
void handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a event request under '/event<id>'.
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override
void parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
void dump_config() override
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a button request under '/button/<id>/press'.
void on_date_update(datetime::DateEntity *obj) override
void on_number_update(number::Number *obj) override
void add_entity_config(EntityBase *entity, float weight, uint64_t group)
void parse_light_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(float), float scale=1.0f)
void handle_css_request(AsyncWebServerRequest *request)
Handle included css request under '/0.css'.
static std::string sensor_state_json_generator(WebServer *web_server, void *source)
void on_valve_update(valve::Valve *obj) override
void on_climate_update(climate::Climate *obj) override
static std::string switch_state_json_generator(WebServer *web_server, void *source)
void parse_int_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(int))
void add_sorting_info_(JsonObject &root, EntityBase *entity)
void handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a light request under '/light/<id>/</turn_on/turn_off/toggle>'.
static std::string event_all_json_generator(WebServer *web_server, void *source)
static std::string climate_state_json_generator(WebServer *web_server, void *source)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
static std::string number_all_json_generator(WebServer *web_server, void *source)
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
static std::string date_state_json_generator(WebServer *web_server, void *source)
static std::string valve_all_json_generator(WebServer *web_server, void *source)
static std::string text_all_json_generator(WebServer *web_server, void *source)
void on_switch_update(switch_::Switch *obj) override
web_server_base::WebServerBase * base_
static std::string binary_sensor_all_json_generator(WebServer *web_server, void *source)
static std::string light_state_json_generator(WebServer *web_server, void *source)
void handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a lock request under '/lock/<id>/</lock/unlock/open>'.
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
static std::string light_all_json_generator(WebServer *web_server, void *source)
void handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text sensor request under '/text_sensor/<id>'.
void parse_bool_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(bool))
void handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a date request under '/date/<id>'.
static std::string cover_all_json_generator(WebServer *web_server, void *source)
void handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a sensor request under '/sensor/<id>'.
static std::string text_sensor_state_json_generator(WebServer *web_server, void *source)
void handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a number request under '/number/<id>'.
static std::string alarm_control_panel_state_json_generator(WebServer *web_server, void *source)
void handle_index_request(AsyncWebServerRequest *request)
Handle an index request under '/'.
void handle_js_request(AsyncWebServerRequest *request)
Handle included js request under '/0.js'.
void set_js_include(const char *js_include)
Set local path to the script that's embedded in the index page.
static std::string fan_state_json_generator(WebServer *web_server, void *source)
static std::string update_state_json_generator(WebServer *web_server, void *source)
void handleRequest(AsyncWebServerRequest *request) override
Override the web handler's handleRequest method.
static std::string climate_all_json_generator(WebServer *web_server, void *source)
void on_datetime_update(datetime::DateTimeEntity *obj) override
void handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a fan request under '/fan/<id>/</turn_on/turn_off/toggle>'.
static std::string cover_state_json_generator(WebServer *web_server, void *source)
static std::string lock_state_json_generator(WebServer *web_server, void *source)
void handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a valve request under '/valve/<id>/<open/close/stop/set>'.
void handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a binary sensor request under '/binary_sensor/<id>'.
static std::string alarm_control_panel_all_json_generator(WebServer *web_server, void *source)
static std::string number_state_json_generator(WebServer *web_server, void *source)
void handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a time request under '/time/<id>'.
void on_sensor_update(sensor::Sensor *obj) override
std::map< uint64_t, SortingGroup > sorting_groups_
void set_css_include(const char *css_include)
Set local path to the script that's embedded in the index page.
static std::string valve_state_json_generator(WebServer *web_server, void *source)
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
void on_event(event::Event *obj) override
void handle_pna_cors_request(AsyncWebServerRequest *request)
void on_fan_update(fan::Fan *obj) override
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
static std::string time_state_json_generator(WebServer *web_server, void *source)
void on_lock_update(lock::Lock *obj) override
static std::string button_all_json_generator(WebServer *web_server, void *source)
static std::string select_state_json_generator(WebServer *web_server, void *source)
float get_setup_priority() const override
MQTT setup priority.
void on_select_update(select::Select *obj) override
void on_time_update(datetime::TimeEntity *obj) override
static std::string update_all_json_generator(WebServer *web_server, void *source)
void handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a update request under '/update/<id>'.
static std::string fan_all_json_generator(WebServer *web_server, void *source)
static std::string switch_all_json_generator(WebServer *web_server, void *source)
static std::string time_all_json_generator(WebServer *web_server, void *source)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
static std::string select_all_json_generator(WebServer *web_server, void *source)
const char * css_include_
static std::string datetime_state_json_generator(WebServer *web_server, void *source)
void handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a climate request under '/climate/<id>'.
void on_text_sensor_update(text_sensor::TextSensor *obj) override
void add_handler(AsyncWebHandler *handler)
uint16_t get_port() const
ClimateSwingMode swing_mode
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
@ CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_SUPPORTS_ACTION
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
ClimateMode
Enum for all modes a climate device can be in.
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
const LogString * cover_operation_to_str(CoverOperation op)
const LogString * lock_state_to_string(LockState state)
LockState
Enum for all states a lock can be in.
const char * get_use_address()
Get the active network hostname.
@ UPDATE_STATE_INSTALLING
const LogString * valve_operation_to_str(ValveOperation op)
@ WATER_HEATER_SUPPORTS_ON_OFF
The water heater can be turned on/off.
const LogString * water_heater_mode_to_string(WaterHeaterMode mode)
Convert the given WaterHeaterMode to a human-readable string for logging.
std::string(WebServer *, void *) message_generator_t
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Parse a string that contains either on, off or toggle.
int8_t step_to_accuracy_decimals(float step)
Derive accuracy in decimals from an increment step.
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
size_t value_accuracy_with_uom_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals, StringRef unit_of_measurement)
Format value with accuracy and UOM to buffer, returns chars written (excluding null)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
std::string current_version
std::string latest_version
Result of matching a URL against an entity.
Internal helper struct that is used to parse incoming URLs.
StringRef device_name
Device name within URL, empty for main device.
bool valid
Whether this match is valid.
EntityMatchResult match_entity(EntityBase *entity) const
Match entity by name first, then fall back to object_id with deprecation warning Returns EntityMatchR...
StringRef method
Method within URL, for example "turn_on".
bool domain_equals(const char *str) const
bool method_equals(const char *str) const
StringRef domain
Domain within URL, for example "sensor".
friend class DeferredUpdateEventSource
const size_t ESPHOME_WEBSERVER_INDEX_HTML_SIZE
const size_t ESPHOME_WEBSERVER_CSS_INCLUDE_SIZE
const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE