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)
202 DeferredEvent item(source, message_generator);
210 this->deferred_queue_.push_back(item);
217 if (this->send(
message.c_str(),
"state") != DISCARDED) {
229 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
248 if (this->count() == 0)
256 if (source ==
nullptr)
258 if (event_type ==
nullptr)
260 if (message_generator ==
nullptr)
263 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
264 ESP_LOGE(TAG,
"Can't defer non-state event");
274 if (this->send(
message.c_str(),
"state") == DISCARDED) {
284 uint32_t reconnect) {
285 this->send(
message, event,
id, reconnect);
305 uint32_t reconnect) {
315 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
319 es->handleRequest(request);
324 ws->
defer([ws, source]() {
330#ifdef USE_WEBSERVER_SORTING
333 JsonObject root = builder.
root();
334 root[ESPHOME_F(
"name")] = group.second.name;
335 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
357 this->remove(source);
365#ifdef USE_WEBSERVER_CSS_INCLUDE
368#ifdef USE_WEBSERVER_JS_INCLUDE
374 JsonObject root = builder.
root();
377 char comment_buffer[ESPHOME_COMMENT_SIZE];
379 root[ESPHOME_F(
"comment")] = comment_buffer;
380#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
381 root[ESPHOME_F(
"ota")] =
false;
383 root[ESPHOME_F(
"ota")] =
true;
386 root[ESPHOME_F(
"lang")] =
"en";
431#ifdef USE_WEBSERVER_LOCAL
434 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
436 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
438#ifdef USE_WEBSERVER_GZIP
439 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
441 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
443 request->send(response);
445#elif USE_WEBSERVER_VERSION >= 2
448 AsyncWebServerResponse *response =
451 AsyncWebServerResponse *response =
455 request->send(response);
459#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
461 AsyncWebServerResponse *response = request->beginResponse(200, ESPHOME_F(
""));
462 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
463 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().c_str());
466 request->send(response);
470#ifdef USE_WEBSERVER_CSS_INCLUDE
473 AsyncWebServerResponse *response =
476 AsyncWebServerResponse *response =
479 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
480 request->send(response);
484#ifdef USE_WEBSERVER_JS_INCLUDE
487 AsyncWebServerResponse *response =
490 AsyncWebServerResponse *response =
493 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
494 request->send(response);
501static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
503 size_t prefix_len = strlen(prefix);
504 size_t name_len = name.
size();
508 const char *device_name = device ? device->
get_name() :
nullptr;
509 size_t device_len = device_name ? strlen(device_name) : 0;
518 static constexpr size_t ID_BUF_SIZE =
519 ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
521 static constexpr size_t ID_BUF_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
523 char id_buf[ID_BUF_SIZE];
525 memcpy(p, prefix, prefix_len);
530 memcpy(p, device_name, device_len);
535 memcpy(p, name.
c_str(), name_len);
540 root[ESPHOME_F(
"name_id")] = id_buf;
544 char legacy_buf[ESPHOME_DOMAIN_MAX_LEN + 1 + OBJECT_ID_MAX_LEN];
545 char *lp = legacy_buf;
546 memcpy(lp, prefix, prefix_len);
550 root[ESPHOME_F(
"id")] = legacy_buf;
553 root[ESPHOME_F(
"domain")] = prefix;
554 root[ESPHOME_F(
"name")] = name;
557 root[ESPHOME_F(
"device")] = device_name;
564 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
571static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
573 set_json_id(root, obj, prefix, start_config);
574 root[ESPHOME_F(
"value")] = value;
578static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const char *
state,
580 set_json_value(root, obj, prefix, value, start_config);
581 root[ESPHOME_F(
"state")] =
state;
585static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
586 auto *param = request->getParam(ESPHOME_F(
"detail"));
599 if (!entity_match.matched)
602 if (entity_match.action_is_empty) {
603 auto detail = get_request_detail(request);
604 std::string data = this->sensor_json_(obj, obj->state, detail);
605 request->send(200,
"application/json", data.c_str());
619 JsonObject root = builder.
root();
622 char buf[VALUE_ACCURACY_MAX_LEN];
623 const char *
state = std::isnan(value)
626 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
629 if (!uom_ref.empty())
630 root[ESPHOME_F(
"uom")] = uom_ref;
637#ifdef USE_TEXT_SENSOR
646 if (!entity_match.matched)
649 if (entity_match.action_is_empty) {
650 auto detail = get_request_detail(request);
651 std::string data = this->text_sensor_json_(obj, obj->
state, detail);
652 request->send(200,
"application/json", data.c_str());
669 JsonObject root = builder.
root();
671 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
707 if (!entity_match.matched)
710 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
711 auto detail = get_request_detail(request);
712 std::string data = this->switch_json_(obj, obj->
state, detail);
713 request->send(200,
"application/json", data.c_str());
728 this->
defer([obj, action]() { execute_switch_action(obj, action); });
745 JsonObject root = builder.
root();
747 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
761 if (!entity_match.matched)
763 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
764 auto detail = get_request_detail(request);
765 std::string data = this->button_json_(obj, detail);
766 request->send(200,
"application/json", data.c_str());
768 DEFER_ACTION(obj, obj->press());
783 JsonObject root = builder.
root();
785 set_json_id(root, obj,
"button", start_config);
794#ifdef USE_BINARY_SENSOR
803 if (!entity_match.matched)
806 if (entity_match.action_is_empty) {
807 auto detail = get_request_detail(request);
808 std::string data = this->binary_sensor_json_(obj, obj->state, detail);
809 request->send(200,
"application/json", data.c_str());
825 JsonObject root = builder.
root();
827 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
845 if (!entity_match.matched)
848 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
849 auto detail = get_request_detail(request);
850 std::string data = this->fan_json_(obj, detail);
851 request->send(200,
"application/json", data.c_str());
853 DEFER_ACTION(obj, obj->toggle().perform());
858 if (!is_on && !is_off) {
862 auto call = is_on ? obj->turn_on() : obj->turn_off();
866 if (request->hasParam(ESPHOME_F(
"oscillation"))) {
867 auto speed = request->getParam(ESPHOME_F(
"oscillation"))->value();
871 call.set_oscillating(
true);
874 call.set_oscillating(
false);
877 call.set_oscillating(!obj->oscillating);
899 JsonObject root = builder.
root();
901 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
903 if (traits.supports_speed()) {
904 root[ESPHOME_F(
"speed_level")] = obj->
speed;
905 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
926 if (!entity_match.matched)
929 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
930 auto detail = get_request_detail(request);
931 std::string data = this->light_json_(obj, detail);
932 request->send(200,
"application/json", data.c_str());
939 if (!is_on && !is_off) {
978 JsonObject root = builder.
root();
980 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
984 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
987 opt.add(option->get_name());
1005 if (!entity_match.matched)
1008 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1009 auto detail = get_request_detail(request);
1010 std::string data = this->cover_json_(obj, detail);
1011 request->send(200,
"application/json", data.c_str());
1018 static const struct {
1029 for (
const auto &method : METHODS) {
1031 (
call.*method.action)();
1043 if ((request->hasParam(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1044 (request->hasParam(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1052 DEFER_ACTION(
call,
call.perform());
1066 JsonObject root = builder.
root();
1070 char buf[PSTR_LOCAL_SIZE];
1074 root[ESPHOME_F(
"position")] = obj->
position;
1076 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1092 for (
auto *obj :
App.get_numbers()) {
1094 if (!entity_match.matched)
1097 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1098 auto detail = get_request_detail(request);
1099 std::string data = this->number_json_(obj, obj->state, detail);
1100 request->send(200,
"application/json", data.c_str());
1111 DEFER_ACTION(
call,
call.perform());
1126 JsonObject root = builder.
root();
1132 char val_buf[VALUE_ACCURACY_MAX_LEN];
1133 char state_buf[VALUE_ACCURACY_MAX_LEN];
1134 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1135 const char *state_str =
1137 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1144 if (!uom_ref.empty())
1145 root[ESPHOME_F(
"uom")] = uom_ref;
1153#ifdef USE_DATETIME_DATE
1160 for (
auto *obj :
App.get_dates()) {
1162 if (!entity_match.matched)
1164 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1165 auto detail = get_request_detail(request);
1166 std::string data = this->date_json_(obj, detail);
1167 request->send(200,
"application/json", data.c_str());
1177 if (!request->hasParam(ESPHOME_F(
"value"))) {
1184 DEFER_ACTION(
call,
call.perform());
1199 JsonObject root = builder.
root();
1203 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1204 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1213#ifdef USE_DATETIME_TIME
1220 for (
auto *obj :
App.get_times()) {
1222 if (!entity_match.matched)
1224 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1225 auto detail = get_request_detail(request);
1226 std::string data = this->time_json_(obj, detail);
1227 request->send(200,
"application/json", data.c_str());
1237 if (!request->hasParam(ESPHOME_F(
"value"))) {
1244 DEFER_ACTION(
call,
call.perform());
1258 JsonObject root = builder.
root();
1262 buf_append_printf(value,
sizeof(value), 0,
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1263 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1272#ifdef USE_DATETIME_DATETIME
1279 for (
auto *obj :
App.get_datetimes()) {
1281 if (!entity_match.matched)
1283 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1284 auto detail = get_request_detail(request);
1285 std::string data = this->datetime_json_(obj, detail);
1286 request->send(200,
"application/json", data.c_str());
1296 if (!request->hasParam(ESPHOME_F(
"value"))) {
1303 DEFER_ACTION(
call,
call.perform());
1317 JsonObject root = builder.
root();
1321 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour,
1323 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1339 for (
auto *obj :
App.get_texts()) {
1341 if (!entity_match.matched)
1344 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1345 auto detail = get_request_detail(request);
1346 std::string data = this->text_json_(obj, obj->state, detail);
1347 request->send(200,
"application/json", data.c_str());
1358 DEFER_ACTION(
call,
call.perform());
1371std::string WebServer::text_json_(
text::Text *obj,
const std::string &value,
JsonDetail start_config) {
1373 JsonObject root = builder.
root();
1376 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1396 for (
auto *obj :
App.get_selects()) {
1398 if (!entity_match.matched)
1401 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1402 auto detail = get_request_detail(request);
1403 std::string data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail);
1404 request->send(200,
"application/json", data.c_str());
1416 DEFER_ACTION(
call,
call.perform());
1432 JsonObject root = builder.
root();
1435 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1437 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1455 for (
auto *obj :
App.get_climates()) {
1457 if (!entity_match.matched)
1460 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1461 auto detail = get_request_detail(request);
1462 std::string data = this->climate_json_(obj, detail);
1463 request->send(200,
"application/json", data.c_str());
1481 &
decltype(
call)::set_target_temperature_high);
1485 DEFER_ACTION(
call,
call.perform());
1502 JsonObject root = builder.
root();
1503 set_json_id(root, obj,
"climate", start_config);
1506 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1507 char buf[PSTR_LOCAL_SIZE];
1508 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1511 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1514 if (!traits.get_supported_custom_fan_modes().empty()) {
1515 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1520 if (!traits.get_supported_custom_fan_modes().empty()) {
1521 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1522 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1525 if (traits.get_supports_swing_modes()) {
1526 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1527 for (
auto swing_mode : traits.get_supported_swing_modes())
1531 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1535 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1536 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1537 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1543 bool has_state =
false;
1545 root[ESPHOME_F(
"max_temp")] =
1547 root[ESPHOME_F(
"min_temp")] =
1549 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1552 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1564 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1567 if (traits.get_supports_swing_modes()) {
1571 root[ESPHOME_F(
"current_temperature")] =
1578 root[ESPHOME_F(
"target_temperature_low")] =
1580 root[ESPHOME_F(
"target_temperature_high")] =
1583 root[ESPHOME_F(
"state")] =
1589 root[ESPHOME_F(
"target_temperature")] =
1592 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1627 if (!entity_match.matched)
1630 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1631 auto detail = get_request_detail(request);
1632 std::string data = this->lock_json_(obj, obj->
state, detail);
1633 request->send(200,
"application/json", data.c_str());
1648 this->
defer([obj, action]() { execute_lock_action(obj, action); });
1665 JsonObject root = builder.
root();
1667 char buf[PSTR_LOCAL_SIZE];
1686 if (!entity_match.matched)
1689 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1690 auto detail = get_request_detail(request);
1691 std::string data = this->valve_json_(obj, detail);
1692 request->send(200,
"application/json", data.c_str());
1699 static const struct {
1710 for (
const auto &method : METHODS) {
1712 (
call.*method.action)();
1723 auto traits = obj->get_traits();
1724 if (request->hasParam(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1731 DEFER_ACTION(
call,
call.perform());
1745 JsonObject root = builder.
root();
1749 char buf[PSTR_LOCAL_SIZE];
1753 root[ESPHOME_F(
"position")] = obj->
position;
1762#ifdef USE_ALARM_CONTROL_PANEL
1771 if (!entity_match.matched)
1774 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1775 auto detail = get_request_detail(request);
1776 std::string data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1777 request->send(200,
"application/json", data.c_str());
1785 static const struct {
1797 for (
const auto &method : METHODS) {
1799 (
call.*method.action)();
1810 DEFER_ACTION(
call,
call.perform());
1830 JsonObject root = builder.
root();
1832 char buf[PSTR_LOCAL_SIZE];
1833 set_json_icon_state_value(root, obj,
"alarm-control-panel", PSTR_LOCAL(alarm_control_panel_state_to_string(value)),
1834 value, start_config);
1843#ifdef USE_WATER_HEATER
1852 if (!entity_match.matched)
1855 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1856 auto detail = get_request_detail(request);
1857 std::string data = this->water_heater_json_(obj, detail);
1858 request->send(200,
"application/json", data.c_str());
1886 DEFER_ACTION(
call,
call.perform());
1902 JsonObject root = builder.
root();
1903 char buf[PSTR_LOCAL_SIZE];
1908 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1913 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1914 for (
auto m : traits.get_supported_modes())
1916 root[ESPHOME_F(
"min_temp")] = traits.get_min_temperature();
1917 root[ESPHOME_F(
"max_temp")] = traits.get_max_temperature();
1918 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
1922 if (traits.get_supports_current_temperature()) {
1924 if (!std::isnan(current))
1925 root[ESPHOME_F(
"current_temperature")] = current;
1928 if (traits.get_supports_two_point_target_temperature()) {
1931 if (!std::isnan(low))
1932 root[ESPHOME_F(
"target_temperature_low")] = low;
1933 if (!std::isnan(high))
1934 root[ESPHOME_F(
"target_temperature_high")] = high;
1937 if (!std::isnan(target))
1938 root[ESPHOME_F(
"target_temperature")] = target;
1941 if (traits.get_supports_away_mode()) {
1942 root[ESPHOME_F(
"away")] = obj->
is_away();
1946 root[ESPHOME_F(
"is_on")] = obj->
is_on();
1957 if (!entity_match.matched)
1960 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1961 auto detail = get_request_detail(request);
1962 std::string data = this->infrared_json_(obj, detail);
1963 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
1972 if (!obj->has_transmitter()) {
1973 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
1981 if (request->hasParam(ESPHOME_F(
"carrier_frequency"))) {
1983 if (value.has_value()) {
1984 call.set_carrier_frequency(*value);
1989 if (request->hasParam(ESPHOME_F(
"repeat_count"))) {
1991 if (value.has_value()) {
1992 call.set_repeat_count(*value);
1998 if (!request->hasParam(ESPHOME_F(
"data"))) {
1999 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing 'data' parameter"));
2004 std::string encoded =
2005 request->getParam(ESPHOME_F(
"data"))->value().c_str();
2008 if (encoded.empty()) {
2009 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Empty 'data' parameter"));
2017 this->
defer([
call, encoded = std::move(encoded)]()
mutable {
2018 call.set_raw_timings_base64url(encoded);
2035 JsonObject root = builder.
root();
2037 set_json_icon_state_value(root, obj,
"infrared",
"", 0, start_config);
2042 root[ESPHOME_F(
"supports_receiver")] = traits.get_supports_receiver();
2062 if (!entity_match.matched)
2066 if (entity_match.action_is_empty) {
2067 auto detail = get_request_detail(request);
2068 std::string data = this->event_json_(obj,
StringRef(), detail);
2069 request->send(200,
"application/json", data.c_str());
2080 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
2085 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
2089 JsonObject root = builder.
root();
2091 set_json_id(root, obj,
"event", start_config);
2092 if (!event_type.
empty()) {
2093 root[ESPHOME_F(
"event_type")] = event_type;
2096 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2098 event_types.add(event_type);
2116 if (!entity_match.matched)
2119 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2120 auto detail = get_request_detail(request);
2121 std::string data = this->update_json_(obj, detail);
2122 request->send(200,
"application/json", data.c_str());
2131 DEFER_ACTION(obj, obj->perform());
2148 JsonObject root = builder.
root();
2150 char buf[PSTR_LOCAL_SIZE];
2168 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2169 StringRef url = request->url_to(url_buf);
2171 const auto &url = request->url();
2173 const auto method = request->method();
2176 if (url == ESPHOME_F(
"/"))
2178#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2179 if (url == ESPHOME_F(
"/events"))
2182#ifdef USE_WEBSERVER_CSS_INCLUDE
2183 if (url == ESPHOME_F(
"/0.css"))
2186#ifdef USE_WEBSERVER_JS_INCLUDE
2187 if (url == ESPHOME_F(
"/0.js"))
2191#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2192 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2202 bool is_get = method == HTTP_GET;
2203 bool is_post = method == HTTP_POST;
2204 bool is_get_or_post = is_get || is_post;
2206 if (!is_get_or_post)
2215#ifdef USE_BINARY_SENSOR
2219#ifdef USE_TEXT_SENSOR
2230 if (is_get_or_post) {
2255#ifdef USE_DATETIME_DATE
2259#ifdef USE_DATETIME_TIME
2263#ifdef USE_DATETIME_DATETIME
2287#ifdef USE_ALARM_CONTROL_PANEL
2295#ifdef USE_WATER_HEATER
2309 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2310 StringRef url = request->url_to(url_buf);
2312 const auto &url = request->url();
2316 if (url == ESPHOME_F(
"/")) {
2321#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2322 if (url == ESPHOME_F(
"/events")) {
2323 this->
events_.add_new_client(
this, request);
2328#ifdef USE_WEBSERVER_CSS_INCLUDE
2329 if (url == ESPHOME_F(
"/0.css")) {
2335#ifdef USE_WEBSERVER_JS_INCLUDE
2336 if (url == ESPHOME_F(
"/0.js")) {
2342#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2343 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2351 UrlMatch match = match_url(url.
c_str(), url.
length(),
false, request->method() == HTTP_POST);
2372#ifdef USE_BINARY_SENSOR
2387#ifdef USE_TEXT_SENSOR
2402#ifdef USE_DATETIME_DATE
2407#ifdef USE_DATETIME_TIME
2412#ifdef USE_DATETIME_DATETIME
2442#ifdef USE_ALARM_CONTROL_PANEL
2443 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2452#ifdef USE_WATER_HEATER
2464 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.
c_str());
2465 request->send(404, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Not Found"));
2472#ifdef USE_WEBSERVER_SORTING
2475 if (this->
sorting_groups_.find(this->sorting_entitys_[entity].group_id) != this->sorting_groups_.end()) {
2482#ifdef USE_WEBSERVER_SORTING
BedjetMode mode
BedJet operating mode.
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
const std::string & get_name() const
Get the name of this Application set by pre_setup().
void get_comment_string(std::span< char, ESPHOME_COMMENT_SIZE > buffer)
Copy the comment string into the provided buffer Buffer must be ESPHOME_COMMENT_SIZE bytes (compile-t...
auto & get_binary_sensors() const
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_interval(const std voi set_interval)(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
void begin(bool include_internal=false)
static void register_controller(Controller *controller)
Register a controller to receive entity state updates.
StringRef get_device_class_ref() const
Get the device class as StringRef.
StringRef get_unit_of_measurement_ref() const
Get the unit of measurement as StringRef.
const StringRef & get_name() const
StringRef get_icon_ref() const
size_t write_object_id_to(char *buf, size_t buf_size) const
Write object_id directly to buffer, returns length written (excluding null) Useful for building compo...
bool is_disabled_by_default() const
Device * get_device() const
EntityCategory get_entity_category() const
StringRef get_object_id_to(std::span< char, OBJECT_ID_MAX_LEN > buf) const
Get object_id with zero heap allocation For static case: returns StringRef to internal storage (buffe...
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
constexpr 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.
ClimateDevice - This is the base class for all climate integrations.
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
float target_temperature
The target temperature of the climate device.
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
bool has_custom_preset() const
Check if a custom preset is currently active.
float current_temperature
The current temperature of the climate device, as reported from the integration.
ClimateAction action
The active state of the climate device.
StringRef get_custom_preset() const
Get the active custom preset (read-only access). Returns StringRef.
bool has_custom_fan_mode() const
Check if a custom fan mode is currently active.
optional< ClimatePreset > preset
The active preset of the climate device.
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
StringRef get_custom_fan_mode() const
Get the active custom fan mode (read-only access). Returns StringRef.
int8_t get_target_temperature_accuracy_decimals() const
CoverCall & set_command_toggle()
Set the command to toggle the cover.
CoverCall & set_command_open()
Set the command to open the cover.
CoverCall & set_command_close()
Set the command to close the cover.
CoverCall & set_command_stop()
Set the command to stop the cover.
Base class for all cover devices.
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
CoverCall make_call()
Construct a new cover call used to control the cover.
float tilt
The current tilt value of the cover from 0.0 to 1.0.
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
bool is_fully_closed() const
Helper method to check if the cover is fully closed. Equivalent to comparing .position against 0....
virtual CoverTraits get_traits()=0
bool get_supports_position() const
bool get_supports_tilt() const
const FixedVector< const char * > & get_event_types() const
Return the event types supported by this event.
virtual FanTraits get_traits()=0
bool oscillating
The current oscillation state of the fan.
bool state
The current on/off state of the fan.
int speed
The current fan speed level.
bool supports_oscillation() const
Return if this fan supports oscillation.
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.
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_listener(LogListener *listener)
Register a log listener to receive log messages.
Base-class for all numbers.
float get_min_value() const
float get_max_value() const
NumberMode get_mode() const
value_type const & value() const
Base-class for all selects.
SelectCall make_call()
Instantiate a SelectCall object to modify this select component's state.
const FixedVector< const char * > & get_options() const
Base-class for all sensors.
float state
This member variable stores the last state that has passed through all filters.
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Base class for all switches.
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.
static std::string water_heater_state_json_generator(WebServer *web_server, void *source)
void setup() override
Setup the internal web server and register handlers.
void on_update(update::UpdateEntity *obj) override
static std::string text_sensor_all_json_generator(WebServer *web_server, void *source)
void on_water_heater_update(water_heater::WaterHeater *obj) override
static std::string water_heater_all_json_generator(WebServer *web_server, void *source)
std::string get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static std::string binary_sensor_state_json_generator(WebServer *web_server, void *source)
void parse_string_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(const std::string &))
void on_text_update(text::Text *obj) override
static std::string lock_all_json_generator(WebServer *web_server, void *source)
void on_light_update(light::LightState *obj) override
static std::string date_all_json_generator(WebServer *web_server, void *source)
void parse_float_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(float))
void on_cover_update(cover::Cover *obj) override
static std::string text_state_json_generator(WebServer *web_server, void *source)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
static std::string event_state_json_generator(WebServer *web_server, void *source)
void handle_water_heater_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a water_heater request under '/water_heater/<id>/<mode/set>'.
static std::string datetime_all_json_generator(WebServer *web_server, void *source)
static std::string sensor_all_json_generator(WebServer *web_server, void *source)
bool isRequestHandlerTrivial() const override
This web handle is not trivial.
WebServer(web_server_base::WebServerBase *base)
void handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a switch request under '/switch/<id>/</turn_on/turn_off/toggle>'.
void handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a event request under '/event<id>'.
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override
void parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
void dump_config() override
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a button request under '/button/<id>/press'.
void on_date_update(datetime::DateEntity *obj) override
void on_number_update(number::Number *obj) override
void add_entity_config(EntityBase *entity, float weight, uint64_t group)
void parse_light_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(float), float scale=1.0f)
void handle_css_request(AsyncWebServerRequest *request)
Handle included css request under '/0.css'.
static std::string sensor_state_json_generator(WebServer *web_server, void *source)
void on_valve_update(valve::Valve *obj) override
void on_climate_update(climate::Climate *obj) override
static std::string switch_state_json_generator(WebServer *web_server, void *source)
void parse_int_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(int))
void add_sorting_info_(JsonObject &root, EntityBase *entity)
void handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a light request under '/light/<id>/</turn_on/turn_off/toggle>'.
static std::string event_all_json_generator(WebServer *web_server, void *source)
static std::string climate_state_json_generator(WebServer *web_server, void *source)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
static std::string number_all_json_generator(WebServer *web_server, void *source)
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
static std::string date_state_json_generator(WebServer *web_server, void *source)
static std::string valve_all_json_generator(WebServer *web_server, void *source)
static std::string text_all_json_generator(WebServer *web_server, void *source)
void on_switch_update(switch_::Switch *obj) override
web_server_base::WebServerBase * base_
static std::string binary_sensor_all_json_generator(WebServer *web_server, void *source)
static std::string light_state_json_generator(WebServer *web_server, void *source)
void handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a lock request under '/lock/<id>/</lock/unlock/open>'.
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
static std::string light_all_json_generator(WebServer *web_server, void *source)
void handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text sensor request under '/text_sensor/<id>'.
void parse_bool_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(bool))
void handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a date request under '/date/<id>'.
static std::string cover_all_json_generator(WebServer *web_server, void *source)
void handle_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>'.
static std::string text_sensor_state_json_generator(WebServer *web_server, void *source)
void handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a number request under '/number/<id>'.
static std::string alarm_control_panel_state_json_generator(WebServer *web_server, void *source)
void handle_index_request(AsyncWebServerRequest *request)
Handle an index request under '/'.
void handle_js_request(AsyncWebServerRequest *request)
Handle included js request under '/0.js'.
void set_js_include(const char *js_include)
Set local path to the script that's embedded in the index page.
static std::string fan_state_json_generator(WebServer *web_server, void *source)
static std::string update_state_json_generator(WebServer *web_server, void *source)
void handleRequest(AsyncWebServerRequest *request) override
Override the web handler's handleRequest method.
static std::string climate_all_json_generator(WebServer *web_server, void *source)
void on_datetime_update(datetime::DateTimeEntity *obj) override
void handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a fan request under '/fan/<id>/</turn_on/turn_off/toggle>'.
static std::string cover_state_json_generator(WebServer *web_server, void *source)
static std::string lock_state_json_generator(WebServer *web_server, void *source)
void handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a valve request under '/valve/<id>/<open/close/stop/set>'.
void handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a binary sensor request under '/binary_sensor/<id>'.
static std::string infrared_all_json_generator(WebServer *web_server, void *source)
static std::string alarm_control_panel_all_json_generator(WebServer *web_server, void *source)
static std::string number_state_json_generator(WebServer *web_server, void *source)
void handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a time request under '/time/<id>'.
void on_sensor_update(sensor::Sensor *obj) override
std::map< uint64_t, SortingGroup > sorting_groups_
void set_css_include(const char *css_include)
Set local path to the script that's embedded in the index page.
static std::string valve_state_json_generator(WebServer *web_server, void *source)
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
void on_event(event::Event *obj) override
void handle_pna_cors_request(AsyncWebServerRequest *request)
void on_fan_update(fan::Fan *obj) override
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
static std::string time_state_json_generator(WebServer *web_server, void *source)
void on_lock_update(lock::Lock *obj) override
static std::string button_all_json_generator(WebServer *web_server, void *source)
static std::string select_state_json_generator(WebServer *web_server, void *source)
float get_setup_priority() const override
MQTT setup priority.
void on_select_update(select::Select *obj) override
void on_time_update(datetime::TimeEntity *obj) override
static std::string update_all_json_generator(WebServer *web_server, void *source)
void handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a update request under '/update/<id>'.
static std::string fan_all_json_generator(WebServer *web_server, void *source)
static std::string switch_all_json_generator(WebServer *web_server, void *source)
static std::string time_all_json_generator(WebServer *web_server, void *source)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
static std::string select_all_json_generator(WebServer *web_server, void *source)
const char * css_include_
static std::string datetime_state_json_generator(WebServer *web_server, void *source)
void handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a climate request under '/climate/<id>'.
void on_text_sensor_update(text_sensor::TextSensor *obj) override
void add_handler(AsyncWebHandler *handler)
uint16_t get_port() const
ClimateSwingMode swing_mode
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
@ CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_SUPPORTS_ACTION
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
ClimateMode
Enum for all modes a climate device can be in.
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
const LogString * cover_operation_to_str(CoverOperation op)
const LogString * lock_state_to_string(LockState state)
LockState
Enum for all states a lock can be in.
const char * get_use_address()
Get the active network hostname.
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.
std::string(WebServer *, void *) message_generator_t
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Parse a string that contains either on, off or toggle.
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