14#if !defined(USE_ESP32) && defined(USE_ARDUINO)
15#include "StreamString.h"
36#ifdef USE_WATER_HEATER
44#ifdef USE_WEBSERVER_LOCAL
45#if USE_WEBSERVER_VERSION == 2
47#elif USE_WEBSERVER_VERSION == 3
54static const char *
const TAG =
"web_server";
57static constexpr size_t PSTR_LOCAL_SIZE = 18;
58#define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1)
66static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain,
bool is_post =
false) {
68 if (url_len < 2 || url_ptr[0] !=
'/')
71 const char *p = url_ptr + 1;
72 const char *
end = url_ptr + url_len;
75 auto next_segment = [&
end](
const char *start) ->
const char * {
76 const char *slash = (
const char *) memchr(start,
'/',
end - start);
77 return slash ? slash + 1 :
nullptr;
81 auto make_ref = [&
end](
const char *start,
const char *next_start) -> StringRef {
82 return StringRef(start, (next_start ? next_start - 1 :
end) - start);
87 const char *s2 = next_segment(s1);
94 match.domain = make_ref(s1, s2);
97 if (only_domain || s2 >=
end)
101 const char *s3 = next_segment(s2);
102 const char *s4 = s3 ? next_segment(s3) : nullptr;
104 StringRef seg2 = make_ref(s2, s3);
105 StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef();
106 StringRef seg4 = s4 ? make_ref(s4,
nullptr) : StringRef();
109 if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty()))
125 match.device_name = seg2;
136 match.device_name = seg2;
153 bool entity_has_device = (entity_device !=
nullptr);
156 if (url_has_device != entity_has_device) {
165 if (this->
id == entity->
get_name()) {
166 result.matched =
true;
171 char object_id_buf[OBJECT_ID_MAX_LEN];
173 if (this->
id == object_id) {
174 result.matched =
true;
178 if (device !=
nullptr) {
180 "Deprecated URL format: /%.*s/%.*s/%.*s - use entity name '/%.*s/%s/%s' instead. "
181 "Object ID URLs will be removed in 2026.7.0.",
182 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->device_name.size(),
183 this->device_name.c_str(), (
int) this->id.size(), this->id.c_str(), (
int) this->domain.size(),
189 "Deprecated URL format: /%.*s/%.*s - use entity name '/%.*s/%s' instead. "
190 "Object ID URLs will be removed in 2026.7.0.",
191 (
int) this->
domain.
size(), this->domain.c_str(), (
int) this->id.size(), this->id.c_str(),
192 (
int) this->domain.size(), this->domain.c_str(), entity->
get_name().
c_str());
199#if !defined(USE_ESP32) && defined(USE_ARDUINO)
203 DeferredEvent item(
source, message_generator);
211 this->deferred_queue_.push_back(item);
218 if (this->send(
message.c_str(),
"state") != DISCARDED) {
230 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
249 if (this->count() == 0)
259 if (event_type ==
nullptr)
261 if (message_generator ==
nullptr)
264 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
265 ESP_LOGE(TAG,
"Can't defer non-state event");
275 if (this->send(
message.c_str(),
"state") == DISCARDED) {
286 this->send(
message, event,
id, reconnect);
316 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
320 es->handleRequest(request);
331#ifdef USE_WEBSERVER_SORTING
334 JsonObject root = builder.
root();
335 root[ESPHOME_F(
"name")] = group.second.name;
336 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
340 source->try_send_nodefer(group_msg.c_str(),
"sorting_group");
366#ifdef USE_WEBSERVER_CSS_INCLUDE
369#ifdef USE_WEBSERVER_JS_INCLUDE
375 JsonObject root = builder.
root();
380 root[ESPHOME_F(
"comment")] = comment_buffer;
381#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
382 root[ESPHOME_F(
"ota")] =
false;
384 root[ESPHOME_F(
"ota")] =
true;
387 root[ESPHOME_F(
"lang")] =
"en";
400 this, [](
void *self, uint8_t level,
const char *
tag,
const char *
message,
size_t message_len) {
418 buf_append_printf(buf,
sizeof(buf), 0,
"{\"uptime\":%u}", uptime);
419 this->
events_.try_send_nodefer(buf,
"ping",
millis(), 30000);
441#ifdef USE_WEBSERVER_LOCAL
444 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
446 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
448#ifdef USE_WEBSERVER_GZIP
449 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
451 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
453 request->send(response);
455#elif USE_WEBSERVER_VERSION >= 2
458 AsyncWebServerResponse *response =
461 AsyncWebServerResponse *response =
465 request->send(response);
469#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
471 AsyncWebServerResponse *response = request->beginResponse(200, ESPHOME_F(
""));
472 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
473 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().
c_str());
476 request->send(response);
480#ifdef USE_WEBSERVER_CSS_INCLUDE
483 AsyncWebServerResponse *response =
486 AsyncWebServerResponse *response =
489 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
490 request->send(response);
494#ifdef USE_WEBSERVER_JS_INCLUDE
497 AsyncWebServerResponse *response =
500 AsyncWebServerResponse *response =
503 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
504 request->send(response);
511static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
513 size_t prefix_len = strlen(prefix);
514 size_t name_len = name.
size();
518 const char *device_name = device ? device->
get_name() :
nullptr;
519 size_t device_len = device_name ? strlen(device_name) : 0;
528 static constexpr size_t LEGACY_ID_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + OBJECT_ID_MAX_LEN;
530 static constexpr size_t ID_BUF_SIZE =
531 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1,
534 static constexpr size_t ID_BUF_SIZE =
535 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1, LEGACY_ID_SIZE);
537 char id_buf[ID_BUF_SIZE];
538 memcpy(id_buf, prefix, prefix_len);
542 char *p = id_buf + prefix_len;
546 memcpy(p, device_name, device_len);
551 memcpy(p, name.
c_str(), name_len);
553 root[ESPHOME_F(
"name_id")] = id_buf;
557 id_buf[prefix_len] =
'-';
559 root[ESPHOME_F(
"id")] = id_buf;
562 root[ESPHOME_F(
"domain")] = prefix;
564 root[ESPHOME_F(
"name")] = name.
c_str();
567 root[ESPHOME_F(
"device")] = device_name;
570#ifdef USE_ENTITY_ICON
571 char icon_buf[MAX_ICON_LENGTH];
572 root[ESPHOME_F(
"icon")] = obj->
get_icon_to(icon_buf);
577 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
584static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
586 set_json_id(root, obj, prefix, start_config);
587 root[ESPHOME_F(
"value")] = value;
591static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const char *
state,
593 set_json_value(root, obj, prefix, value, start_config);
594 root[ESPHOME_F(
"state")] =
state;
598static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
611 if (!entity_match.matched)
614 if (entity_match.action_is_empty) {
615 auto detail = get_request_detail(request);
616 auto data = this->sensor_json_(obj, obj->state, detail);
617 request->send(200,
"application/json", data.c_str());
631 JsonObject root = builder.
root();
634 char buf[VALUE_ACCURACY_MAX_LEN];
635 const char *
state = std::isnan(value)
638 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
641 if (!uom_ref.empty())
642 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
649#ifdef USE_TEXT_SENSOR
658 if (!entity_match.matched)
661 if (entity_match.action_is_empty) {
662 auto detail = get_request_detail(request);
663 auto data = this->text_sensor_json_(obj, obj->
state, detail);
664 request->send(200,
"application/json", data.c_str());
681 JsonObject root = builder.
root();
683 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
719 if (!entity_match.matched)
722 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
723 auto detail = get_request_detail(request);
724 auto data = this->switch_json_(obj, obj->
state, detail);
725 request->send(200,
"application/json", data.c_str());
740 this->
defer([obj, action]() { execute_switch_action(obj, action); });
757 JsonObject root = builder.
root();
759 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
773 if (!entity_match.matched)
775 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
776 auto detail = get_request_detail(request);
777 auto data = this->button_json_(obj, detail);
778 request->send(200,
"application/json", data.c_str());
780 DEFER_ACTION(obj, obj->press());
795 JsonObject root = builder.
root();
797 set_json_id(root, obj,
"button", start_config);
806#ifdef USE_BINARY_SENSOR
815 if (!entity_match.matched)
818 if (entity_match.action_is_empty) {
819 auto detail = get_request_detail(request);
820 auto data = this->binary_sensor_json_(obj, obj->state, detail);
821 request->send(200,
"application/json", data.c_str());
838 JsonObject root = builder.
root();
840 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
858 if (!entity_match.matched)
861 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
862 auto detail = get_request_detail(request);
863 auto data = this->fan_json_(obj, detail);
864 request->send(200,
"application/json", data.c_str());
866 DEFER_ACTION(obj, obj->toggle().perform());
871 if (!is_on && !is_off) {
875 auto call = is_on ? obj->turn_on() : obj->turn_off();
879 if (request->hasArg(ESPHOME_F(
"oscillation"))) {
880 auto speed = request->arg(ESPHOME_F(
"oscillation"));
884 call.set_oscillating(
true);
887 call.set_oscillating(
false);
890 call.set_oscillating(!obj->oscillating);
912 JsonObject root = builder.
root();
914 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
916 if (traits.supports_speed()) {
917 root[ESPHOME_F(
"speed_level")] = obj->
speed;
918 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
939 if (!entity_match.matched)
942 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
943 auto detail = get_request_detail(request);
944 auto data = this->light_json_(obj, detail);
945 request->send(200,
"application/json", data.c_str());
952 if (!is_on && !is_off) {
974 request, ESPHOME_F(
"effect"),
call,
993 JsonObject root = builder.
root();
995 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
999 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
1002 opt.add(option->get_name());
1020 if (!entity_match.matched)
1023 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1024 auto detail = get_request_detail(request);
1025 auto data = this->cover_json_(obj, detail);
1026 request->send(200,
"application/json", data.c_str());
1033 static const struct {
1044 for (
const auto &method : METHODS) {
1046 (
call.*method.action)();
1058 if ((request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1059 (request->hasArg(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1067 DEFER_ACTION(
call,
call.perform());
1081 JsonObject root = builder.
root();
1085 char buf[PSTR_LOCAL_SIZE];
1089 root[ESPHOME_F(
"position")] = obj->
position;
1091 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1107 for (
auto *obj :
App.get_numbers()) {
1109 if (!entity_match.matched)
1112 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1113 auto detail = get_request_detail(request);
1114 auto data = this->number_json_(obj, obj->state, detail);
1115 request->send(200,
"application/json", data.c_str());
1126 DEFER_ACTION(
call,
call.perform());
1141 JsonObject root = builder.
root();
1147 char val_buf[VALUE_ACCURACY_MAX_LEN];
1148 char state_buf[VALUE_ACCURACY_MAX_LEN];
1149 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1150 const char *state_str =
1152 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1159 if (!uom_ref.empty())
1160 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
1168#ifdef USE_DATETIME_DATE
1175 for (
auto *obj :
App.get_dates()) {
1177 if (!entity_match.matched)
1179 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1180 auto detail = get_request_detail(request);
1181 auto data = this->date_json_(obj, detail);
1182 request->send(200,
"application/json", data.c_str());
1192 const auto &value = request->arg(ESPHOME_F(
"value"));
1194 if (value.length() == 0) {
1198 call.set_date(value.c_str(), value.length());
1200 DEFER_ACTION(
call,
call.perform());
1215 JsonObject root = builder.
root();
1219 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1220 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1229#ifdef USE_DATETIME_TIME
1236 for (
auto *obj :
App.get_times()) {
1238 if (!entity_match.matched)
1240 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1241 auto detail = get_request_detail(request);
1242 auto data = this->time_json_(obj, detail);
1243 request->send(200,
"application/json", data.c_str());
1253 const auto &value = request->arg(ESPHOME_F(
"value"));
1255 if (value.length() == 0) {
1259 call.set_time(value.c_str(), value.length());
1261 DEFER_ACTION(
call,
call.perform());
1275 JsonObject root = builder.
root();
1279 buf_append_printf(value,
sizeof(value), 0,
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1280 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1289#ifdef USE_DATETIME_DATETIME
1296 for (
auto *obj :
App.get_datetimes()) {
1298 if (!entity_match.matched)
1300 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1301 auto detail = get_request_detail(request);
1302 auto data = this->datetime_json_(obj, detail);
1303 request->send(200,
"application/json", data.c_str());
1313 const auto &value = request->arg(ESPHOME_F(
"value"));
1315 if (value.length() == 0) {
1319 call.set_datetime(value.c_str(), value.length());
1321 DEFER_ACTION(
call,
call.perform());
1335 JsonObject root = builder.
root();
1339 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour,
1341 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1357 for (
auto *obj :
App.get_texts()) {
1359 if (!entity_match.matched)
1362 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1363 auto detail = get_request_detail(request);
1364 auto data = this->text_json_(obj, obj->state, detail);
1365 request->send(200,
"application/json", data.c_str());
1375 request, ESPHOME_F(
"value"),
call,
1378 DEFER_ACTION(
call,
call.perform());
1393 JsonObject root = builder.
root();
1396 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1416 for (
auto *obj :
App.get_selects()) {
1418 if (!entity_match.matched)
1421 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1422 auto detail = get_request_detail(request);
1423 auto data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail);
1424 request->send(200,
"application/json", data.c_str());
1435 request, ESPHOME_F(
"option"),
call,
1438 DEFER_ACTION(
call,
call.perform());
1454 JsonObject root = builder.
root();
1457 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1459 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1477 for (
auto *obj :
App.get_climates()) {
1479 if (!entity_match.matched)
1482 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1483 auto detail = get_request_detail(request);
1484 auto data = this->climate_json_(obj, detail);
1485 request->send(200,
"application/json", data.c_str());
1498 request, ESPHOME_F(
"mode"),
call,
1502 &
decltype(
call)::set_fan_mode));
1505 &
decltype(
call)::set_swing_mode));
1508 &
decltype(
call)::set_preset));
1512 using ClimateCall =
decltype(
call);
1514 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_high));
1516 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_low));
1518 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature));
1520 DEFER_ACTION(
call,
call.perform());
1537 JsonObject root = builder.
root();
1538 set_json_id(root, obj,
"climate", start_config);
1541 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1542 char buf[PSTR_LOCAL_SIZE];
1543 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1546 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1549 if (traits.get_supports_fan_modes()) {
1550 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1555 if (!traits.get_supported_custom_fan_modes().empty()) {
1556 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1557 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1560 if (traits.get_supports_swing_modes()) {
1561 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1562 for (
auto swing_mode : traits.get_supported_swing_modes())
1565 if (traits.get_supports_presets()) {
1566 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1570 if (!traits.get_supported_custom_presets().empty()) {
1571 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1572 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1575 root[ESPHOME_F(
"max_temp")] =
1577 root[ESPHOME_F(
"min_temp")] =
1579 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1583 bool has_state =
false;
1587 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1590 if (traits.get_supports_fan_modes() && obj->
fan_mode.has_value()) {
1596 if (traits.get_supports_presets() && obj->
preset.has_value()) {
1599 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1602 if (traits.get_supports_swing_modes()) {
1606 root[ESPHOME_F(
"current_temperature")] =
1618 root[ESPHOME_F(
"target_temperature_low")] =
1620 root[ESPHOME_F(
"target_temperature_high")] =
1623 root[ESPHOME_F(
"state")] =
1629 root[ESPHOME_F(
"target_temperature")] =
1632 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1667 if (!entity_match.matched)
1670 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1671 auto detail = get_request_detail(request);
1672 auto data = this->lock_json_(obj, obj->
state, detail);
1673 request->send(200,
"application/json", data.c_str());
1688 this->
defer([obj, action]() { execute_lock_action(obj, action); });
1705 JsonObject root = builder.
root();
1707 char buf[PSTR_LOCAL_SIZE];
1726 if (!entity_match.matched)
1729 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1730 auto detail = get_request_detail(request);
1731 auto data = this->valve_json_(obj, detail);
1732 request->send(200,
"application/json", data.c_str());
1739 static const struct {
1750 for (
const auto &method : METHODS) {
1752 (
call.*method.action)();
1763 auto traits = obj->get_traits();
1764 if (request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1771 DEFER_ACTION(
call,
call.perform());
1785 JsonObject root = builder.
root();
1789 char buf[PSTR_LOCAL_SIZE];
1793 root[ESPHOME_F(
"position")] = obj->
position;
1802#ifdef USE_ALARM_CONTROL_PANEL
1811 if (!entity_match.matched)
1814 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1815 auto detail = get_request_detail(request);
1816 auto data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1817 request->send(200,
"application/json", data.c_str());
1823 request, ESPHOME_F(
"code"),
call,
1828 static const struct {
1840 for (
const auto &method : METHODS) {
1842 (
call.*method.action)();
1853 DEFER_ACTION(
call,
call.perform());
1873 JsonObject root = builder.
root();
1875 char buf[PSTR_LOCAL_SIZE];
1876 set_json_icon_state_value(root, obj,
"alarm-control-panel", PSTR_LOCAL(alarm_control_panel_state_to_string(value)),
1877 value, start_config);
1886#ifdef USE_WATER_HEATER
1895 if (!entity_match.matched)
1898 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1899 auto detail = get_request_detail(request);
1900 auto data = this->water_heater_json_(obj, detail);
1901 request->send(200,
"application/json", data.c_str());
1914 request, ESPHOME_F(
"mode"), base_call,
1932 DEFER_ACTION(
call,
call.perform());
1948 JsonObject root = builder.
root();
1949 char buf[PSTR_LOCAL_SIZE];
1954 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1959 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1960 for (
auto m : traits.get_supported_modes())
1962 root[ESPHOME_F(
"min_temp")] = traits.get_min_temperature();
1963 root[ESPHOME_F(
"max_temp")] = traits.get_max_temperature();
1964 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
1968 if (traits.get_supports_current_temperature()) {
1970 if (!std::isnan(current))
1971 root[ESPHOME_F(
"current_temperature")] = current;
1974 if (traits.get_supports_two_point_target_temperature()) {
1977 if (!std::isnan(low))
1978 root[ESPHOME_F(
"target_temperature_low")] = low;
1979 if (!std::isnan(high))
1980 root[ESPHOME_F(
"target_temperature_high")] = high;
1983 if (!std::isnan(target))
1984 root[ESPHOME_F(
"target_temperature")] = target;
1987 if (traits.get_supports_away_mode()) {
1988 root[ESPHOME_F(
"away")] = obj->
is_away();
1992 root[ESPHOME_F(
"is_on")] = obj->
is_on();
2003 if (!entity_match.matched)
2006 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2007 auto detail = get_request_detail(request);
2008 auto data = this->infrared_json_(obj, detail);
2009 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
2018 if (!obj->has_transmitter()) {
2019 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2029 if (value.has_value()) {
2030 call.set_carrier_frequency(*value);
2037 if (value.has_value()) {
2038 call.set_repeat_count(*value);
2044 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2048 if (data_arg.length() == 0) {
2049 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2057 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2058 call.set_raw_timings_base64url(encoded);
2075 JsonObject root = builder.
root();
2077 set_json_icon_state_value(root, obj,
"infrared",
"", 0, start_config);
2082 root[ESPHOME_F(
"supports_receiver")] = traits.get_supports_receiver();
2102 if (!entity_match.matched)
2106 if (entity_match.action_is_empty) {
2107 auto detail = get_request_detail(request);
2108 auto data = this->event_json_(obj,
StringRef(), detail);
2109 request->send(200,
"application/json", data.c_str());
2120 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
2125 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
2129 JsonObject root = builder.
root();
2131 set_json_id(root, obj,
"event", start_config);
2132 if (!event_type.
empty()) {
2133 root[ESPHOME_F(
"event_type")] = event_type;
2136 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2138 event_types.add(event_type);
2140 char dc_buf[MAX_DEVICE_CLASS_LENGTH];
2157 if (!entity_match.matched)
2160 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2161 auto detail = get_request_detail(request);
2162 auto data = this->update_json_(obj, detail);
2163 request->send(200,
"application/json", data.c_str());
2172 DEFER_ACTION(obj, obj->perform());
2189 JsonObject root = builder.
root();
2191 char buf[PSTR_LOCAL_SIZE];
2209 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2210 StringRef url = request->url_to(url_buf);
2212 const auto &url = request->url();
2214 const auto method = request->method();
2217 if (url == ESPHOME_F(
"/"))
2219#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2220 if (url == ESPHOME_F(
"/events"))
2223#ifdef USE_WEBSERVER_CSS_INCLUDE
2224 if (url == ESPHOME_F(
"/0.css"))
2227#ifdef USE_WEBSERVER_JS_INCLUDE
2228 if (url == ESPHOME_F(
"/0.js"))
2232#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2233 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2243 bool is_get = method == HTTP_GET;
2244 bool is_post = method == HTTP_POST;
2245 bool is_get_or_post = is_get || is_post;
2247 if (!is_get_or_post)
2256#ifdef USE_BINARY_SENSOR
2260#ifdef USE_TEXT_SENSOR
2271 if (is_get_or_post) {
2296#ifdef USE_DATETIME_DATE
2300#ifdef USE_DATETIME_TIME
2304#ifdef USE_DATETIME_DATETIME
2328#ifdef USE_ALARM_CONTROL_PANEL
2336#ifdef USE_WATER_HEATER
2350 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2351 StringRef url = request->url_to(url_buf);
2353 const auto &url = request->url();
2357 if (url == ESPHOME_F(
"/")) {
2362#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2363 if (url == ESPHOME_F(
"/events")) {
2364 this->
events_.add_new_client(
this, request);
2369#ifdef USE_WEBSERVER_CSS_INCLUDE
2370 if (url == ESPHOME_F(
"/0.css")) {
2376#ifdef USE_WEBSERVER_JS_INCLUDE
2377 if (url == ESPHOME_F(
"/0.js")) {
2383#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2384 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2392 UrlMatch match = match_url(url.
c_str(), url.
length(),
false, request->method() == HTTP_POST);
2413#ifdef USE_BINARY_SENSOR
2428#ifdef USE_TEXT_SENSOR
2443#ifdef USE_DATETIME_DATE
2448#ifdef USE_DATETIME_TIME
2453#ifdef USE_DATETIME_DATETIME
2483#ifdef USE_ALARM_CONTROL_PANEL
2484 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2493#ifdef USE_WATER_HEATER
2505 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.
c_str());
2506 request->send(404, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Not Found"));
2513#ifdef USE_WEBSERVER_SORTING
2516 if (this->
sorting_groups_.find(this->sorting_entitys_[entity].group_id) != this->sorting_groups_.end()) {
2523#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.
auto & get_binary_sensors() const
auto & get_events() 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.
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.
InfraredTraits & get_traits()
Get the traits for this infrared implementation.
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
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)
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
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 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
struct @65::@66 __attribute__
ClimateSwingMode swing_mode
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.
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