14#if !defined(USE_ESP32) && defined(USE_ARDUINO)
15#include "StreamString.h"
36#ifdef USE_WATER_HEATER
43#ifdef USE_RADIO_FREQUENCY
47#ifdef USE_WEBSERVER_LOCAL
48#if USE_WEBSERVER_VERSION == 2
50#elif USE_WEBSERVER_VERSION == 3
57static const char *
const TAG =
"web_server";
60[[maybe_unused]]
static ProgmemStr json_state_str(
const LogString *s) {
return reinterpret_cast<ProgmemStr>(s); }
68static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain,
bool is_post =
false) {
70 if (url_len < 2 || url_ptr[0] !=
'/')
73 const char *p = url_ptr + 1;
74 const char *
end = url_ptr + url_len;
77 auto next_segment = [&
end](
const char *start) ->
const char * {
78 const char *slash = (
const char *) memchr(start,
'/',
end - start);
79 return slash ? slash + 1 :
nullptr;
83 auto make_ref = [&
end](
const char *start,
const char *next_start) -> StringRef {
84 return StringRef(start, (next_start ? next_start - 1 :
end) - start);
89 const char *s2 = next_segment(s1);
96 match.domain = make_ref(s1, s2);
99 if (only_domain || s2 >=
end)
103 const char *s3 = next_segment(s2);
104 const char *s4 = s3 ? next_segment(s3) : nullptr;
106 StringRef seg2 = make_ref(s2, s3);
107 StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef();
108 StringRef seg4 = s4 ? make_ref(s4,
nullptr) : StringRef();
111 if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty()))
127 match.device_name = seg2;
138 match.device_name = seg2;
155 bool entity_has_device = (entity_device !=
nullptr);
158 if (url_has_device != entity_has_device) {
167 if (this->
id == entity->
get_name()) {
168 result.matched =
true;
174#if !defined(USE_ESP32) && defined(USE_ARDUINO)
178 DeferredEvent item(source, message_generator);
186 this->deferred_queue_.push_back(item);
193 if (this->send(
message.c_str(),
"state") != DISCARDED) {
205 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
224 if (this->count() == 0)
232 if (source ==
nullptr)
234 if (event_type ==
nullptr)
236 if (message_generator ==
nullptr)
239 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
240 ESP_LOGE(TAG,
"Can't defer non-state event");
250 if (this->send(
message.c_str(),
"state") == DISCARDED) {
263 this->send(
message, event,
id, reconnect);
270 return !this->empty();
294 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
298 es->handleRequest(request);
304 ws->
defer([ws, source]() {
310#ifdef USE_WEBSERVER_SORTING
313 JsonObject root = builder.
root();
314 root[ESPHOME_F(
"name")] = group.second.name;
315 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
319 source->
try_send_nodefer(group_msg.c_str(), group_msg.size(),
"sorting_group");
337 this->remove(source);
345#ifdef USE_WEBSERVER_CSS_INCLUDE
348#ifdef USE_WEBSERVER_JS_INCLUDE
354 JsonObject root = builder.
root();
359 root[ESPHOME_F(
"comment")] = comment_buffer;
360#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
361 root[ESPHOME_F(
"ota")] =
false;
363 root[ESPHOME_F(
"ota")] =
true;
366 root[ESPHOME_F(
"lang")] =
"en";
379 this, [](
void *self, uint8_t level,
const char *
tag,
const char *
message,
size_t message_len) {
399 size_t len = buf_append_printf(buf,
sizeof(buf), 0,
"{\"uptime\":%" PRIu32
"}", uptime);
418 this->
events_.try_send_nodefer(message, message_len,
"log",
millis());
423 char addr_buf[network::USE_ADDRESS_BUFFER_SIZE];
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);
461static std::string get_request_header(AsyncWebServerRequest *request,
const char *name) {
464 optional<std::string> value = request->get_header(name);
465 return value.has_value() ? std::move(*value) :
std::string();
468 const AsyncWebHeader *header = request->getHeader(name);
469 return header !=
nullptr ? std::string(header->value().c_str()) :
std::string();
480 const size_t scheme_sep = origin.find(
"://");
481 if (scheme_sep != std::string::npos) {
482 const std::string host = get_request_header(request,
"Host");
483 if (!host.empty() && origin.compare(scheme_sep + 3, std::string::npos, host) == 0)
487#ifdef USE_WEBSERVER_ALLOWED_ORIGINS
491 if (allowed_origin[0] ==
'*' && allowed_origin[1] ==
'\0')
493 if (origin == allowed_origin)
500#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
502 const std::string origin = get_request_header(request,
"Origin");
508 AsyncWebServerResponse *response = request->beginResponse(200, ESPHOME_F(
""));
510 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Origin"), origin.empty() ?
"*" : origin.c_str());
511 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
512 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().
c_str());
515 request->send(response);
519#ifdef USE_WEBSERVER_CSS_INCLUDE
522 AsyncWebServerResponse *response =
525 AsyncWebServerResponse *response =
528 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
529 request->send(response);
533#ifdef USE_WEBSERVER_JS_INCLUDE
536 AsyncWebServerResponse *response =
539 AsyncWebServerResponse *response =
542 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
543 request->send(response);
550static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
552 size_t prefix_len = strlen(prefix);
553 size_t name_len = name.size();
557 const char *device_name = device ? device->
get_name() :
nullptr;
558 size_t device_len = device_name ? strlen(device_name) : 0;
567 static constexpr size_t LEGACY_ID_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + OBJECT_ID_MAX_LEN;
569 static constexpr size_t ID_BUF_SIZE =
570 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1,
573 static constexpr size_t ID_BUF_SIZE =
574 std::max(ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1, LEGACY_ID_SIZE);
576 char id_buf[ID_BUF_SIZE];
577 memcpy(id_buf, prefix, prefix_len);
581 char *p = id_buf + prefix_len;
585 memcpy(p, device_name, device_len);
590 memcpy(p, name.c_str(), name_len);
592 root[ESPHOME_F(
"name_id")] = id_buf;
596 id_buf[prefix_len] =
'-';
598 root[ESPHOME_F(
"id")] = id_buf;
601 root[ESPHOME_F(
"domain")] = prefix;
603 root[ESPHOME_F(
"name")] = name.c_str();
606 root[ESPHOME_F(
"device")] = device_name;
609#ifdef USE_ENTITY_ICON
610 char icon_buf[MAX_ICON_LENGTH];
611 root[ESPHOME_F(
"icon")] = obj->
get_icon_to(icon_buf);
616 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
623static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
625 set_json_id(root, obj, prefix, start_config);
626 root[ESPHOME_F(
"value")] = value;
629template<
typename S,
typename T>
630static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix, S
state,
const T &value,
632 set_json_value(root, obj, prefix, value, start_config);
633 root[ESPHOME_F(
"state")] =
state;
637[[maybe_unused]]
static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
650 if (!entity_match.matched)
653 if (entity_match.action_is_empty) {
654 auto detail = get_request_detail(request);
655 auto data = this->sensor_json_(obj, obj->state, detail);
656 request->send(200,
"application/json", data.c_str());
670 JsonObject root = builder.
root();
673 char buf[VALUE_ACCURACY_MAX_LEN];
674 const char *
state = std::isnan(value)
677 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
680 if (!uom_ref.empty())
681 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
688#ifdef USE_TEXT_SENSOR
697 if (!entity_match.matched)
700 if (entity_match.action_is_empty) {
701 auto detail = get_request_detail(request);
702 auto data = this->text_sensor_json_(obj, obj->
state, detail);
703 request->send(200,
"application/json", data.c_str());
720 JsonObject root = builder.
root();
722 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
758 if (!entity_match.matched)
761 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
762 auto detail = get_request_detail(request);
763 auto data = this->switch_json_(obj, obj->
state, detail);
764 request->send(200,
"application/json", data.c_str());
779 this->
defer([obj, action]() { execute_switch_action(obj, action); });
796 JsonObject root = builder.
root();
798 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
812 if (!entity_match.matched)
814 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
815 auto detail = get_request_detail(request);
816 auto data = this->button_json_(obj, detail);
817 request->send(200,
"application/json", data.c_str());
819 DEFER_ACTION(obj, obj->press());
834 JsonObject root = builder.
root();
836 set_json_id(root, obj,
"button", start_config);
845#ifdef USE_BINARY_SENSOR
854 if (!entity_match.matched)
857 if (entity_match.action_is_empty) {
858 auto detail = get_request_detail(request);
859 auto data = this->binary_sensor_json_(obj, obj->state, detail);
860 request->send(200,
"application/json", data.c_str());
877 JsonObject root = builder.
root();
879 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
897 if (!entity_match.matched)
900 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
901 auto detail = get_request_detail(request);
902 auto data = this->fan_json_(obj, detail);
903 request->send(200,
"application/json", data.c_str());
905 DEFER_ACTION(obj, obj->toggle().perform());
910 if (!is_on && !is_off) {
914 auto call = is_on ? obj->turn_on() : obj->turn_off();
918 if (request->hasArg(ESPHOME_F(
"oscillation"))) {
919 auto speed = request->arg(ESPHOME_F(
"oscillation"));
923 call.set_oscillating(
true);
926 call.set_oscillating(
false);
929 call.set_oscillating(!obj->oscillating);
951 JsonObject root = builder.
root();
953 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
955 if (traits.supports_speed()) {
956 root[ESPHOME_F(
"speed_level")] = obj->
speed;
957 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
978 if (!entity_match.matched)
981 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
982 auto detail = get_request_detail(request);
983 auto data = this->light_json_(obj, detail);
984 request->send(200,
"application/json", data.c_str());
991 if (!is_on && !is_off) {
1013 request, ESPHOME_F(
"effect"),
call,
1017 DEFER_ACTION(
call,
call.perform());
1032 JsonObject root = builder.
root();
1034 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
1038 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
1041 opt.add(option->get_name());
1059 if (!entity_match.matched)
1062 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1063 auto detail = get_request_detail(request);
1064 auto data = this->cover_json_(obj, detail);
1065 request->send(200,
"application/json", data.c_str());
1072 static const struct {
1083 for (
const auto &method : METHODS) {
1085 (
call.*method.action)();
1097 if ((request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1098 (request->hasArg(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1106 DEFER_ACTION(
call,
call.perform());
1120 JsonObject root = builder.
root();
1127 root[ESPHOME_F(
"position")] = obj->
position;
1129 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1145 for (
auto *obj :
App.get_numbers()) {
1147 if (!entity_match.matched)
1150 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1151 auto detail = get_request_detail(request);
1152 auto data = this->number_json_(obj, obj->state, detail);
1153 request->send(200,
"application/json", data.c_str());
1164 DEFER_ACTION(
call,
call.perform());
1179 JsonObject root = builder.
root();
1185 char val_buf[VALUE_ACCURACY_MAX_LEN];
1186 char state_buf[VALUE_ACCURACY_MAX_LEN];
1187 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1188 const char *state_str =
1190 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1197 if (!uom_ref.empty())
1198 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
1206#ifdef USE_DATETIME_DATE
1213 for (
auto *obj :
App.get_dates()) {
1215 if (!entity_match.matched)
1217 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1218 auto detail = get_request_detail(request);
1219 auto data = this->date_json_(obj, detail);
1220 request->send(200,
"application/json", data.c_str());
1230 const auto &value = request->arg(ESPHOME_F(
"value"));
1232 if (value.length() == 0) {
1236 call.set_date(value.c_str(), value.length());
1238 DEFER_ACTION(
call,
call.perform());
1253 JsonObject root = builder.
root();
1257 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1258 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1267#ifdef USE_DATETIME_TIME
1274 for (
auto *obj :
App.get_times()) {
1276 if (!entity_match.matched)
1278 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1279 auto detail = get_request_detail(request);
1280 auto data = this->time_json_(obj, detail);
1281 request->send(200,
"application/json", data.c_str());
1291 const auto &value = request->arg(ESPHOME_F(
"value"));
1293 if (value.length() == 0) {
1297 call.set_time(value.c_str(), value.length());
1299 DEFER_ACTION(
call,
call.perform());
1313 JsonObject root = builder.
root();
1317 buf_append_printf(value,
sizeof(value), 0,
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1318 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1327#ifdef USE_DATETIME_DATETIME
1334 for (
auto *obj :
App.get_datetimes()) {
1336 if (!entity_match.matched)
1338 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1339 auto detail = get_request_detail(request);
1340 auto data = this->datetime_json_(obj, detail);
1341 request->send(200,
"application/json", data.c_str());
1351 const auto &value = request->arg(ESPHOME_F(
"value"));
1353 if (value.length() == 0) {
1357 call.set_datetime(value.c_str(), value.length());
1359 DEFER_ACTION(
call,
call.perform());
1373 JsonObject root = builder.
root();
1377 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour,
1379 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1395 for (
auto *obj :
App.get_texts()) {
1397 if (!entity_match.matched)
1400 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1401 auto detail = get_request_detail(request);
1402 auto data = this->text_json_(obj, obj->state, detail);
1403 request->send(200,
"application/json", data.c_str());
1413 request, ESPHOME_F(
"value"),
call,
1416 DEFER_ACTION(
call,
call.perform());
1431 JsonObject root = builder.
root();
1434 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1454 for (
auto *obj :
App.get_selects()) {
1456 if (!entity_match.matched)
1459 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1460 auto detail = get_request_detail(request);
1461 auto data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail);
1462 request->send(200,
"application/json", data.c_str());
1473 request, ESPHOME_F(
"option"),
call,
1476 DEFER_ACTION(
call,
call.perform());
1492 JsonObject root = builder.
root();
1495 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1497 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1515 for (
auto *obj :
App.get_climates()) {
1517 if (!entity_match.matched)
1520 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1521 auto detail = get_request_detail(request);
1522 auto data = this->climate_json_(obj, detail);
1523 request->send(200,
"application/json", data.c_str());
1536 request, ESPHOME_F(
"mode"),
call,
1540 &
decltype(
call)::set_fan_mode));
1543 &
decltype(
call)::set_swing_mode));
1546 &
decltype(
call)::set_preset));
1550 using ClimateCall =
decltype(
call);
1552 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_high));
1554 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_low));
1556 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature));
1558 DEFER_ACTION(
call,
call.perform());
1575 JsonObject root = builder.
root();
1576 set_json_id(root, obj,
"climate", start_config);
1579 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1580 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1583 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1586 if (traits.get_supports_fan_modes()) {
1587 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1592 if (!traits.get_supported_custom_fan_modes().empty()) {
1593 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1594 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1597 if (traits.get_supports_swing_modes()) {
1598 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1599 for (
auto swing_mode : traits.get_supported_swing_modes())
1602 if (traits.get_supports_presets()) {
1603 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1607 if (!traits.get_supported_custom_presets().empty()) {
1608 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1609 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1612 root[ESPHOME_F(
"max_temp")] =
1614 root[ESPHOME_F(
"min_temp")] =
1616 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1620 bool has_state =
false;
1624 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1627 if (traits.get_supports_fan_modes() && obj->
fan_mode.has_value()) {
1633 if (traits.get_supports_presets() && obj->
preset.has_value()) {
1636 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1639 if (traits.get_supports_swing_modes()) {
1643 root[ESPHOME_F(
"current_temperature")] =
1655 root[ESPHOME_F(
"target_temperature_low")] =
1657 root[ESPHOME_F(
"target_temperature_high")] =
1660 root[ESPHOME_F(
"state")] =
1666 root[ESPHOME_F(
"target_temperature")] =
1669 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1704 if (!entity_match.matched)
1707 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1708 auto detail = get_request_detail(request);
1709 auto data = this->lock_json_(obj, obj->
state, detail);
1710 request->send(200,
"application/json", data.c_str());
1725 this->
defer([obj, action]() { execute_lock_action(obj, action); });
1742 JsonObject root = builder.
root();
1762 if (!entity_match.matched)
1765 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1766 auto detail = get_request_detail(request);
1767 auto data = this->valve_json_(obj, detail);
1768 request->send(200,
"application/json", data.c_str());
1775 static const struct {
1786 for (
const auto &method : METHODS) {
1788 (
call.*method.action)();
1799 auto traits = obj->get_traits();
1800 if (request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1807 DEFER_ACTION(
call,
call.perform());
1821 JsonObject root = builder.
root();
1828 root[ESPHOME_F(
"position")] = obj->
position;
1837#ifdef USE_ALARM_CONTROL_PANEL
1846 if (!entity_match.matched)
1849 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1850 auto detail = get_request_detail(request);
1851 auto data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1852 request->send(200,
"application/json", data.c_str());
1858 request, ESPHOME_F(
"code"),
call,
1863 static const struct {
1875 for (
const auto &method : METHODS) {
1877 (
call.*method.action)();
1888 DEFER_ACTION(
call,
call.perform());
1908 JsonObject root = builder.
root();
1910 set_json_icon_state_value(root, obj,
"alarm-control-panel",
1911 json_state_str(alarm_control_panel_state_to_string(value)), value, start_config);
1920#ifdef USE_WATER_HEATER
1929 if (!entity_match.matched)
1932 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1933 auto detail = get_request_detail(request);
1934 auto data = this->water_heater_json_(obj, detail);
1935 request->send(200,
"application/json", data.c_str());
1948 request, ESPHOME_F(
"mode"), base_call,
1966 DEFER_ACTION(
call,
call.perform());
1982 JsonObject root = builder.
root();
1987 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1992 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1993 for (
auto m : traits.get_supported_modes())
1995 root[ESPHOME_F(
"min_temp")] = traits.get_min_temperature();
1996 root[ESPHOME_F(
"max_temp")] = traits.get_max_temperature();
1997 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
2001 if (traits.get_supports_current_temperature()) {
2003 if (!std::isnan(current))
2004 root[ESPHOME_F(
"current_temperature")] = current;
2007 if (traits.get_supports_two_point_target_temperature()) {
2010 if (!std::isnan(low))
2011 root[ESPHOME_F(
"target_temperature_low")] = low;
2012 if (!std::isnan(high))
2013 root[ESPHOME_F(
"target_temperature_high")] = high;
2016 if (!std::isnan(target))
2017 root[ESPHOME_F(
"target_temperature")] = target;
2020 if (traits.get_supports_away_mode()) {
2021 root[ESPHOME_F(
"away")] = obj->
is_away();
2025 root[ESPHOME_F(
"is_on")] = obj->
is_on();
2036 if (!entity_match.matched)
2039 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2040 auto detail = get_request_detail(request);
2041 auto data = this->infrared_json_(obj, detail);
2042 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
2051 if (!obj->has_transmitter()) {
2052 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2062 if (value.has_value()) {
2063 call.set_carrier_frequency(*value);
2070 if (value.has_value()) {
2071 call.set_repeat_count(*value);
2077 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2081 if (data_arg.length() == 0) {
2082 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2090 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2091 call.set_raw_timings_base64url(encoded);
2108 JsonObject root = builder.
root();
2110 set_json_icon_state_value(root, obj,
"infrared",
"", 0, start_config);
2115 root[ESPHOME_F(
"supports_receiver")] = traits.get_supports_receiver();
2125#ifdef USE_RADIO_FREQUENCY
2129 if (!entity_match.matched)
2132 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2133 auto detail = get_request_detail(request);
2134 auto data = this->radio_frequency_json_(obj, detail);
2135 request->send(200, ESPHOME_F(
"application/json"), data.c_str());
2145 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2154 if (value.has_value()) {
2155 call.set_frequency(*value);
2162 if (value.has_value()) {
2163 call.set_repeat_count(*value);
2169 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2173 if (data_arg.length() == 0) {
2174 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2182 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2183 call.set_raw_timings_base64url(encoded);
2201 JsonObject root = builder.
root();
2203 set_json_icon_state_value(root, obj,
"radio_frequency",
"", 0, start_config);
2210 if (traits.get_frequency_min_hz() != 0) {
2211 root[ESPHOME_F(
"frequency_min")] = traits.get_frequency_min_hz();
2212 root[ESPHOME_F(
"frequency_max")] = traits.get_frequency_max_hz();
2233 if (!entity_match.matched)
2237 if (entity_match.action_is_empty) {
2238 auto detail = get_request_detail(request);
2239 auto data = this->event_json_(obj,
StringRef(), detail);
2240 request->send(200,
"application/json", data.c_str());
2251 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
2256 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
2260 JsonObject root = builder.
root();
2262 set_json_id(root, obj,
"event", start_config);
2263 if (!event_type.
empty()) {
2264 root[ESPHOME_F(
"event_type")] = event_type;
2267 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2269 event_types.add(event_type);
2271 char dc_buf[MAX_DEVICE_CLASS_LENGTH];
2288 if (!entity_match.matched)
2291 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2292 auto detail = get_request_detail(request);
2293 auto data = this->update_json_(obj, detail);
2294 request->send(200,
"application/json", data.c_str());
2303 DEFER_ACTION(obj, obj->perform());
2320 JsonObject root = builder.
root();
2328 constexpr size_t max_summary_len = 256;
2343 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2344 StringRef url = request->url_to(url_buf);
2346 const auto &url = request->url();
2348 const auto method = request->method();
2351 if (url == ESPHOME_F(
"/"))
2353#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2354 if (url == ESPHOME_F(
"/events"))
2357#ifdef USE_WEBSERVER_CSS_INCLUDE
2358 if (url == ESPHOME_F(
"/0.css"))
2361#ifdef USE_WEBSERVER_JS_INCLUDE
2362 if (url == ESPHOME_F(
"/0.js"))
2366#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2367 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2377 bool is_get = method == HTTP_GET;
2378 bool is_post = method == HTTP_POST;
2379 bool is_get_or_post = is_get || is_post;
2381 if (!is_get_or_post)
2390#ifdef USE_BINARY_SENSOR
2394#ifdef USE_TEXT_SENSOR
2405 if (is_get_or_post) {
2430#ifdef USE_DATETIME_DATE
2434#ifdef USE_DATETIME_TIME
2438#ifdef USE_DATETIME_DATETIME
2462#ifdef USE_ALARM_CONTROL_PANEL
2470#ifdef USE_WATER_HEATER
2478#ifdef USE_RADIO_FREQUENCY
2488 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2489 StringRef url = request->url_to(url_buf);
2491 const auto &url = request->url();
2495 if (url == ESPHOME_F(
"/")) {
2500#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2503 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2515#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2516 if (url == ESPHOME_F(
"/events")) {
2517 this->
events_.add_new_client(
this, request);
2522#ifdef USE_WEBSERVER_CSS_INCLUDE
2523 if (url == ESPHOME_F(
"/0.css")) {
2529#ifdef USE_WEBSERVER_JS_INCLUDE
2530 if (url == ESPHOME_F(
"/0.js")) {
2538 UrlMatch match = match_url(url.
c_str(), url.
length(),
false, request->method() == HTTP_POST);
2559#ifdef USE_BINARY_SENSOR
2574#ifdef USE_TEXT_SENSOR
2589#ifdef USE_DATETIME_DATE
2594#ifdef USE_DATETIME_TIME
2599#ifdef USE_DATETIME_DATETIME
2629#ifdef USE_ALARM_CONTROL_PANEL
2630 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2639#ifdef USE_WATER_HEATER
2649#ifdef USE_RADIO_FREQUENCY
2650 else if (match.
domain_equals(ESPHOME_F(
"radio_frequency"))) {
2656 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.
c_str());
2657 request->send(404, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Not Found"));
2664#ifdef USE_WEBSERVER_SORTING
2667 if (this->
sorting_groups_.contains(this->sorting_entitys_[entity].group_id)) {
2674#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.
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
void disable_loop()
Disable this component's loop.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
void begin(bool include_internal=false)
static void register_controller(Controller *controller)
Register a controller to receive entity state updates.
const char * get_device_class_to(std::span< char, MAX_DEVICE_CLASS_LENGTH > buffer) const
const StringRef & get_name() const
ESPDEPRECATED("Use get_unit_of_measurement_ref() instead for better performance (avoids string copy). Will be " "removed in ESPHome 2026.9.0", "2026.3.0") std const char * get_icon_to(std::span< char, MAX_ICON_LENGTH > buffer) const
Get the unit of measurement as std::string (deprecated, prefer get_unit_of_measurement_ref())
size_t write_object_id_to(char *buf, size_t buf_size) const
Write object_id directly to buffer, returns length written (excluding null) Useful for building compo...
bool is_disabled_by_default() const
ESPDEPRECATED("Use get_device_class_to() instead. Will be removed in ESPHome 2026.9.0", "2026.3.0") std StringRef get_unit_of_measurement_ref() const
Device * get_device() const
EntityCategory get_entity_category() const
StringRef 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
AlarmControlPanelCall & arm_night()
AlarmControlPanelCall & disarm()
AlarmControlPanelCall & arm_away()
AlarmControlPanelCall & arm_home()
AlarmControlPanelCall & arm_vacation()
AlarmControlPanelCall make_call()
Make a AlarmControlPanelCall.
Base class for all binary_sensor-type classes.
This class is used to encode all control actions on a climate device.
ClimateDevice - This is the base class for all climate integrations.
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
float target_temperature
The target temperature of the climate device.
float current_humidity
The current humidity of the climate device, as reported from the integration.
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
bool has_custom_preset() const
Check if a custom preset is currently active.
float current_temperature
The current temperature of the climate device, as reported from the integration.
ClimateAction action
The active state of the climate device.
StringRef get_custom_preset() const
Get the active custom preset (read-only access). Returns StringRef.
bool has_custom_fan_mode() const
Check if a custom fan mode is currently active.
optional< ClimatePreset > preset
The active preset of the climate device.
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
StringRef get_custom_fan_mode() const
Get the active custom fan mode (read-only access). Returns StringRef.
int8_t get_target_temperature_accuracy_decimals() const
CoverCall & set_command_toggle()
Set the command to toggle the cover.
CoverCall & set_command_open()
Set the command to open the cover.
CoverCall & set_command_close()
Set the command to close the cover.
CoverCall & set_command_stop()
Set the command to stop the cover.
Base class for all cover devices.
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
CoverCall make_call()
Construct a new cover call used to control the cover.
float tilt
The current tilt value of the cover from 0.0 to 1.0.
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
bool is_fully_closed() const
Helper method to check if the cover is fully closed. Equivalent to comparing .position against 0....
virtual CoverTraits get_traits()=0
bool get_supports_position() const
bool get_supports_tilt() const
const FixedVector< const char * > & get_event_types() const
Return the event types supported by this event.
virtual FanTraits get_traits()=0
bool oscillating
The current oscillation state of the fan.
bool state
The current on/off state of the fan.
int speed
The current fan speed level.
bool supports_oscillation() const
Return if this fan supports oscillation.
Infrared - Base class for infrared remote control implementations.
InfraredCall make_call()
Create a call object for transmitting.
InfraredTraits & get_traits()
Get the traits for this infrared implementation.
uint32_t get_capability_flags() const
Get capability flags for this infrared instance.
bool get_supports_transmitter() const
Builder class for creating JSON documents without lambdas.
SerializationBuffer serialize()
Serialize the JSON document to a SerializationBuffer (stack-first allocation) Uses 512-byte stack buf...
Buffer for JSON serialization that uses stack allocation for small payloads.
This class represents a requested change in a light state.
bool is_on() const
Get the binary true/false state of these light color values.
static void dump_json(LightState &state, JsonObject root)
Dump the state of a light as JSON.
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
LightColorValues remote_values
The remote color values reported to the frontend.
const FixedVector< LightEffect * > & get_effects() const
Get all effects for this light state.
Base class for all locks.
LockCall make_call()
Make a lock device control call, this is used to control the lock device, see the LockCall descriptio...
void lock()
Turn this lock on.
LockState state
The current reported state of the lock.
void unlock()
Turn this lock off.
void open()
Open (unlatch) this lock.
void add_log_callback(void *instance, void(*fn)(void *, uint8_t, const char *, const char *, size_t))
Register a log callback to receive log messages.
Base-class for all numbers.
float get_min_value() const
float get_max_value() const
NumberMode get_mode() const
RadioFrequency - Base class for radio frequency implementations.
uint32_t get_capability_flags() const
Get capability flags for this radio frequency instance.
RadioFrequencyTraits & get_traits()
Get the traits for this radio frequency implementation.
Base-class for all selects.
SelectCall make_call()
Instantiate a SelectCall object to modify this select component's state.
const FixedVector< const char * > & get_options() const
Base-class for all sensors.
float state
This member variable stores the last state that has passed through all filters.
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Base class for all switches.
void toggle()
Toggle this switch.
void turn_on()
Turn this switch on.
void turn_off()
Turn this switch off.
bool state
The current reported state of the binary sensor.
virtual bool assumed_state()
Return whether this switch uses an assumed state - i.e.
Base-class for all text inputs.
TextCall make_call()
Instantiate a TextCall object to modify this text component's state.
TextMode get_mode() const
int get_max_length() const
int get_min_length() const
const char * get_pattern_c_str() const
const UpdateState & state
const UpdateInfo & update_info
ValveCall & set_command_close()
Set the command to close the valve.
ValveCall & set_command_toggle()
Set the command to toggle the valve.
ValveCall & set_command_stop()
Set the command to stop the valve.
ValveCall & set_command_open()
Set the command to open the valve.
Base class for all valve devices.
bool is_fully_closed() const
Helper method to check if the valve is fully closed. Equivalent to comparing .position against 0....
float position
The position of the valve from 0.0 (fully closed) to 1.0 (fully open).
ValveCall make_call()
Construct a new valve call used to control the valve.
ValveOperation current_operation
The current operation of the valve (idle, opening, closing).
virtual ValveTraits get_traits()=0
bool get_supports_position() const
WaterHeaterCall & set_away(bool away)
WaterHeaterCall & set_target_temperature_high(float temperature)
WaterHeaterCall & set_mode(WaterHeaterMode mode)
WaterHeaterCall & set_target_temperature_low(float temperature)
WaterHeaterCall & set_on(bool on)
WaterHeaterCall & set_target_temperature(float temperature)
float get_target_temperature_low() const
float get_target_temperature() const
bool is_on() const
Check if the water heater is on.
float get_current_temperature() const
bool is_away() const
Check if away mode is currently active.
virtual WaterHeaterCallInternal make_call()=0
WaterHeaterMode get_mode() const
virtual WaterHeaterTraits get_traits()
float get_target_temperature_high() const
void process_deferred_queue_()
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 try_send_nodefer(const char *message, size_t message_len, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
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 try_send_nodefer(const char *message, size_t message_len, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
void add_new_client(WebServer *ws, AsyncWebServerRequest *request)
void deferrable_send_state(void *source, const char *event_type, message_generator_t *message_generator)
void on_client_disconnect_(DeferredUpdateEventSource *source)
bool loop()
Returns true if there are event sources remaining (including pending cleanup).
This class allows users to create a web server with their ESP nodes.
void setup() override
Setup the internal web server and register handlers.
void on_update(update::UpdateEntity *obj) override
static json::SerializationBuffer radio_frequency_all_json_generator(WebServer *web_server, void *source)
void on_water_heater_update(water_heater::WaterHeater *obj) override
json::SerializationBuffer get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static json::SerializationBuffer text_state_json_generator(WebServer *web_server, void *source)
void on_text_update(text::Text *obj) override
void on_light_update(light::LightState *obj) override
static json::SerializationBuffer datetime_state_json_generator(WebServer *web_server, void *source)
void on_cover_update(cover::Cover *obj) override
static json::SerializationBuffer lock_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer alarm_control_panel_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer text_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer switch_all_json_generator(WebServer *web_server, void *source)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)
static json::SerializationBuffer event_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer update_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer text_sensor_all_json_generator(WebServer *web_server, void *source)
void handle_water_heater_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a water_heater request under '/water_heater/<id>/<mode/set>'.
bool isRequestHandlerTrivial() const override
This web handle is not trivial.
static json::SerializationBuffer cover_all_json_generator(WebServer *web_server, void *source)
WebServer(web_server_base::WebServerBase *base)
void handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a switch request under '/switch/<id>/</turn_on/turn_off/toggle>'.
void handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a event request under '/event<id>'.
void parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
void dump_config() override
static json::SerializationBuffer datetime_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer light_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer climate_state_json_generator(WebServer *web_server, void *source)
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a button request under '/button/<id>/press'.
void on_date_update(datetime::DateEntity *obj) override
static json::SerializationBuffer date_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer sensor_state_json_generator(WebServer *web_server, void *source)
void on_number_update(number::Number *obj) override
void add_entity_config(EntityBase *entity, float weight, uint64_t group)
void handle_radio_frequency_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a radio frequency request under '/radio_frequency/<id>/transmit'.
void parse_light_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(float), float scale=1.0f)
void handle_css_request(AsyncWebServerRequest *request)
Handle included css request under '/0.css'.
static json::SerializationBuffer select_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer infrared_all_json_generator(WebServer *web_server, void *source)
void on_valve_update(valve::Valve *obj) override
void on_climate_update(climate::Climate *obj) override
void add_sorting_info_(JsonObject &root, EntityBase *entity)
void handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a light request under '/light/<id>/</turn_on/turn_off/toggle>'.
static json::SerializationBuffer sensor_all_json_generator(WebServer *web_server, void *source)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
static json::SerializationBuffer number_all_json_generator(WebServer *web_server, void *source)
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
static json::SerializationBuffer select_state_json_generator(WebServer *web_server, void *source)
void on_switch_update(switch_::Switch *obj) override
static json::SerializationBuffer water_heater_state_json_generator(WebServer *web_server, void *source)
web_server_base::WebServerBase * base_
void handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a lock request under '/lock/<id>/</lock/unlock/open>'.
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
static json::SerializationBuffer time_state_json_generator(WebServer *web_server, void *source)
void handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text sensor request under '/text_sensor/<id>'.
void parse_bool_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(bool))
bool is_request_origin_allowed_(AsyncWebServerRequest *request, const std::string &origin)
Check whether the given request Origin is permitted.
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.
FixedVector< const char * > allowed_origins_
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
static json::SerializationBuffer climate_all_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer fan_state_json_generator(WebServer *web_server, void *source)
void on_event(event::Event *obj) override
static json::SerializationBuffer cover_state_json_generator(WebServer *web_server, void *source)
void handle_pna_cors_request(AsyncWebServerRequest *request)
static json::SerializationBuffer binary_sensor_state_json_generator(WebServer *web_server, void *source)
void on_fan_update(fan::Fan *obj) override
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
static json::SerializationBuffer event_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer binary_sensor_all_json_generator(WebServer *web_server, void *source)
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
void on_lock_update(lock::Lock *obj) override
static json::SerializationBuffer switch_state_json_generator(WebServer *web_server, void *source)
float get_setup_priority() const override
MQTT setup priority.
void on_select_update(select::Select *obj) override
void on_time_update(datetime::TimeEntity *obj) override
void parse_num_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(NumT))
static json::SerializationBuffer text_sensor_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer number_state_json_generator(WebServer *web_server, void *source)
static json::SerializationBuffer valve_all_json_generator(WebServer *web_server, void *source)
void handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a update request under '/update/<id>'.
static json::SerializationBuffer light_all_json_generator(WebServer *web_server, void *source)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
const char * css_include_
void handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a climate request under '/climate/<id>'.
void on_text_sensor_update(text_sensor::TextSensor *obj) override
void add_handler(AsyncWebHandler *handler)
uint16_t get_port() const
ClimateSwingMode swing_mode
struct @65::@66 __attribute__
Wake the main loop task from an ISR. ISR-safe.
const LogString * message
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_to(std::span< char, USE_ADDRESS_BUFFER_SIZE > buf)
Get the active network address for logging.
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.
const __FlashStringHelper * ProgmemStr
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 Returns EntityMatchResult with match status and whether action segment is empty.
StringRef method
Method within URL, for example "turn_on".
bool domain_equals(const char *str) const
bool method_equals(const char *str) const
const size_t ESPHOME_WEBSERVER_INDEX_HTML_SIZE
const size_t ESPHOME_WEBSERVER_CSS_INCLUDE_SIZE
const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE