14#if !defined(USE_ESP32) && defined(USE_ARDUINO)
15#include "StreamString.h"
36#ifdef USE_WATER_HEATER
43#ifdef USE_RADIO_FREQUENCY
47#ifdef USE_WEBSERVER_LOCAL
48#if USE_WEBSERVER_VERSION == 2
50#elif USE_WEBSERVER_VERSION == 3
57static const char *
const TAG =
"web_server";
60static constexpr size_t PSTR_LOCAL_SIZE = 18;
61#define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1)
69static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain,
bool is_post =
false) {
71 if (url_len < 2 || url_ptr[0] !=
'/')
74 const char *p = url_ptr + 1;
75 const char *
end = url_ptr + url_len;
78 auto next_segment = [&
end](
const char *start) ->
const char * {
79 const char *slash = (
const char *) memchr(start,
'/',
end - start);
80 return slash ? slash + 1 :
nullptr;
84 auto make_ref = [&
end](
const char *start,
const char *next_start) -> StringRef {
85 return StringRef(start, (next_start ? next_start - 1 :
end) - start);
90 const char *s2 = next_segment(s1);
97 match.domain = make_ref(s1, s2);
100 if (only_domain || s2 >=
end)
104 const char *s3 = next_segment(s2);
105 const char *s4 = s3 ? next_segment(s3) : nullptr;
107 StringRef seg2 = make_ref(s2, s3);
108 StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef();
109 StringRef seg4 = s4 ? make_ref(s4,
nullptr) : StringRef();
112 if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty()))
128 match.device_name = seg2;
139 match.device_name = seg2;
156 bool entity_has_device = (entity_device !=
nullptr);
159 if (url_has_device != entity_has_device) {
168 if (this->
id == entity->
get_name()) {
169 result.matched =
true;
174 char object_id_buf[OBJECT_ID_MAX_LEN];
176 if (this->
id == object_id) {
177 result.matched =
true;
181 if (device !=
nullptr) {
183 "Deprecated URL format: /%.*s/%.*s/%.*s - use entity name '/%.*s/%s/%s' instead. "
184 "Object ID URLs will be removed in 2026.7.0.",
185 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->device_name.size(),
186 this->device_name.c_str(), (
int) this->id.size(), this->id.c_str(), (
int) this->domain.size(),
192 "Deprecated URL format: /%.*s/%.*s - use entity name '/%.*s/%s' instead. "
193 "Object ID URLs will be removed in 2026.7.0.",
194 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->id.size(), this->id.c_str(),
195 (
int) this->domain.size(), this->domain.c_str(), entity->
get_name().
c_str());
202#if !defined(USE_ESP32) && defined(USE_ARDUINO)
206 DeferredEvent item(source, message_generator);
214 this->deferred_queue_.push_back(item);
221 if (this->send(
message.c_str(),
"state") != DISCARDED) {
233 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
252 if (this->count() == 0)
260 if (source ==
nullptr)
262 if (event_type ==
nullptr)
264 if (message_generator ==
nullptr)
267 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
268 ESP_LOGE(TAG,
"Can't defer non-state event");
278 if (this->send(
message.c_str(),
"state") == DISCARDED) {
289 this->send(
message, event,
id, reconnect);
296 return !this->empty();
320 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
324 es->handleRequest(request);
330 ws->
defer([ws, source]() {
336#ifdef USE_WEBSERVER_SORTING
339 JsonObject root = builder.
root();
340 root[ESPHOME_F(
"name")] = group.second.name;
341 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
363 this->remove(source);
371#ifdef USE_WEBSERVER_CSS_INCLUDE
374#ifdef USE_WEBSERVER_JS_INCLUDE
380 JsonObject root = builder.
root();
385 root[ESPHOME_F(
"comment")] = comment_buffer;
386#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
387 root[ESPHOME_F(
"ota")] =
false;
389 root[ESPHOME_F(
"ota")] =
true;
392 root[ESPHOME_F(
"lang")] =
"en";
405 this, [](
void *self, uint8_t level,
const char *
tag,
const char *
message,
size_t message_len) {
425 buf_append_printf(buf,
sizeof(buf), 0,
"{\"uptime\":%" PRIu32
"}", uptime);
426 this->
events_.try_send_nodefer(buf,
"ping",
millis(), 30000);
457#ifdef USE_WEBSERVER_LOCAL
460 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
462 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
464#ifdef USE_WEBSERVER_GZIP
465 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
467 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
469 request->send(response);
471#elif USE_WEBSERVER_VERSION >= 2
474 AsyncWebServerResponse *response =
477 AsyncWebServerResponse *response =
481 request->send(response);
485#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
487 AsyncWebServerResponse *response = request->beginResponse(200, ESPHOME_F(
""));
488 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
489 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().
c_str());
492 request->send(response);
496#ifdef USE_WEBSERVER_CSS_INCLUDE
499 AsyncWebServerResponse *response =
502 AsyncWebServerResponse *response =
505 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
506 request->send(response);
510#ifdef USE_WEBSERVER_JS_INCLUDE
513 AsyncWebServerResponse *response =
516 AsyncWebServerResponse *response =
519 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
520 request->send(response);
527static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
529 size_t prefix_len = strlen(prefix);
530 size_t name_len = name.
size();
534 const char *device_name = device ? device->
get_name() :
nullptr;
535 size_t device_len = device_name ? strlen(device_name) : 0;
544 static constexpr size_t LEGACY_ID_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + OBJECT_ID_MAX_LEN;
546 static constexpr size_t ID_BUF_SIZE =
547 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1,
550 static constexpr size_t ID_BUF_SIZE =
551 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1, LEGACY_ID_SIZE);
553 char id_buf[ID_BUF_SIZE];
554 memcpy(id_buf, prefix, prefix_len);
558 char *p = id_buf + prefix_len;
562 memcpy(p, device_name, device_len);
567 memcpy(p, name.
c_str(), name_len);
569 root[ESPHOME_F(
"name_id")] = id_buf;
573 id_buf[prefix_len] =
'-';
575 root[ESPHOME_F(
"id")] = id_buf;
578 root[ESPHOME_F(
"domain")] = prefix;
580 root[ESPHOME_F(
"name")] = name.
c_str();
583 root[ESPHOME_F(
"device")] = device_name;
586#ifdef USE_ENTITY_ICON
587 char icon_buf[MAX_ICON_LENGTH];
588 root[ESPHOME_F(
"icon")] = obj->
get_icon_to(icon_buf);
593 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
600static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
602 set_json_id(root, obj, prefix, start_config);
603 root[ESPHOME_F(
"value")] = value;
607static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const char *
state,
609 set_json_value(root, obj, prefix, value, start_config);
610 root[ESPHOME_F(
"state")] =
state;
614[[maybe_unused]]
static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
627 if (!entity_match.matched)
630 if (entity_match.action_is_empty) {
631 auto detail = get_request_detail(request);
632 auto data = this->sensor_json_(obj, obj->state, detail);
633 request->send(200,
"application/json", data.c_str());
647 JsonObject root = builder.
root();
650 char buf[VALUE_ACCURACY_MAX_LEN];
651 const char *
state = std::isnan(value)
654 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
657 if (!uom_ref.empty())
658 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
665#ifdef USE_TEXT_SENSOR
674 if (!entity_match.matched)
677 if (entity_match.action_is_empty) {
678 auto detail = get_request_detail(request);
679 auto data = this->text_sensor_json_(obj, obj->
state, detail);
680 request->send(200,
"application/json", data.c_str());
697 JsonObject root = builder.
root();
699 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
735 if (!entity_match.matched)
738 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
739 auto detail = get_request_detail(request);
740 auto data = this->switch_json_(obj, obj->
state, detail);
741 request->send(200,
"application/json", data.c_str());
756 this->
defer([obj, action]() { execute_switch_action(obj, action); });
773 JsonObject root = builder.
root();
775 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
789 if (!entity_match.matched)
791 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
792 auto detail = get_request_detail(request);
793 auto data = this->button_json_(obj, detail);
794 request->send(200,
"application/json", data.c_str());
796 DEFER_ACTION(obj, obj->press());
811 JsonObject root = builder.
root();
813 set_json_id(root, obj,
"button", start_config);
822#ifdef USE_BINARY_SENSOR
831 if (!entity_match.matched)
834 if (entity_match.action_is_empty) {
835 auto detail = get_request_detail(request);
836 auto data = this->binary_sensor_json_(obj, obj->state, detail);
837 request->send(200,
"application/json", data.c_str());
854 JsonObject root = builder.
root();
856 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
874 if (!entity_match.matched)
877 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
878 auto detail = get_request_detail(request);
879 auto data = this->fan_json_(obj, detail);
880 request->send(200,
"application/json", data.c_str());
882 DEFER_ACTION(obj, obj->toggle().perform());
887 if (!is_on && !is_off) {
891 auto call = is_on ? obj->turn_on() : obj->turn_off();
895 if (request->hasArg(ESPHOME_F(
"oscillation"))) {
896 auto speed = request->arg(ESPHOME_F(
"oscillation"));
900 call.set_oscillating(
true);
903 call.set_oscillating(
false);
906 call.set_oscillating(!obj->oscillating);
928 JsonObject root = builder.
root();
930 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
932 if (traits.supports_speed()) {
933 root[ESPHOME_F(
"speed_level")] = obj->
speed;
934 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
955 if (!entity_match.matched)
958 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
959 auto detail = get_request_detail(request);
960 auto data = this->light_json_(obj, detail);
961 request->send(200,
"application/json", data.c_str());
968 if (!is_on && !is_off) {
990 request, ESPHOME_F(
"effect"),
call,
1009 JsonObject root = builder.
root();
1011 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
1015 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
1018 opt.add(option->get_name());
1036 if (!entity_match.matched)
1039 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1040 auto detail = get_request_detail(request);
1041 auto data = this->cover_json_(obj, detail);
1042 request->send(200,
"application/json", data.c_str());
1049 static const struct {
1060 for (
const auto &method : METHODS) {
1062 (
call.*method.action)();
1074 if ((request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1075 (request->hasArg(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1083 DEFER_ACTION(
call,
call.perform());
1097 JsonObject root = builder.
root();
1101 char buf[PSTR_LOCAL_SIZE];
1105 root[ESPHOME_F(
"position")] = obj->
position;
1107 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1123 for (
auto *obj :
App.get_numbers()) {
1125 if (!entity_match.matched)
1128 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1129 auto detail = get_request_detail(request);
1130 auto data = this->number_json_(obj, obj->state, detail);
1131 request->send(200,
"application/json", data.c_str());
1142 DEFER_ACTION(
call,
call.perform());
1157 JsonObject root = builder.
root();
1163 char val_buf[VALUE_ACCURACY_MAX_LEN];
1164 char state_buf[VALUE_ACCURACY_MAX_LEN];
1165 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1166 const char *state_str =
1168 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1175 if (!uom_ref.empty())
1176 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
1184#ifdef USE_DATETIME_DATE
1191 for (
auto *obj :
App.get_dates()) {
1193 if (!entity_match.matched)
1195 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1196 auto detail = get_request_detail(request);
1197 auto data = this->date_json_(obj, detail);
1198 request->send(200,
"application/json", data.c_str());
1208 const auto &value = request->arg(ESPHOME_F(
"value"));
1210 if (value.length() == 0) {
1214 call.set_date(value.c_str(), value.length());
1216 DEFER_ACTION(
call,
call.perform());
1231 JsonObject root = builder.
root();
1235 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1236 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1245#ifdef USE_DATETIME_TIME
1252 for (
auto *obj :
App.get_times()) {
1254 if (!entity_match.matched)
1256 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1257 auto detail = get_request_detail(request);
1258 auto data = this->time_json_(obj, detail);
1259 request->send(200,
"application/json", data.c_str());
1269 const auto &value = request->arg(ESPHOME_F(
"value"));
1271 if (value.length() == 0) {
1275 call.set_time(value.c_str(), value.length());
1277 DEFER_ACTION(
call,
call.perform());
1291 JsonObject root = builder.
root();
1295 buf_append_printf(value,
sizeof(value), 0,
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1296 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1305#ifdef USE_DATETIME_DATETIME
1312 for (
auto *obj :
App.get_datetimes()) {
1314 if (!entity_match.matched)
1316 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1317 auto detail = get_request_detail(request);
1318 auto data = this->datetime_json_(obj, detail);
1319 request->send(200,
"application/json", data.c_str());
1329 const auto &value = request->arg(ESPHOME_F(
"value"));
1331 if (value.length() == 0) {
1335 call.set_datetime(value.c_str(), value.length());
1337 DEFER_ACTION(
call,
call.perform());
1351 JsonObject root = builder.
root();
1355 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour,
1357 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1373 for (
auto *obj :
App.get_texts()) {
1375 if (!entity_match.matched)
1378 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1379 auto detail = get_request_detail(request);
1380 auto data = this->text_json_(obj, obj->state, detail);
1381 request->send(200,
"application/json", data.c_str());
1391 request, ESPHOME_F(
"value"),
call,
1394 DEFER_ACTION(
call,
call.perform());
1409 JsonObject root = builder.
root();
1412 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1432 for (
auto *obj :
App.get_selects()) {
1434 if (!entity_match.matched)
1437 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1438 auto detail = get_request_detail(request);
1439 auto data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail);
1440 request->send(200,
"application/json", data.c_str());
1451 request, ESPHOME_F(
"option"),
call,
1454 DEFER_ACTION(
call,
call.perform());
1470 JsonObject root = builder.
root();
1473 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1475 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1493 for (
auto *obj :
App.get_climates()) {
1495 if (!entity_match.matched)
1498 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1499 auto detail = get_request_detail(request);
1500 auto data = this->climate_json_(obj, detail);
1501 request->send(200,
"application/json", data.c_str());
1514 request, ESPHOME_F(
"mode"),
call,
1518 &
decltype(
call)::set_fan_mode));
1521 &
decltype(
call)::set_swing_mode));
1524 &
decltype(
call)::set_preset));
1528 using ClimateCall =
decltype(
call);
1530 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_high));
1532 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_low));
1534 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature));
1536 DEFER_ACTION(
call,
call.perform());
1553 JsonObject root = builder.
root();
1554 set_json_id(root, obj,
"climate", start_config);
1557 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1558 char buf[PSTR_LOCAL_SIZE];
1559 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1562 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1565 if (traits.get_supports_fan_modes()) {
1566 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1571 if (!traits.get_supported_custom_fan_modes().empty()) {
1572 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1573 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1576 if (traits.get_supports_swing_modes()) {
1577 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1578 for (
auto swing_mode : traits.get_supported_swing_modes())
1581 if (traits.get_supports_presets()) {
1582 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1586 if (!traits.get_supported_custom_presets().empty()) {
1587 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1588 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1591 root[ESPHOME_F(
"max_temp")] =
1593 root[ESPHOME_F(
"min_temp")] =
1595 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1599 bool has_state =
false;
1603 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1606 if (traits.get_supports_fan_modes() && obj->
fan_mode.has_value()) {
1612 if (traits.get_supports_presets() && obj->
preset.has_value()) {
1615 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1618 if (traits.get_supports_swing_modes()) {
1622 root[ESPHOME_F(
"current_temperature")] =
1634 root[ESPHOME_F(
"target_temperature_low")] =
1636 root[ESPHOME_F(
"target_temperature_high")] =
1639 root[ESPHOME_F(
"state")] =
1645 root[ESPHOME_F(
"target_temperature")] =
1648 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1683 if (!entity_match.matched)
1686 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1687 auto detail = get_request_detail(request);
1688 auto data = this->lock_json_(obj, obj->
state, detail);
1689 request->send(200,
"application/json", data.c_str());
1704 this->
defer([obj, action]() { execute_lock_action(obj, action); });
1721 JsonObject root = builder.
root();
1723 char buf[PSTR_LOCAL_SIZE];
1742 if (!entity_match.matched)
1745 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1746 auto detail = get_request_detail(request);
1747 auto data = this->valve_json_(obj, detail);
1748 request->send(200,
"application/json", data.c_str());
1755 static const struct {
1766 for (
const auto &method : METHODS) {
1768 (
call.*method.action)();
1779 auto traits = obj->get_traits();
1780 if (request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1787 DEFER_ACTION(
call,
call.perform());
1801 JsonObject root = builder.
root();
1805 char buf[PSTR_LOCAL_SIZE];
1809 root[ESPHOME_F(
"position")] = obj->
position;
1818#ifdef USE_ALARM_CONTROL_PANEL
1827 if (!entity_match.matched)
1830 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1831 auto detail = get_request_detail(request);
1832 auto data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1833 request->send(200,
"application/json", data.c_str());
1839 request, ESPHOME_F(
"code"),
call,
1844 static const struct {
1856 for (
const auto &method : METHODS) {
1858 (
call.*method.action)();
1869 DEFER_ACTION(
call,
call.perform());
1889 JsonObject root = builder.
root();
1891 char buf[PSTR_LOCAL_SIZE];
1892 set_json_icon_state_value(root, obj,
"alarm-control-panel", PSTR_LOCAL(alarm_control_panel_state_to_string(value)),
1893 value, start_config);
1902#ifdef USE_WATER_HEATER
1911 if (!entity_match.matched)
1914 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1915 auto detail = get_request_detail(request);
1916 auto data = this->water_heater_json_(obj, detail);
1917 request->send(200,
"application/json", data.c_str());
1930 request, ESPHOME_F(
"mode"), base_call,
1948 DEFER_ACTION(
call,
call.perform());
1964 JsonObject root = builder.
root();
1965 char buf[PSTR_LOCAL_SIZE];
1970 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1975 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1976 for (
auto m : traits.get_supported_modes())
1978 root[ESPHOME_F(
"min_temp")] = traits.get_min_temperature();
1979 root[ESPHOME_F(
"max_temp")] = traits.get_max_temperature();
1980 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
1984 if (traits.get_supports_current_temperature()) {
1986 if (!std::isnan(current))
1987 root[ESPHOME_F(
"current_temperature")] = current;
1990 if (traits.get_supports_two_point_target_temperature()) {
1993 if (!std::isnan(low))
1994 root[ESPHOME_F(
"target_temperature_low")] = low;
1995 if (!std::isnan(high))
1996 root[ESPHOME_F(
"target_temperature_high")] = high;
1999 if (!std::isnan(target))
2000 root[ESPHOME_F(
"target_temperature")] = target;
2003 if (traits.get_supports_away_mode()) {
2004 root[ESPHOME_F(
"away")] = obj->
is_away();
2008 root[ESPHOME_F(
"is_on")] = obj->
is_on();
2019 if (!entity_match.matched)
2022 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2023 auto detail = get_request_detail(request);
2024 auto data = this->infrared_json_(obj, detail);
2025 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
2034 if (!obj->has_transmitter()) {
2035 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2045 if (value.has_value()) {
2046 call.set_carrier_frequency(*value);
2053 if (value.has_value()) {
2054 call.set_repeat_count(*value);
2060 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2064 if (data_arg.length() == 0) {
2065 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2073 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2074 call.set_raw_timings_base64url(encoded);
2091 JsonObject root = builder.
root();
2093 set_json_icon_state_value(root, obj,
"infrared",
"", 0, start_config);
2098 root[ESPHOME_F(
"supports_receiver")] = traits.get_supports_receiver();
2108#ifdef USE_RADIO_FREQUENCY
2112 if (!entity_match.matched)
2115 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2116 auto detail = get_request_detail(request);
2117 auto data = this->radio_frequency_json_(obj, detail);
2118 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
2128 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2137 if (value.has_value()) {
2138 call.set_frequency(*value);
2145 if (value.has_value()) {
2146 call.set_repeat_count(*value);
2152 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2156 if (data_arg.length() == 0) {
2157 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2165 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2166 call.set_raw_timings_base64url(encoded);
2184 JsonObject root = builder.
root();
2186 set_json_icon_state_value(root, obj,
"radio_frequency",
"", 0, start_config);
2193 if (traits.get_frequency_min_hz() != 0) {
2194 root[ESPHOME_F(
"frequency_min")] = traits.get_frequency_min_hz();
2195 root[ESPHOME_F(
"frequency_max")] = traits.get_frequency_max_hz();
2216 if (!entity_match.matched)
2220 if (entity_match.action_is_empty) {
2221 auto detail = get_request_detail(request);
2222 auto data = this->event_json_(obj,
StringRef(), detail);
2223 request->send(200,
"application/json", data.c_str());
2234 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
2239 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
2243 JsonObject root = builder.
root();
2245 set_json_id(root, obj,
"event", start_config);
2246 if (!event_type.
empty()) {
2247 root[ESPHOME_F(
"event_type")] = event_type;
2250 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2252 event_types.add(event_type);
2254 char dc_buf[MAX_DEVICE_CLASS_LENGTH];
2271 if (!entity_match.matched)
2274 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2275 auto detail = get_request_detail(request);
2276 auto data = this->update_json_(obj, detail);
2277 request->send(200,
"application/json", data.c_str());
2286 DEFER_ACTION(obj, obj->perform());
2303 JsonObject root = builder.
root();
2305 char buf[PSTR_LOCAL_SIZE];
2312 constexpr size_t max_summary_len = 256;
2327 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2328 StringRef url = request->url_to(url_buf);
2330 const auto &url = request->url();
2332 const auto method = request->method();
2335 if (url == ESPHOME_F(
"/"))
2337#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2338 if (url == ESPHOME_F(
"/events"))
2341#ifdef USE_WEBSERVER_CSS_INCLUDE
2342 if (url == ESPHOME_F(
"/0.css"))
2345#ifdef USE_WEBSERVER_JS_INCLUDE
2346 if (url == ESPHOME_F(
"/0.js"))
2350#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2351 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2361 bool is_get = method == HTTP_GET;
2362 bool is_post = method == HTTP_POST;
2363 bool is_get_or_post = is_get || is_post;
2365 if (!is_get_or_post)
2374#ifdef USE_BINARY_SENSOR
2378#ifdef USE_TEXT_SENSOR
2389 if (is_get_or_post) {
2414#ifdef USE_DATETIME_DATE
2418#ifdef USE_DATETIME_TIME
2422#ifdef USE_DATETIME_DATETIME
2446#ifdef USE_ALARM_CONTROL_PANEL
2454#ifdef USE_WATER_HEATER
2462#ifdef USE_RADIO_FREQUENCY
2472 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2473 StringRef url = request->url_to(url_buf);
2475 const auto &url = request->url();
2479 if (url == ESPHOME_F(
"/")) {
2484#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2485 if (url == ESPHOME_F(
"/events")) {
2486 this->
events_.add_new_client(
this, request);
2491#ifdef USE_WEBSERVER_CSS_INCLUDE
2492 if (url == ESPHOME_F(
"/0.css")) {
2498#ifdef USE_WEBSERVER_JS_INCLUDE
2499 if (url == ESPHOME_F(
"/0.js")) {
2505#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2506 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2514 UrlMatch match = match_url(url.
c_str(), url.
length(),
false, request->method() == HTTP_POST);
2535#ifdef USE_BINARY_SENSOR
2550#ifdef USE_TEXT_SENSOR
2565#ifdef USE_DATETIME_DATE
2570#ifdef USE_DATETIME_TIME
2575#ifdef USE_DATETIME_DATETIME
2605#ifdef USE_ALARM_CONTROL_PANEL
2606 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2615#ifdef USE_WATER_HEATER
2625#ifdef USE_RADIO_FREQUENCY
2626 else if (match.
domain_equals(ESPHOME_F(
"radio_frequency"))) {
2632 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.
c_str());
2633 request->send(404, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Not Found"));
2640#ifdef USE_WEBSERVER_SORTING
2643 if (this->
sorting_groups_.find(this->sorting_entitys_[entity].group_id) != this->sorting_groups_.end()) {
2650#ifdef USE_WEBSERVER_SORTING
BedjetMode mode
BedJet operating mode.
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
const StringRef & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
static constexpr size_t ESPHOME_COMMENT_SIZE_MAX
Maximum size of the comment buffer (including null terminator)
void get_comment_string(std::span< char, ESPHOME_COMMENT_SIZE_MAX > buffer)
Copy the comment string into the provided buffer.
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 enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void disable_loop()
Disable this component's loop.
void begin(bool include_internal=false)
static void register_controller(Controller *controller)
Register a controller to receive entity state updates.
const char * get_device_class_to(std::span< char, MAX_DEVICE_CLASS_LENGTH > buffer) const
const StringRef & get_name() const
ESPDEPRECATED("Use get_unit_of_measurement_ref() instead for better performance (avoids string copy). Will be " "removed in ESPHome 2026.9.0", "2026.3.0") std const char * get_icon_to(std::span< char, MAX_ICON_LENGTH > buffer) const
Get the unit of measurement as std::string (deprecated, prefer get_unit_of_measurement_ref())
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
ESPDEPRECATED("Use get_device_class_to() instead. Will be removed in ESPHome 2026.9.0", "2026.3.0") std StringRef get_unit_of_measurement_ref() 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 size_type length() 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.
This class is used to encode all control actions on a climate device.
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.
float current_humidity
The current humidity of the climate device, as reported from the integration.
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.
Infrared - Base class for infrared remote control implementations.
InfraredCall make_call()
Create a call object for transmitting.
InfraredTraits & get_traits()
Get the traits for this infrared implementation.
uint32_t get_capability_flags() const
Get capability flags for this infrared instance.
bool get_supports_transmitter() const
Builder class for creating JSON documents without lambdas.
SerializationBuffer serialize()
Serialize the JSON document to a SerializationBuffer (stack-first allocation) Uses 512-byte stack buf...
Buffer for JSON serialization that uses stack allocation for small payloads.
This class represents a requested change in a light state.
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 lock()
Turn this lock on.
LockState state
The current reported state of the lock.
void unlock()
Turn this lock off.
void open()
Open (unlatch) this lock.
void add_log_callback(void *instance, void(*fn)(void *, uint8_t, const char *, const char *, size_t))
Register a log callback to receive log messages.
Base-class for all numbers.
float get_min_value() const
float get_max_value() const
NumberMode get_mode() const
RadioFrequency - Base class for radio frequency implementations.
uint32_t get_capability_flags() const
Get capability flags for this radio frequency instance.
RadioFrequencyTraits & get_traits()
Get the traits for this radio frequency implementation.
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.
void toggle()
Toggle this switch.
void turn_on()
Turn this switch on.
void turn_off()
Turn this switch off.
bool state
The current reported state of the binary sensor.
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.
virtual WaterHeaterCallInternal make_call()=0
WaterHeaterMode get_mode() const
virtual WaterHeaterTraits get_traits()
float get_target_temperature_high() 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)
bool loop()
Returns true if there are event sources remaining (including pending cleanup).
This class allows users to create a web server with their ESP nodes.
void setup() override
Setup the internal web server and register handlers.
void on_update(update::UpdateEntity *obj) override
static json::SerializationBuffer radio_frequency_all_json_generator(WebServer *web_server, void *source)
void on_water_heater_update(water_heater::WaterHeater *obj) override
json::SerializationBuffer get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static json::SerializationBuffer text_state_json_generator(WebServer *web_server, void *source)
void on_text_update(text::Text *obj) override
void on_light_update(light::LightState *obj) override
static json::SerializationBuffer datetime_state_json_generator(WebServer *web_server, void *source)
void on_cover_update(cover::Cover *obj) override
static json::SerializationBuffer lock_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer alarm_control_panel_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer text_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer switch_all_json_generator(WebServer *web_server, void *source)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)
static json::SerializationBuffer event_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer update_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer text_sensor_all_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>'.
bool isRequestHandlerTrivial() const override
This web handle is not trivial.
static json::SerializationBuffer cover_all_json_generator(WebServer *web_server, void *source)
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 parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
void dump_config() override
static json::SerializationBuffer datetime_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer light_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer climate_state_json_generator(WebServer *web_server, void *source)
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
static json::SerializationBuffer date_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer sensor_state_json_generator(WebServer *web_server, void *source)
void on_number_update(number::Number *obj) override
void add_entity_config(EntityBase *entity, float weight, uint64_t group)
void handle_radio_frequency_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a radio frequency request under '/radio_frequency/<id>/transmit'.
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 json::SerializationBuffer select_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer infrared_all_json_generator(WebServer *web_server, void *source)
void on_valve_update(valve::Valve *obj) override
void on_climate_update(climate::Climate *obj) override
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 json::SerializationBuffer sensor_all_json_generator(WebServer *web_server, void *source)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
static json::SerializationBuffer number_all_json_generator(WebServer *web_server, void *source)
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
static json::SerializationBuffer select_state_json_generator(WebServer *web_server, void *source)
void on_switch_update(switch_::Switch *obj) override
static json::SerializationBuffer water_heater_state_json_generator(WebServer *web_server, void *source)
web_server_base::WebServerBase * base_
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 json::SerializationBuffer time_state_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>'.
void handle_infrared_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle an infrared request under '/infrared/<id>/transmit'.
void handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a sensor request under '/sensor/<id>'.
void handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a number request under '/number/<id>'.
void handle_index_request(AsyncWebServerRequest *request)
Handle an index request under '/'.
void handle_js_request(AsyncWebServerRequest *request)
Handle included js request under '/0.js'.
static json::SerializationBuffer valve_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer fan_all_json_generator(WebServer *web_server, void *source)
void set_js_include(const char *js_include)
Set local path to the script that's embedded in the index page.
static json::SerializationBuffer lock_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer update_state_json_generator(WebServer *web_server, void *source)
void handleRequest(AsyncWebServerRequest *request) override
Override the web handler's handleRequest method.
static json::SerializationBuffer button_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 json::SerializationBuffer alarm_control_panel_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer time_all_json_generator(WebServer *web_server, void *source)
void parse_cstr_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(const char *, size_t))
static json::SerializationBuffer water_heater_all_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>'.
static json::SerializationBuffer date_state_json_generator(WebServer *web_server, void *source)
void handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a binary sensor request under '/binary_sensor/<id>'.
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.
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
static json::SerializationBuffer climate_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer fan_state_json_generator(WebServer *web_server, void *source)
void on_event(event::Event *obj) override
static json::SerializationBuffer cover_state_json_generator(WebServer *web_server, void *source)
void handle_pna_cors_request(AsyncWebServerRequest *request)
static json::SerializationBuffer binary_sensor_state_json_generator(WebServer *web_server, void *source)
void on_fan_update(fan::Fan *obj) override
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
static json::SerializationBuffer event_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer binary_sensor_all_json_generator(WebServer *web_server, void *source)
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
void on_lock_update(lock::Lock *obj) override
static json::SerializationBuffer switch_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
void parse_num_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(NumT))
static json::SerializationBuffer text_sensor_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer number_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer valve_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 json::SerializationBuffer light_all_json_generator(WebServer *web_server, void *source)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
const char * css_include_
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
struct @65::@66 __attribute__
Wake the main loop task from an ISR. ISR-safe.
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
@ CLIMATE_SUPPORTS_CURRENT_HUMIDITY
@ 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.
ESPHOME_ALWAYS_INLINE const char * get_use_address()
Get the active network hostname.
const LogString * update_state_to_string(UpdateState state)
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.
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.
optional< T > parse_number(const char *str)
Parse an unsigned decimal number from a null-terminated string.
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".
const size_t ESPHOME_WEBSERVER_INDEX_HTML_SIZE
const size_t ESPHOME_WEBSERVER_CSS_INCLUDE_SIZE
const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE