15#if !defined(USE_ESP32) && defined(USE_ARDUINO)
16#include "StreamString.h"
37#ifdef USE_WATER_HEATER
44#ifdef USE_RADIO_FREQUENCY
48#ifdef USE_WEBSERVER_LOCAL
49#if USE_WEBSERVER_VERSION == 2
51#elif USE_WEBSERVER_VERSION == 3
58static const char *
const TAG =
"web_server";
61[[maybe_unused]]
static ProgmemStr json_state_str(
const LogString *s) {
return reinterpret_cast<ProgmemStr>(s); }
64[[maybe_unused]]
static void send_json(AsyncWebServerRequest *request, json::JsonBuilder &builder) {
65 auto data = builder.serialize();
66 request->send(200, ESPHOME_F(
"application/json"),
data.c_str());
75static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain,
bool is_post =
false) {
80 if (url_len < 2 || url_ptr[0] !=
'/')
83 const char *p = url_ptr + 1;
84 const char *
end = url_ptr + url_len;
87 auto next_segment = [&
end](
const char *start) ->
const char * {
88 const char *slash = (
const char *) memchr(start,
'/',
end - start);
89 return slash ? slash + 1 :
nullptr;
93 auto make_ref = [&
end](
const char *start,
const char *next_start) -> StringRef {
94 return StringRef(start, (next_start ? next_start - 1 :
end) - start);
99 const char *s2 = next_segment(s1);
105 if (only_domain || s2 >=
end) {
106 match.domain = make_ref(s1, s2);
112 const char *s3 = next_segment(s2);
113 const char *s4 = s3 ? next_segment(s3) : nullptr;
115 StringRef seg2 = make_ref(s2, s3);
116 StringRef seg3 = s3 ? make_ref(s3, s4) : StringRef();
117 StringRef seg4 = s4 ? make_ref(s4,
nullptr) : StringRef();
120 if (seg2.empty() || (s3 && seg3.empty()) || (s4 && seg4.empty()))
135 match.device_name = seg2;
147 match.device_name = seg2;
156 match.domain = make_ref(s1, s2);
167 bool entity_has_device = (entity_device !=
nullptr);
170 if (url_has_device != entity_has_device) {
179 if (this->
id == entity->
get_name()) {
180 result.matched =
true;
186#if !defined(USE_ESP32) && defined(USE_ARDUINO)
190 DeferredEvent item(source, message_generator);
198 this->deferred_queue_.push_back(item);
205 de.message_generator_(
web_server_, de.source_, builder);
207 if (this->send(
message.c_str(),
"state") != DISCARDED) {
219 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
238 if (this->
count() == 0)
246 if (source ==
nullptr)
248 if (event_type ==
nullptr)
250 if (message_generator ==
nullptr)
253 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
254 ESP_LOGE(TAG,
"Can't defer non-state event");
266 if (this->send(
message.c_str(),
"state") == DISCARDED) {
279 this->send(
message, event,
id, reconnect);
286 return !this->empty();
310 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
314 es->handleRequest(request);
320 ws->
defer([ws, source]() {
326#ifdef USE_WEBSERVER_SORTING
329 JsonObject root = builder.
root();
330 root[ESPHOME_F(
"name")] = group.second.name;
331 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
335 source->
try_send_nodefer(group_msg.c_str(), group_msg.size(),
"sorting_group");
347 this->remove(source);
360 JsonObject root = builder.
root();
365 root[ESPHOME_F(
"comment")] =
static_cast<const char *
>(comment_buffer);
366#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
367 root[ESPHOME_F(
"ota")] =
false;
369 root[ESPHOME_F(
"ota")] =
true;
372 root[ESPHOME_F(
"lang")] =
"en";
373 root[ESPHOME_F(
"uptime")] = uptime_seconds();
384 this, [](
void *self, uint8_t level,
const char *tag,
const char *
message,
size_t message_len) {
403 auto uptime = uptime_seconds();
404 size_t len = buf_append_printf(buf,
sizeof(buf), 0,
"{\"uptime\":%" PRIu32
"}", uptime);
429 char addr_buf[network::USE_ADDRESS_BUFFER_SIZE];
437#ifdef USE_WEBSERVER_LOCAL
440 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
442 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
444#ifdef USE_WEBSERVER_GZIP
445 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
447 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
449 request->send(response);
451#elif USE_WEBSERVER_VERSION >= 2
454 AsyncWebServerResponse *response =
457 AsyncWebServerResponse *response =
461 request->send(response);
467static std::string get_request_header(AsyncWebServerRequest *request,
const char *name) {
470 optional<std::string> value = request->get_header(name);
471 return value.has_value() ? std::move(*value) :
std::string();
474 const AsyncWebHeader *header = request->getHeader(name);
475 return header !=
nullptr ? std::string(header->value().c_str()) :
std::string();
486 const size_t scheme_sep = origin.find(
"://");
487 if (scheme_sep != std::string::npos) {
488 const std::string host = get_request_header(request,
"Host");
490 const size_t authority = scheme_sep + 3;
491 if (!host.empty() && origin.size() - authority == host.size() &&
492 memcmp(origin.data() + authority, host.data(), host.size()) == 0)
496#ifdef USE_WEBSERVER_ALLOWED_ORIGINS
498 for (
const char *
const *it = this->
allowed_origins_; *it !=
nullptr; it++) {
499 const char *allowed_origin = *it;
501 if (allowed_origin[0] ==
'*' && allowed_origin[1] ==
'\0')
503 if (origin == allowed_origin)
510#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
512 const std::string origin = get_request_header(request,
"Origin");
518 AsyncWebServerResponse *response = request->beginResponse(200, ESPHOME_F(
""));
520 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Origin"), origin.empty() ?
"*" : origin.c_str());
521 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
522 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().
c_str());
523 char mac_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
525 request->send(response);
529#ifdef USE_WEBSERVER_CSS_INCLUDE
532 AsyncWebServerResponse *response =
535 AsyncWebServerResponse *response =
538 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
539 request->send(response);
543#ifdef USE_WEBSERVER_JS_INCLUDE
546 AsyncWebServerResponse *response =
549 AsyncWebServerResponse *response =
552 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
553 request->send(response);
560static void set_json_id(JsonObject root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
562 size_t prefix_len = strlen(prefix);
563 size_t name_len = name.size();
567 const char *device_name = device ? device->
get_name() :
nullptr;
568 size_t device_len = device_name ? strlen(device_name) : 0;
576 static constexpr size_t ID_BUF_SIZE =
577 ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
579 static constexpr size_t ID_BUF_SIZE = ESPHOME_DOMAIN_MAX_LEN + 1 + ESPHOME_FRIENDLY_NAME_MAX_LEN + 1;
581 char id_buf[ID_BUF_SIZE];
582 memcpy(id_buf, prefix, prefix_len);
584 char *p = id_buf + prefix_len;
588 memcpy(p, device_name, device_len);
593 memcpy(p, name.c_str(), name_len);
595 root[ESPHOME_F(
"id")] =
static_cast<const char *
>(id_buf);
598 root[ESPHOME_F(
"domain")] = prefix;
600 root[ESPHOME_F(
"name")] = name.c_str();
603 root[ESPHOME_F(
"device")] = device_name;
606#ifdef USE_ENTITY_ICON
607 char icon_buf[MAX_ICON_LENGTH];
608 root[ESPHOME_F(
"icon")] = obj->
get_icon_to(icon_buf);
613 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
620static void set_json_value(JsonObject root, EntityBase *obj,
const char *prefix, T value,
JsonDetail start_config) {
621 set_json_id(root, obj, prefix, start_config);
622 root[ESPHOME_F(
"value")] = value;
625template<
typename S,
typename T>
626static void set_json_icon_state_value(JsonObject root, EntityBase *obj,
const char *prefix, S
state, T value,
628 set_json_value(root, obj, prefix, value, start_config);
629 root[ESPHOME_F(
"state")] =
state;
633[[maybe_unused]]
static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
646 if (!entity_match.matched)
649 if (entity_match.action_is_empty) {
650 auto detail = get_request_detail(request);
652 this->sensor_json_(obj, obj->state, detail, builder);
653 send_json(request, builder);
666 JsonObject root = builder.
root();
669 char buf[VALUE_ACCURACY_MAX_LEN];
670 const char *
state = std::isnan(value)
673 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
676 if (!uom_ref.empty())
677 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
682#ifdef USE_TEXT_SENSOR
691 if (!entity_match.matched)
694 if (entity_match.action_is_empty) {
695 auto detail = get_request_detail(request);
697 this->text_sensor_json_(obj, obj->
state, detail, builder);
698 send_json(request, builder);
714 JsonObject root = builder.
root();
716 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
750 if (!entity_match.matched)
753 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
754 auto detail = get_request_detail(request);
756 this->switch_json_(obj, obj->
state, detail, builder);
757 send_json(request, builder);
772 this->
defer([obj, action]() { execute_switch_action(obj, action); });
788 JsonObject root = builder.
root();
790 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
802 if (!entity_match.matched)
804 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
805 auto detail = get_request_detail(request);
807 this->button_json_(obj, detail, builder);
808 send_json(request, builder);
810 DEFER_ACTION(obj, obj->press());
824 JsonObject root = builder.
root();
826 set_json_id(root, obj,
"button", start_config);
833#ifdef USE_BINARY_SENSOR
842 if (!entity_match.matched)
845 if (entity_match.action_is_empty) {
846 auto detail = get_request_detail(request);
848 this->binary_sensor_json_(obj, obj->state, detail, builder);
849 send_json(request, builder);
865 JsonObject root = builder.
root();
867 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
883 if (!entity_match.matched)
886 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
887 auto detail = get_request_detail(request);
889 this->fan_json_(obj, detail, builder);
890 send_json(request, builder);
892 DEFER_ACTION(obj, obj->toggle().perform());
897 if (!is_on && !is_off) {
901 auto call = is_on ? obj->turn_on() : obj->turn_off();
905 if (request->hasArg(ESPHOME_F(
"oscillation"))) {
906 auto speed = request->arg(ESPHOME_F(
"oscillation"));
910 call.set_oscillating(
true);
913 call.set_oscillating(
false);
916 call.set_oscillating(!obj->oscillating);
937 JsonObject root = builder.
root();
939 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
941 if (traits.supports_speed()) {
942 root[ESPHOME_F(
"speed_level")] = obj->
speed;
943 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
962 if (!entity_match.matched)
965 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
966 auto detail = get_request_detail(request);
968 this->light_json_(obj, detail, builder);
969 send_json(request, builder);
976 if (!is_on && !is_off) {
998 request, ESPHOME_F(
"effect"),
call,
1002 DEFER_ACTION(
call,
call.perform());
1016 JsonObject root = builder.
root();
1022 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
1025 opt.add(option->get_name());
1041 if (!entity_match.matched)
1044 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1045 auto detail = get_request_detail(request);
1047 this->cover_json_(obj, detail, builder);
1048 send_json(request, builder);
1055 static const struct {
1066 for (
const auto &method : METHODS) {
1068 (
call.*method.action)();
1080 if ((request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) ||
1081 (request->hasArg(ESPHOME_F(
"tilt")) && !traits.get_supports_tilt())) {
1089 DEFER_ACTION(
call,
call.perform());
1102 JsonObject root = builder.
root();
1109 root[ESPHOME_F(
"position")] = obj->
position;
1111 root[ESPHOME_F(
"tilt")] = obj->
tilt;
1126 for (
auto *obj :
App.get_numbers()) {
1128 if (!entity_match.matched)
1131 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1132 auto detail = get_request_detail(request);
1134 this->number_json_(obj, obj->state, detail, builder);
1135 send_json(request, builder);
1146 DEFER_ACTION(
call,
call.perform());
1160 JsonObject root = builder.
root();
1166 char val_buf[VALUE_ACCURACY_MAX_LEN];
1167 char state_buf[VALUE_ACCURACY_MAX_LEN];
1168 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
1169 const char *state_str =
1171 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
1178 if (!uom_ref.empty())
1179 root[ESPHOME_F(
"uom")] = uom_ref.c_str();
1185#ifdef USE_DATETIME_DATE
1192 for (
auto *obj :
App.get_dates()) {
1194 if (!entity_match.matched)
1196 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1197 auto detail = get_request_detail(request);
1199 this->date_json_(obj, detail, builder);
1200 send_json(request, builder);
1210 const auto &value = request->arg(ESPHOME_F(
"value"));
1212 if (value.length() == 0) {
1216 call.set_date(value.c_str(), value.length());
1218 DEFER_ACTION(
call,
call.perform());
1232 JsonObject root = builder.
root();
1236 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1237 set_json_icon_state_value<const char *, const char *>(root, obj,
"date", value, value, start_config);
1244#ifdef USE_DATETIME_TIME
1251 for (
auto *obj :
App.get_times()) {
1253 if (!entity_match.matched)
1255 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1256 auto detail = get_request_detail(request);
1258 this->time_json_(obj, detail, builder);
1259 send_json(request, builder);
1269 const auto &value = request->arg(ESPHOME_F(
"value"));
1271 if (value.length() == 0) {
1275 call.set_time(value.c_str(), value.length());
1277 DEFER_ACTION(
call,
call.perform());
1290 JsonObject root = builder.
root();
1294 buf_append_printf(value,
sizeof(value), 0,
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1295 set_json_icon_state_value<const char *, const char *>(root, obj,
"time", value, value, start_config);
1302#ifdef USE_DATETIME_DATETIME
1309 for (
auto *obj :
App.get_datetimes()) {
1311 if (!entity_match.matched)
1313 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1314 auto detail = get_request_detail(request);
1316 this->datetime_json_(obj, detail, builder);
1317 send_json(request, builder);
1327 const auto &value = request->arg(ESPHOME_F(
"value"));
1329 if (value.length() == 0) {
1333 call.set_datetime(value.c_str(), value.length());
1335 DEFER_ACTION(
call,
call.perform());
1348 JsonObject root = builder.
root();
1352 buf_append_printf(value,
sizeof(value), 0,
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour,
1354 set_json_icon_state_value<const char *, const char *>(root, obj,
"datetime", value, value, start_config);
1368 for (
auto *obj :
App.get_texts()) {
1370 if (!entity_match.matched)
1373 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1374 auto detail = get_request_detail(request);
1376 this->text_json_(obj, obj->state, detail, builder);
1377 send_json(request, builder);
1387 request, ESPHOME_F(
"value"),
call,
1390 DEFER_ACTION(
call,
call.perform());
1405 JsonObject root = builder.
root();
1410 set_json_icon_state_value(root, obj,
"text", password ?
"********" : value.c_str(), password ?
"" : value.c_str(),
1429 for (
auto *obj :
App.get_selects()) {
1431 if (!entity_match.matched)
1434 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1435 auto detail = get_request_detail(request);
1437 this->select_json_(obj, obj->
has_state() ? obj->current_option() :
StringRef(), detail, builder);
1438 send_json(request, builder);
1449 request, ESPHOME_F(
"option"),
call,
1452 DEFER_ACTION(
call,
call.perform());
1468 JsonObject root = builder.
root();
1471 set_json_icon_state_value(root, obj,
"select", value.
c_str(), value.
c_str(), start_config);
1473 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1489 for (
auto *obj :
App.get_climates()) {
1491 if (!entity_match.matched)
1494 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1495 auto detail = get_request_detail(request);
1497 this->climate_json_(obj, detail, builder);
1498 send_json(request, builder);
1511 request, ESPHOME_F(
"mode"),
call,
1515 &
decltype(
call)::set_fan_mode));
1518 &
decltype(
call)::set_swing_mode));
1521 &
decltype(
call)::set_preset));
1525 using ClimateCall =
decltype(
call);
1527 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_high));
1529 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature_low));
1531 static_cast<ClimateCall &(ClimateCall::*) (
float)
>(&ClimateCall::set_target_temperature));
1533 DEFER_ACTION(
call,
call.perform());
1549 JsonObject root = builder.
root();
1550 set_json_id(root, obj,
"climate", start_config);
1553 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1554 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1557 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1560 if (traits.get_supports_fan_modes()) {
1561 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1566 if (!traits.get_supported_custom_fan_modes().empty()) {
1567 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1568 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1571 if (traits.get_supports_swing_modes()) {
1572 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1573 for (
auto swing_mode : traits.get_supported_swing_modes())
1576 if (traits.get_supports_presets()) {
1577 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1581 if (!traits.get_supported_custom_presets().empty()) {
1582 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1583 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1586 root[ESPHOME_F(
"max_temp")] =
1588 root[ESPHOME_F(
"min_temp")] =
1590 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1591 root[ESPHOME_F(
"temperature_unit")] =
static_cast<uint8_t
>(traits.get_temperature_unit());
1595 bool has_state =
false;
1599 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1602 if (traits.get_supports_fan_modes() && obj->
fan_mode.has_value()) {
1608 if (traits.get_supports_presets() && obj->
preset.has_value()) {
1611 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1614 if (traits.get_supports_swing_modes()) {
1618 root[ESPHOME_F(
"current_temperature")] =
1630 root[ESPHOME_F(
"target_temperature_low")] =
1632 root[ESPHOME_F(
"target_temperature_high")] =
1635 root[ESPHOME_F(
"state")] =
1641 root[ESPHOME_F(
"target_temperature")] =
1644 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1678 if (!entity_match.matched)
1681 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1682 auto detail = get_request_detail(request);
1684 this->lock_json_(obj, obj->
state, detail, builder);
1685 send_json(request, builder);
1700 this->
defer([obj, action]() { execute_lock_action(obj, action); });
1717 JsonObject root = builder.
root();
1735 if (!entity_match.matched)
1738 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1739 auto detail = get_request_detail(request);
1741 this->valve_json_(obj, detail, builder);
1742 send_json(request, builder);
1749 static const struct {
1760 for (
const auto &method : METHODS) {
1762 (
call.*method.action)();
1773 auto traits = obj->get_traits();
1774 if (request->hasArg(ESPHOME_F(
"position")) && !traits.get_supports_position()) {
1781 DEFER_ACTION(
call,
call.perform());
1794 JsonObject root = builder.
root();
1801 root[ESPHOME_F(
"position")] = obj->
position;
1808#ifdef USE_ALARM_CONTROL_PANEL
1817 if (!entity_match.matched)
1820 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1821 auto detail = get_request_detail(request);
1823 this->alarm_control_panel_json_(obj, obj->get_state(), detail, builder);
1824 send_json(request, builder);
1830 request, ESPHOME_F(
"code"),
call,
1835 static const struct {
1847 for (
const auto &method : METHODS) {
1849 (
call.*method.action)();
1860 DEFER_ACTION(
call,
call.perform());
1881 JsonObject root = builder.
root();
1883 set_json_icon_state_value(root, obj,
"alarm_control_panel",
1884 json_state_str(alarm_control_panel_state_to_string(value)), value, start_config);
1891#ifdef USE_WATER_HEATER
1900 if (!entity_match.matched)
1903 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
1904 auto detail = get_request_detail(request);
1906 this->water_heater_json_(obj, detail, builder);
1907 send_json(request, builder);
1920 request, ESPHOME_F(
"mode"), base_call,
1938 DEFER_ACTION(
call,
call.perform());
1954 JsonObject root = builder.
root();
1959 set_json_icon_state_value(root, obj,
"water_heater", mode_s,
mode, start_config);
1964 JsonArray modes = root[ESPHOME_F(
"modes")].to<JsonArray>();
1965 for (
auto m : traits.get_supported_modes())
1967 root[ESPHOME_F(
"min_temp")] = traits.get_min_temperature();
1968 root[ESPHOME_F(
"max_temp")] = traits.get_max_temperature();
1969 root[ESPHOME_F(
"step")] = traits.get_target_temperature_step();
1970 root[ESPHOME_F(
"temperature_unit")] =
static_cast<uint8_t
>(traits.get_temperature_unit());
1974 if (traits.get_supports_current_temperature()) {
1976 if (!std::isnan(current))
1977 root[ESPHOME_F(
"current_temperature")] = current;
1980 if (traits.get_supports_two_point_target_temperature()) {
1983 if (!std::isnan(low))
1984 root[ESPHOME_F(
"target_temperature_low")] = low;
1985 if (!std::isnan(high))
1986 root[ESPHOME_F(
"target_temperature_high")] = high;
1989 if (!std::isnan(target))
1990 root[ESPHOME_F(
"target_temperature")] = target;
1993 if (traits.get_supports_away_mode()) {
1994 root[ESPHOME_F(
"away")] = obj->
is_away();
1998 root[ESPHOME_F(
"is_on")] = obj->
is_on();
2007 if (!entity_match.matched)
2010 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2011 auto detail = get_request_detail(request);
2013 this->infrared_json_(obj, detail, builder);
2014 send_json(request, builder);
2023 if (!obj->has_transmitter()) {
2024 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2034 if (value.has_value()) {
2035 call.set_carrier_frequency(*value);
2042 if (value.has_value()) {
2043 call.set_repeat_count(*value);
2049 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2053 if (data_arg.length() == 0) {
2054 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2062 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2063 call.set_raw_timings_base64url(encoded);
2079 JsonObject root = builder.
root();
2081 set_json_icon_state_value(root, obj,
"infrared",
"", 0, start_config);
2092#ifdef USE_RADIO_FREQUENCY
2096 if (!entity_match.matched)
2099 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2100 auto detail = get_request_detail(request);
2102 this->radio_frequency_json_(obj, detail, builder);
2103 send_json(request, builder);
2113 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Device does not support transmission"));
2122 if (value.has_value()) {
2123 call.set_frequency(*value);
2130 if (value.has_value()) {
2131 call.set_repeat_count(*value);
2137 const auto &data_arg = request->arg(ESPHOME_F(
"data"));
2141 if (data_arg.length() == 0) {
2142 request->send(400, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Missing or empty 'data' parameter"));
2150 this->
defer([
call, encoded = std::string(data_arg.c_str(), data_arg.length())]()
mutable {
2151 call.set_raw_timings_base64url(encoded);
2168 JsonObject root = builder.
root();
2170 set_json_icon_state_value(root, obj,
"radio_frequency",
"", 0, start_config);
2175 root[ESPHOME_F(
"supports_transmitter")] = bool(caps & radio_frequency::CAPABILITY_TRANSMITTER);
2176 root[ESPHOME_F(
"supports_receiver")] = bool(caps & radio_frequency::CAPABILITY_RECEIVER);
2177 if (traits.get_frequency_min_hz() != 0) {
2178 root[ESPHOME_F(
"frequency_min")] = traits.get_frequency_min_hz();
2179 root[ESPHOME_F(
"frequency_max")] = traits.get_frequency_max_hz();
2198 if (!entity_match.matched)
2202 if (entity_match.action_is_empty) {
2203 auto detail = get_request_detail(request);
2205 this->event_json_(obj,
StringRef(), detail, builder);
2206 send_json(request, builder);
2217 web_server->event_json_(event, get_event_type(event),
DETAIL_STATE, builder);
2222 web_server->event_json_(event, get_event_type(event),
DETAIL_ALL, builder);
2226 JsonObject root = builder.
root();
2228 set_json_id(root, obj,
"event", start_config);
2229 if (!event_type.
empty()) {
2230 root[ESPHOME_F(
"event_type")] = event_type;
2233 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
2235 event_types.add(event_type);
2237 char dc_buf[MAX_DEVICE_CLASS_LENGTH];
2252 if (!entity_match.matched)
2255 if (request->method() == HTTP_GET && entity_match.action_is_empty) {
2256 auto detail = get_request_detail(request);
2258 this->update_json_(obj, detail, builder);
2259 send_json(request, builder);
2268 DEFER_ACTION(obj, obj->perform());
2284 JsonObject root = builder.
root();
2292 constexpr size_t max_summary_len = 256;
2306 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2307 StringRef url = request->url_to(url_buf);
2309 const auto &url = request->url();
2311 const auto method = request->method();
2314 if (url == ESPHOME_F(
"/"))
2316#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2317 if (url == ESPHOME_F(
"/events"))
2320#ifdef USE_WEBSERVER_CSS_INCLUDE
2321 if (url == ESPHOME_F(
"/0.css"))
2324#ifdef USE_WEBSERVER_JS_INCLUDE
2325 if (url == ESPHOME_F(
"/0.js"))
2329#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2330 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
2340 bool is_get = method == HTTP_GET;
2341 bool is_post = method == HTTP_POST;
2342 bool is_get_or_post = is_get || is_post;
2344 if (!is_get_or_post)
2353#ifdef USE_BINARY_SENSOR
2357#ifdef USE_TEXT_SENSOR
2368 if (is_get_or_post) {
2393#ifdef USE_DATETIME_DATE
2397#ifdef USE_DATETIME_TIME
2401#ifdef USE_DATETIME_DATETIME
2425#ifdef USE_ALARM_CONTROL_PANEL
2433#ifdef USE_WATER_HEATER
2441#ifdef USE_RADIO_FREQUENCY
2451 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
2452 StringRef url = request->url_to(url_buf);
2454 const auto &url = request->url();
2458 if (url == ESPHOME_F(
"/")) {
2463#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
2466 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
2478#if !defined(USE_ESP32) && defined(USE_ARDUINO)
2479 if (url == ESPHOME_F(
"/events")) {
2480 this->
events_.add_new_client(
this, request);
2485#ifdef USE_WEBSERVER_CSS_INCLUDE
2486 if (url == ESPHOME_F(
"/0.css")) {
2492#ifdef USE_WEBSERVER_JS_INCLUDE
2493 if (url == ESPHOME_F(
"/0.js")) {
2501 UrlMatch match = match_url(url.
c_str(), url.
length(),
false, request->method() == HTTP_POST);
2522#ifdef USE_BINARY_SENSOR
2537#ifdef USE_TEXT_SENSOR
2552#ifdef USE_DATETIME_DATE
2557#ifdef USE_DATETIME_TIME
2562#ifdef USE_DATETIME_DATETIME
2592#ifdef USE_ALARM_CONTROL_PANEL
2593 else if (match.
domain_equals(ESPHOME_F(
"alarm_control_panel"))) {
2602#ifdef USE_WATER_HEATER
2612#ifdef USE_RADIO_FREQUENCY
2613 else if (match.
domain_equals(ESPHOME_F(
"radio_frequency"))) {
2619 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.
c_str());
2620 request->send(404, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Not Found"));
2627#ifdef USE_WEBSERVER_SORTING
2630 if (this->
sorting_groups_.contains(this->sorting_entitys_[entity].group_id)) {
2637#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)
ESPHOME_ALWAYS_INLINE void try_advance(size_t max_steps)
Run up to max_steps iteration steps; stops early when iteration completes or a callback refuses (that...
const char * get_device_class_to(std::span< char, MAX_DEVICE_CLASS_LENGTH > buffer) const
const StringRef & get_name() const
const char * get_icon_to(std::span< char, MAX_ICON_LENGTH > buffer) const
bool is_disabled_by_default() const
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_is_assumed_state() 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.
uint32_t get_capability_flags() const
Capability flags as reported to the API and web server.
bool get_supports_transmitter() const
What the entity can do; platforms with their own hardware set these from their own setup(),...
bool get_supports_receiver() 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...
const LightColorValues & get_reported_values() const
The values reported to the frontend: current_values while a light publishes intermediate states on an...
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.
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 SelectOptions & 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.
static void alarm_control_panel_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void setup() override
Setup the internal web server and register handlers.
static void text_sensor_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
json::SerializationBuffer get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static void light_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_light_update(light::LightState *obj)
static void date_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_text_sensor_update(text_sensor::TextSensor *obj)
void on_lock_update(lock::Lock *obj)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
void on_date_update(datetime::DateEntity *obj)
static void event_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)
static void cover_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
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.
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>'.
static void datetime_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void parse_light_param_uint_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
static void sensor_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void dump_config() override
static void infrared_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void switch_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a button request under '/button/<id>/press'.
void on_update(update::UpdateEntity *obj)
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'.
static void update_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
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 void binary_sensor_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void water_heater_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void datetime_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void date_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void select_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void time_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj)
void on_cover_update(cover::Cover *obj)
static void number_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_fan_update(fan::Fan *obj)
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 void update_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
void on_climate_update(climate::Climate *obj)
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
void on_time_update(datetime::TimeEntity *obj)
static void event_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void switch_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void text_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void valve_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
web_server_base::WebServerBase * base_
void on_event(event::Event *obj)
void handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a lock request under '/lock/<id>/</lock/unlock/open>'.
void on_water_heater_update(water_heater::WaterHeater *obj)
void on_number_update(number::Number *obj)
static void fan_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text sensor request under '/text_sensor/<id>'.
static void select_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
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'.
void on_select_update(select::Select *obj)
void on_sensor_update(sensor::Sensor *obj)
static void text_sensor_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void radio_frequency_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void time_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handleRequest(AsyncWebServerRequest *request) override
Override the web handler's handleRequest method.
void handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a fan request under '/fan/<id>/</turn_on/turn_off/toggle>'.
static void button_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void parse_cstr_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(const char *, size_t))
static void alarm_control_panel_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void number_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_switch_update(switch_::Switch *obj)
static void light_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
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 void lock_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a time request under '/time/<id>'.
std::map< uint64_t, SortingGroup > sorting_groups_
static void fan_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
void on_valve_update(valve::Valve *obj)
static void water_heater_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void on_datetime_update(datetime::DateTimeEntity *obj)
void handle_pna_cors_request(AsyncWebServerRequest *request)
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj)
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
void on_text_update(text::Text *obj)
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
const char *const * allowed_origins_
float get_setup_priority() const override
MQTT setup priority.
static void text_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void sensor_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void parse_num_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call, Ret(T::*setter)(NumT))
static void climate_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a update request under '/update/<id>'.
static void lock_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
static void valve_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void cover_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void binary_sensor_all_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
static void climate_state_json_generator(WebServer *web_server, void *source, json::JsonBuilder &builder)
void handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a climate request under '/climate/<id>'.
void add_handler(AsyncWebHandler *handler)
uint16_t get_port() const
ClimateSwingMode swing_mode
struct @66::@67 __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.
std::span< const uint8_t > data
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.
constexpr size_t LOG_EVENT_MAX_LEN
void(WebServer *, void *, json::JsonBuilder &) 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.
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