13#if !defined(USE_ESP32) && defined(USE_ARDUINO)
14#include "StreamString.h"
31#ifdef USE_WEBSERVER_LOCAL
32#if USE_WEBSERVER_VERSION == 2
34#elif USE_WEBSERVER_VERSION == 3
41static const char *
const TAG =
"web_server";
44static constexpr size_t PSTR_LOCAL_SIZE = 18;
45#define PSTR_LOCAL(mode_s) ESPHOME_strncpy_P(buf, (ESPHOME_PGM_P) ((mode_s)), PSTR_LOCAL_SIZE - 1)
48static UrlMatch match_url(
const char *url_ptr,
size_t url_len,
bool only_domain) {
52 if (url_len < 2 || url_ptr[0] !=
'/') {
57 const char *start = url_ptr + 1;
58 const char *
end = url_ptr + url_len;
61 const char *domain_end = (
const char *) memchr(start,
'/',
end - start);
69 match.domain_len = domain_end - start;
77 if (domain_end + 1 >=
end) {
81 const char *id_start = domain_end + 1;
82 const char *id_end = (
const char *) memchr(id_start,
'/',
end - id_start);
87 match.id_len =
end - id_start;
93 match.id_len = id_end - id_start;
96 if (id_end + 1 <
end) {
97 match.method = id_end + 1;
98 match.method_len =
end - (id_end + 1);
104#if !defined(USE_ESP32) && defined(USE_ARDUINO)
107 DeferredEvent item(source, message_generator);
115 this->deferred_queue_.push_back(item);
122 if (this->send(
message.c_str(),
"state") != DISCARDED) {
134 ESP_LOGW(TAG,
"Closing stuck EventSource connection after %" PRIu16
" failed sends",
153 if (this->count() == 0)
161 if (source ==
nullptr)
163 if (event_type ==
nullptr)
165 if (message_generator ==
nullptr)
168 if (0 != strcmp(event_type,
"state_detail_all") && 0 != strcmp(event_type,
"state")) {
169 ESP_LOGE(TAG,
"Can't defer non-state event");
179 if (this->send(
message.c_str(),
"state") == DISCARDED) {
189 uint32_t reconnect) {
190 this->send(
message, event,
id, reconnect);
210 uint32_t reconnect) {
220 es->onConnect([
this, es](AsyncEventSourceClient *client) { this->
on_client_connect_(es); });
224 es->handleRequest(request);
229 ws->
defer([ws, source]() {
235#ifdef USE_WEBSERVER_SORTING
238 JsonObject root = builder.
root();
239 root[ESPHOME_F(
"name")] = group.second.name;
240 root[ESPHOME_F(
"sorting_weight")] = group.second.weight;
262 this->remove(source);
270#ifdef USE_WEBSERVER_CSS_INCLUDE
273#ifdef USE_WEBSERVER_JS_INCLUDE
279 JsonObject root = builder.
root();
282 char comment_buffer[ESPHOME_COMMENT_SIZE];
284 root[ESPHOME_F(
"comment")] = comment_buffer;
285#if defined(USE_WEBSERVER_OTA_DISABLED) || !defined(USE_WEBSERVER_OTA)
286 root[ESPHOME_F(
"ota")] =
false;
288 root[ESPHOME_F(
"ota")] =
true;
291 root[ESPHOME_F(
"lang")] =
"en";
336#ifdef USE_WEBSERVER_LOCAL
339 AsyncWebServerResponse *response = request->beginResponse(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
341 AsyncWebServerResponse *response = request->beginResponse_P(200,
"text/html", INDEX_GZ,
sizeof(INDEX_GZ));
343 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
344 request->send(response);
346#elif USE_WEBSERVER_VERSION >= 2
349 AsyncWebServerResponse *response =
352 AsyncWebServerResponse *response =
356 request->send(response);
360#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
362 AsyncWebServerResponse *response = request->beginResponse(200,
"");
363 response->addHeader(ESPHOME_F(
"Access-Control-Allow-Private-Network"), ESPHOME_F(
"true"));
364 response->addHeader(ESPHOME_F(
"Private-Network-Access-Name"),
App.
get_name().c_str());
367 request->send(response);
371#ifdef USE_WEBSERVER_CSS_INCLUDE
374 AsyncWebServerResponse *response =
377 AsyncWebServerResponse *response =
380 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
381 request->send(response);
385#ifdef USE_WEBSERVER_JS_INCLUDE
388 AsyncWebServerResponse *response =
391 AsyncWebServerResponse *response =
394 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
395 request->send(response);
400static void set_json_id(JsonObject &root,
EntityBase *obj,
const char *prefix,
JsonDetail start_config) {
402 size_t len = strlen(prefix);
403 memcpy(id_buf, prefix,
len);
406 root[ESPHOME_F(
"id")] = id_buf;
408 root[ESPHOME_F(
"name")] = obj->
get_name();
413 root[ESPHOME_F(
"is_disabled_by_default")] = is_disabled;
420static void set_json_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const T &value,
422 set_json_id(root, obj, prefix, start_config);
423 root[ESPHOME_F(
"value")] = value;
427static void set_json_icon_state_value(JsonObject &root, EntityBase *obj,
const char *prefix,
const char *
state,
429 set_json_value(root, obj, prefix, value, start_config);
430 root[ESPHOME_F(
"state")] =
state;
434static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
435 auto *param = request->getParam(
"detail");
451 auto detail = get_request_detail(request);
452 std::string data = this->sensor_json_(obj, obj->state, detail);
453 request->send(200,
"application/json", data.c_str());
467 JsonObject root = builder.
root();
470 char buf[VALUE_ACCURACY_MAX_LEN];
471 const char *
state = std::isnan(value)
474 set_json_icon_state_value(root, obj,
"sensor",
state, value, start_config);
477 if (!uom_ref.empty())
478 root[ESPHOME_F(
"uom")] = uom_ref;
485#ifdef USE_TEXT_SENSOR
497 auto detail = get_request_detail(request);
498 std::string data = this->text_sensor_json_(obj, obj->
state, detail);
499 request->send(200,
"application/json", data.c_str());
516 JsonObject root = builder.
root();
518 set_json_icon_state_value(root, obj,
"text_sensor", value.c_str(), value.c_str(), start_config);
538 if (request->method() == HTTP_GET && match.
method_empty()) {
539 auto detail = get_request_detail(request);
540 std::string data = this->switch_json_(obj, obj->
state, detail);
541 request->send(200,
"application/json", data.c_str());
546 enum SwitchAction { NONE, TOGGLE, TURN_ON, TURN_OFF };
547 SwitchAction action = NONE;
557 if (action != NONE) {
558 this->
defer([obj, action]() {
589 JsonObject root = builder.
root();
591 set_json_icon_state_value(root, obj,
"switch", value ?
"ON" :
"OFF", value, start_config);
606 if (request->method() == HTTP_GET && match.
method_empty()) {
607 auto detail = get_request_detail(request);
608 std::string data = this->button_json_(obj, detail);
609 request->send(200,
"application/json", data.c_str());
611 this->
defer([obj]() { obj->press(); });
629 JsonObject root = builder.
root();
631 set_json_id(root, obj,
"button", start_config);
640#ifdef USE_BINARY_SENSOR
652 auto detail = get_request_detail(request);
653 std::string data = this->binary_sensor_json_(obj, obj->state, detail);
654 request->send(200,
"application/json", data.c_str());
670 JsonObject root = builder.
root();
672 set_json_icon_state_value(root, obj,
"binary_sensor", value ?
"ON" :
"OFF", value, start_config);
692 if (request->method() == HTTP_GET && match.
method_empty()) {
693 auto detail = get_request_detail(request);
694 std::string data = this->fan_json_(obj, detail);
695 request->send(200,
"application/json", data.c_str());
697 this->
defer([obj]() { obj->toggle().perform(); });
702 if (!is_on && !is_off) {
706 auto call = is_on ? obj->turn_on() : obj->turn_off();
710 if (request->hasParam(
"oscillation")) {
711 auto speed = request->getParam(
"oscillation")->value();
715 call.set_oscillating(
true);
718 call.set_oscillating(
false);
721 call.set_oscillating(!obj->oscillating);
743 JsonObject root = builder.
root();
745 set_json_icon_state_value(root, obj,
"fan", obj->
state ?
"ON" :
"OFF", obj->
state, start_config);
747 if (traits.supports_speed()) {
748 root[ESPHOME_F(
"speed_level")] = obj->
speed;
749 root[ESPHOME_F(
"speed_count")] = traits.supported_speed_count();
772 if (request->method() == HTTP_GET && match.
method_empty()) {
773 auto detail = get_request_detail(request);
774 std::string data = this->light_json_(obj, detail);
775 request->send(200,
"application/json", data.c_str());
782 if (!is_on && !is_off) {
821 JsonObject root = builder.
root();
823 set_json_value(root, obj,
"light", obj->
remote_values.
is_on() ?
"ON" :
"OFF", start_config);
827 JsonArray opt = root[ESPHOME_F(
"effects")].to<JsonArray>();
830 opt.add(option->get_name());
850 if (request->method() == HTTP_GET && match.
method_empty()) {
851 auto detail = get_request_detail(request);
852 std::string data = this->cover_json_(obj, detail);
853 request->send(200,
"application/json", data.c_str());
860 static const struct {
871 for (
const auto &method : METHODS) {
873 (
call.*method.action)();
885 if ((request->hasParam(
"position") && !traits.get_supports_position()) ||
886 (request->hasParam(
"tilt") && !traits.get_supports_tilt())) {
908 JsonObject root = builder.
root();
912 char buf[PSTR_LOCAL_SIZE];
916 root[ESPHOME_F(
"position")] = obj->
position;
918 root[ESPHOME_F(
"tilt")] = obj->
tilt;
934 for (
auto *obj :
App.get_numbers()) {
938 if (request->method() == HTTP_GET && match.
method_empty()) {
939 auto detail = get_request_detail(request);
940 std::string data = this->number_json_(obj, obj->state, detail);
941 request->send(200,
"application/json", data.c_str());
967 JsonObject root = builder.
root();
973 char val_buf[VALUE_ACCURACY_MAX_LEN];
974 char state_buf[VALUE_ACCURACY_MAX_LEN];
975 const char *val_str = std::isnan(value) ?
"\"NaN\"" : (
value_accuracy_to_buf(val_buf, value, accuracy), val_buf);
976 const char *state_str =
978 set_json_icon_state_value(root, obj,
"number", state_str, val_str, start_config);
985 if (!uom_ref.empty())
986 root[ESPHOME_F(
"uom")] = uom_ref;
994#ifdef USE_DATETIME_DATE
1001 for (
auto *obj :
App.get_dates()) {
1004 if (request->method() == HTTP_GET && match.
method_empty()) {
1005 auto detail = get_request_detail(request);
1006 std::string data = this->date_json_(obj, detail);
1007 request->send(200,
"application/json", data.c_str());
1017 if (!request->hasParam(
"value")) {
1039 JsonObject root = builder.
root();
1044 snprintf_P(value,
sizeof(value), PSTR(
"%d-%02d-%02d"), obj->
year, obj->
month, obj->
day);
1046 snprintf(value,
sizeof(value),
"%d-%02d-%02d", obj->
year, obj->
month, obj->
day);
1048 set_json_icon_state_value(root, obj,
"date", value, value, start_config);
1057#ifdef USE_DATETIME_TIME
1064 for (
auto *obj :
App.get_times()) {
1067 if (request->method() == HTTP_GET && match.
method_empty()) {
1068 auto detail = get_request_detail(request);
1069 std::string data = this->time_json_(obj, detail);
1070 request->send(200,
"application/json", data.c_str());
1080 if (!request->hasParam(
"value")) {
1101 JsonObject root = builder.
root();
1106 snprintf_P(value,
sizeof(value), PSTR(
"%02d:%02d:%02d"), obj->
hour, obj->
minute, obj->
second);
1108 snprintf(value,
sizeof(value),
"%02d:%02d:%02d", obj->
hour, obj->
minute, obj->
second);
1110 set_json_icon_state_value(root, obj,
"time", value, value, start_config);
1119#ifdef USE_DATETIME_DATETIME
1126 for (
auto *obj :
App.get_datetimes()) {
1129 if (request->method() == HTTP_GET && match.
method_empty()) {
1130 auto detail = get_request_detail(request);
1131 std::string data = this->datetime_json_(obj, detail);
1132 request->send(200,
"application/json", data.c_str());
1142 if (!request->hasParam(
"value")) {
1163 JsonObject root = builder.
root();
1168 snprintf_P(value,
sizeof(value), PSTR(
"%d-%02d-%02d %02d:%02d:%02d"), obj->
year, obj->
month, obj->
day, obj->
hour,
1171 snprintf(value,
sizeof(value),
"%d-%02d-%02d %02d:%02d:%02d", obj->
year, obj->
month, obj->
day, obj->
hour, obj->
minute,
1174 set_json_icon_state_value(root, obj,
"datetime", value, value, start_config);
1190 for (
auto *obj :
App.get_texts()) {
1194 if (request->method() == HTTP_GET && match.
method_empty()) {
1195 auto detail = get_request_detail(request);
1196 std::string data = this->text_json_(obj, obj->state, detail);
1197 request->send(200,
"application/json", data.c_str());
1221std::string WebServer::text_json_(
text::Text *obj,
const std::string &value,
JsonDetail start_config) {
1223 JsonObject root = builder.
root();
1226 set_json_icon_state_value(root, obj,
"text",
state, value.c_str(), start_config);
1246 for (
auto *obj :
App.get_selects()) {
1250 if (request->method() == HTTP_GET && match.
method_empty()) {
1251 auto detail = get_request_detail(request);
1252 std::string data = this->select_json_(obj, obj->
has_state() ? obj->current_option() :
"", detail);
1253 request->send(200,
"application/json", data.c_str());
1277 return web_server->select_json_(obj, obj->
has_state() ? obj->current_option() :
"",
DETAIL_ALL);
1281 JsonObject root = builder.
root();
1283 set_json_icon_state_value(root, obj,
"select", value, value, start_config);
1285 JsonArray opt = root[ESPHOME_F(
"option")].to<JsonArray>();
1303 for (
auto *obj :
App.get_climates()) {
1307 if (request->method() == HTTP_GET && match.
method_empty()) {
1308 auto detail = get_request_detail(request);
1309 std::string data = this->climate_json_(obj, detail);
1310 request->send(200,
"application/json", data.c_str());
1348 JsonObject root = builder.
root();
1349 set_json_id(root, obj,
"climate", start_config);
1352 int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
1353 char buf[PSTR_LOCAL_SIZE];
1354 char temp_buf[VALUE_ACCURACY_MAX_LEN];
1357 JsonArray opt = root[ESPHOME_F(
"modes")].to<JsonArray>();
1360 if (!traits.get_supported_custom_fan_modes().empty()) {
1361 JsonArray opt = root[ESPHOME_F(
"fan_modes")].to<JsonArray>();
1366 if (!traits.get_supported_custom_fan_modes().empty()) {
1367 JsonArray opt = root[ESPHOME_F(
"custom_fan_modes")].to<JsonArray>();
1368 for (
auto const &
custom_fan_mode : traits.get_supported_custom_fan_modes())
1371 if (traits.get_supports_swing_modes()) {
1372 JsonArray opt = root[ESPHOME_F(
"swing_modes")].to<JsonArray>();
1373 for (
auto swing_mode : traits.get_supported_swing_modes())
1377 JsonArray opt = root[ESPHOME_F(
"presets")].to<JsonArray>();
1381 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1382 JsonArray opt = root[ESPHOME_F(
"custom_presets")].to<JsonArray>();
1383 for (
auto const &
custom_preset : traits.get_supported_custom_presets())
1389 bool has_state =
false;
1391 root[ESPHOME_F(
"max_temp")] =
1393 root[ESPHOME_F(
"min_temp")] =
1395 root[ESPHOME_F(
"step")] = traits.get_visual_target_temperature_step();
1398 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"action")];
1410 if (!traits.get_supported_custom_presets().empty() && obj->
has_custom_preset()) {
1413 if (traits.get_supports_swing_modes()) {
1417 root[ESPHOME_F(
"current_temperature")] =
1424 root[ESPHOME_F(
"target_temperature_low")] =
1426 root[ESPHOME_F(
"target_temperature_high")] =
1429 root[ESPHOME_F(
"state")] =
1435 root[ESPHOME_F(
"target_temperature")] =
1438 root[ESPHOME_F(
"state")] = root[ESPHOME_F(
"target_temperature")];
1457 if (request->method() == HTTP_GET && match.
method_empty()) {
1458 auto detail = get_request_detail(request);
1459 std::string data = this->lock_json_(obj, obj->state, detail);
1460 request->send(200,
"application/json", data.c_str());
1465 enum LockAction { NONE, LOCK, UNLOCK, OPEN };
1466 LockAction action = NONE;
1476 if (action != NONE) {
1477 this->
defer([obj, action]() {
1508 JsonObject root = builder.
root();
1510 char buf[PSTR_LOCAL_SIZE];
1531 if (request->method() == HTTP_GET && match.
method_empty()) {
1532 auto detail = get_request_detail(request);
1533 std::string data = this->valve_json_(obj, detail);
1534 request->send(200,
"application/json", data.c_str());
1541 static const struct {
1552 for (
const auto &method : METHODS) {
1554 (
call.*method.action)();
1565 auto traits = obj->get_traits();
1566 if (request->hasParam(
"position") && !traits.get_supports_position()) {
1587 JsonObject root = builder.
root();
1591 char buf[PSTR_LOCAL_SIZE];
1595 root[ESPHOME_F(
"position")] = obj->
position;
1604#ifdef USE_ALARM_CONTROL_PANEL
1615 if (request->method() == HTTP_GET && match.
method_empty()) {
1616 auto detail = get_request_detail(request);
1617 std::string data = this->alarm_control_panel_json_(obj, obj->get_state(), detail);
1618 request->send(200,
"application/json", data.c_str());
1626 static const struct {
1638 for (
const auto &method : METHODS) {
1640 (
call.*method.action)();
1671 JsonObject root = builder.
root();
1673 char buf[PSTR_LOCAL_SIZE];
1674 set_json_icon_state_value(root, obj,
"alarm-control-panel", PSTR_LOCAL(alarm_control_panel_state_to_string(value)),
1675 value, start_config);
1698 auto detail = get_request_detail(request);
1699 std::string data = this->event_json_(obj,
"", detail);
1700 request->send(200,
"application/json", data.c_str());
1707static std::string get_event_type(
event::Event *event) {
1708 const char *last_type =
event ?
event->get_last_event_type() :
nullptr;
1709 return last_type ? last_type :
"";
1714 return web_server->event_json_(event, get_event_type(event),
DETAIL_STATE);
1719 return web_server->event_json_(event, get_event_type(event),
DETAIL_ALL);
1721std::string WebServer::event_json_(
event::Event *obj,
const std::string &event_type,
JsonDetail start_config) {
1723 JsonObject root = builder.
root();
1725 set_json_id(root, obj,
"event", start_config);
1726 if (!event_type.empty()) {
1727 root[ESPHOME_F(
"event_type")] = event_type;
1730 JsonArray event_types = root[ESPHOME_F(
"event_types")].to<JsonArray>();
1732 event_types.add(event_type);
1747 return LOG_STR(
"NO UPDATE");
1749 return LOG_STR(
"UPDATE AVAILABLE");
1751 return LOG_STR(
"INSTALLING");
1753 return LOG_STR(
"UNKNOWN");
1765 if (request->method() == HTTP_GET && match.
method_empty()) {
1766 auto detail = get_request_detail(request);
1767 std::string data = this->update_json_(obj, detail);
1768 request->send(200,
"application/json", data.c_str());
1777 this->
defer([obj]()
mutable { obj->perform(); });
1794 JsonObject root = builder.
root();
1796 char buf[PSTR_LOCAL_SIZE];
1797 set_json_icon_state_value(root, obj,
"update", PSTR_LOCAL(update_state_to_string(obj->
state)),
1813 const auto &url = request->url();
1814 const auto method = request->method();
1817 static const char *
const STATIC_URLS[] = {
1819#if !defined(USE_ESP32) && defined(USE_ARDUINO)
1822#ifdef USE_WEBSERVER_CSS_INCLUDE
1825#ifdef USE_WEBSERVER_JS_INCLUDE
1830 for (
const auto &static_url : STATIC_URLS) {
1831 if (url == static_url)
1835#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
1836 if (method == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network")))
1841 UrlMatch match = match_url(url.c_str(), url.length(),
true);
1846 bool is_get = method == HTTP_GET;
1847 bool is_post = method == HTTP_POST;
1848 bool is_get_or_post = is_get || is_post;
1850 if (!is_get_or_post)
1854 static const char *
const GET_ONLY_DOMAINS[] = {
1858#ifdef USE_BINARY_SENSOR
1861#ifdef USE_TEXT_SENSOR
1869 static const char *
const GET_POST_DOMAINS[] = {
1888#ifdef USE_DATETIME_DATE
1891#ifdef USE_DATETIME_TIME
1894#ifdef USE_DATETIME_DATETIME
1912#ifdef USE_ALARM_CONTROL_PANEL
1913 "alarm_control_panel",
1922 for (
const auto &domain : GET_ONLY_DOMAINS) {
1929 if (is_get_or_post) {
1930 for (
const auto &domain : GET_POST_DOMAINS) {
1939 const auto &url = request->url();
1947#if !defined(USE_ESP32) && defined(USE_ARDUINO)
1948 if (url ==
"/events") {
1949 this->
events_.add_new_client(
this, request);
1954#ifdef USE_WEBSERVER_CSS_INCLUDE
1955 if (url ==
"/0.css") {
1961#ifdef USE_WEBSERVER_JS_INCLUDE
1962 if (url ==
"/0.js") {
1968#ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
1969 if (request->method() == HTTP_OPTIONS && request->hasHeader(ESPHOME_F(
"Access-Control-Request-Private-Network"))) {
1976 UrlMatch match = match_url(url.c_str(), url.length(),
false);
1997#ifdef USE_BINARY_SENSOR
2012#ifdef USE_TEXT_SENSOR
2027#ifdef USE_DATETIME_DATE
2032#ifdef USE_DATETIME_TIME
2037#ifdef USE_DATETIME_DATETIME
2067#ifdef USE_ALARM_CONTROL_PANEL
2079 ESP_LOGV(TAG,
"Request for unknown URL: %s", url.c_str());
2080 request->send(404,
"text/plain",
"Not Found");
2087#ifdef USE_WEBSERVER_SORTING
2090 if (this->
sorting_groups_.find(this->sorting_entitys_[entity].group_id) != this->sorting_groups_.end()) {
2097#ifdef USE_WEBSERVER_SORTING
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
const std::string & get_name() const
Get the name of this Application set by pre_setup().
void get_comment_string(std::span< char, ESPHOME_COMMENT_SIZE > buffer)
Copy the comment string into the provided buffer Buffer must be ESPHOME_COMMENT_SIZE bytes (compile-t...
auto & get_binary_sensors() const
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
void defer(const std::string &name, std::function< void()> &&f)
Defer a callback to the next loop() call.
void begin(bool include_internal=false)
static void register_controller(Controller *controller)
Register a controller to receive entity state updates.
StringRef get_device_class_ref() const
Get the device class as StringRef.
StringRef get_unit_of_measurement_ref() const
Get the unit of measurement as StringRef.
const StringRef & get_name() const
StringRef get_icon_ref() const
size_t write_object_id_to(char *buf, size_t buf_size) const
Write object_id directly to buffer, returns length written (excluding null) Useful for building compo...
bool is_disabled_by_default() const
EntityCategory get_entity_category() const
AlarmControlPanelCall & arm_night()
AlarmControlPanelCall & disarm()
AlarmControlPanelCall & arm_away()
AlarmControlPanelCall & arm_home()
AlarmControlPanelCall & arm_vacation()
Base class for all binary_sensor-type classes.
ClimateDevice - This is the base class for all climate integrations.
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
float target_temperature
The target temperature of the climate device.
const char * get_custom_fan_mode() const
Get the active custom fan mode (read-only access).
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...
const char * get_custom_preset() const
Get the active custom preset (read-only access).
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.
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...
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.
Builder class for creating JSON documents without lambdas.
bool is_on() const
Get the binary true/false state of these light color values.
static void dump_json(LightState &state, JsonObject root)
Dump the state of a light as JSON.
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
LightColorValues remote_values
The remote color values reported to the frontend.
const FixedVector< LightEffect * > & get_effects() const
Get all effects for this light state.
Base class for all locks.
LockCall make_call()
Make a lock device control call, this is used to control the lock device, see the LockCall descriptio...
void add_log_listener(LogListener *listener)
Register a log listener to receive log messages.
Base-class for all numbers.
float get_min_value() const
float get_max_value() const
NumberMode get_mode() const
value_type const & value() const
Base-class for all selects.
SelectCall make_call()
Instantiate a SelectCall object to modify this select component's state.
const FixedVector< const char * > & get_options() const
Base-class for all sensors.
float state
This member variable stores the last state that has passed through all filters.
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Base class for all switches.
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
void process_deferred_queue_()
void try_send_nodefer(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
static constexpr uint16_t MAX_CONSECUTIVE_SEND_FAILURES
uint16_t consecutive_send_failures_
void deq_push_back_with_dedup_(void *source, message_generator_t *message_generator)
void deferrable_send_state(void *source, const char *event_type, message_generator_t *message_generator)
ListEntitiesIterator entities_iterator_
std::vector< DeferredEvent > deferred_queue_
void on_client_connect_(DeferredUpdateEventSource *source)
void add_new_client(WebServer *ws, AsyncWebServerRequest *request)
void deferrable_send_state(void *source, const char *event_type, message_generator_t *message_generator)
void try_send_nodefer(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0)
void on_client_disconnect_(DeferredUpdateEventSource *source)
This class allows users to create a web server with their ESP nodes.
void setup() override
Setup the internal web server and register handlers.
void on_update(update::UpdateEntity *obj) override
static std::string text_sensor_all_json_generator(WebServer *web_server, void *source)
std::string get_config_json()
Return the webserver configuration as JSON.
std::map< EntityBase *, SortingComponents > sorting_entitys_
static std::string binary_sensor_state_json_generator(WebServer *web_server, void *source)
void on_text_update(text::Text *obj) override
static std::string button_state_json_generator(WebServer *web_server, void *source)
static std::string lock_all_json_generator(WebServer *web_server, void *source)
void on_light_update(light::LightState *obj) override
static std::string date_all_json_generator(WebServer *web_server, void *source)
void on_cover_update(cover::Cover *obj) override
static std::string text_state_json_generator(WebServer *web_server, void *source)
void handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a select request under '/select/<id>'.
static std::string event_state_json_generator(WebServer *web_server, void *source)
static std::string datetime_all_json_generator(WebServer *web_server, void *source)
static std::string sensor_all_json_generator(WebServer *web_server, void *source)
bool isRequestHandlerTrivial() const override
This web handle is not trivial.
WebServer(web_server_base::WebServerBase *base)
void handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a switch request under '/switch/<id>/</turn_on/turn_off/toggle>'.
void handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a event request under '/event<id>'.
void parse_light_param_uint_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret(T::*setter)(uint32_t), uint32_t scale=1)
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len) override
void dump_config() override
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a button request under '/button/<id>/press'.
void on_date_update(datetime::DateEntity *obj) override
void on_number_update(number::Number *obj) override
void add_entity_config(EntityBase *entity, float weight, uint64_t group)
void handle_css_request(AsyncWebServerRequest *request)
Handle included css request under '/0.css'.
static std::string sensor_state_json_generator(WebServer *web_server, void *source)
void on_valve_update(valve::Valve *obj) override
void on_climate_update(climate::Climate *obj) override
static std::string switch_state_json_generator(WebServer *web_server, void *source)
void add_sorting_info_(JsonObject &root, EntityBase *entity)
void handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a light request under '/light/<id>/</turn_on/turn_off/toggle>'.
static std::string event_all_json_generator(WebServer *web_server, void *source)
static std::string climate_state_json_generator(WebServer *web_server, void *source)
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
static std::string number_all_json_generator(WebServer *web_server, void *source)
void handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text input request under '/text/<id>'.
void handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a cover request under '/cover/<id>/<open/close/stop/set>'.
static std::string date_state_json_generator(WebServer *web_server, void *source)
static std::string valve_all_json_generator(WebServer *web_server, void *source)
static std::string text_all_json_generator(WebServer *web_server, void *source)
void on_switch_update(switch_::Switch *obj) override
web_server_base::WebServerBase * base_
static std::string binary_sensor_all_json_generator(WebServer *web_server, void *source)
static std::string light_state_json_generator(WebServer *web_server, void *source)
void handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a lock request under '/lock/<id>/</lock/unlock/open>'.
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
static std::string light_all_json_generator(WebServer *web_server, void *source)
void handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a text sensor request under '/text_sensor/<id>'.
void handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a date request under '/date/<id>'.
static std::string cover_all_json_generator(WebServer *web_server, void *source)
void handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a sensor request under '/sensor/<id>'.
static std::string text_sensor_state_json_generator(WebServer *web_server, void *source)
void handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a number request under '/number/<id>'.
static std::string alarm_control_panel_state_json_generator(WebServer *web_server, void *source)
void handle_index_request(AsyncWebServerRequest *request)
Handle an index request under '/'.
void handle_js_request(AsyncWebServerRequest *request)
Handle included js request under '/0.js'.
void set_js_include(const char *js_include)
Set local path to the script that's embedded in the index page.
static std::string fan_state_json_generator(WebServer *web_server, void *source)
static std::string update_state_json_generator(WebServer *web_server, void *source)
void handleRequest(AsyncWebServerRequest *request) override
Override the web handler's handleRequest method.
static std::string climate_all_json_generator(WebServer *web_server, void *source)
void on_datetime_update(datetime::DateTimeEntity *obj) override
void handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a fan request under '/fan/<id>/</turn_on/turn_off/toggle>'.
static std::string cover_state_json_generator(WebServer *web_server, void *source)
static std::string lock_state_json_generator(WebServer *web_server, void *source)
void handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a valve request under '/valve/<id>/<open/close/stop/set>'.
void handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a binary sensor request under '/binary_sensor/<id>'.
static std::string alarm_control_panel_all_json_generator(WebServer *web_server, void *source)
static std::string number_state_json_generator(WebServer *web_server, void *source)
void handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a time request under '/time/<id>'.
void on_sensor_update(sensor::Sensor *obj) override
std::map< uint64_t, SortingGroup > sorting_groups_
void set_css_include(const char *css_include)
Set local path to the script that's embedded in the index page.
static std::string valve_state_json_generator(WebServer *web_server, void *source)
bool canHandle(AsyncWebServerRequest *request) const override
Override the web handler's canHandle method.
void on_event(event::Event *obj) override
void handle_pna_cors_request(AsyncWebServerRequest *request)
void on_fan_update(fan::Fan *obj) override
void parse_light_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret(T::*setter)(float), float scale=1.0f)
void handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a datetime request under '/datetime/<id>'.
void parse_string_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret(T::*setter)(const std::string &))
void parse_float_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret(T::*setter)(float))
void handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a alarm_control_panel request under '/alarm_control_panel/<id>'.
static std::string time_state_json_generator(WebServer *web_server, void *source)
void on_lock_update(lock::Lock *obj) override
static std::string button_all_json_generator(WebServer *web_server, void *source)
static std::string select_state_json_generator(WebServer *web_server, void *source)
float get_setup_priority() const override
MQTT setup priority.
void parse_int_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret(T::*setter)(int))
void on_select_update(select::Select *obj) override
void on_time_update(datetime::TimeEntity *obj) override
static std::string update_all_json_generator(WebServer *web_server, void *source)
void handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a update request under '/update/<id>'.
static std::string fan_all_json_generator(WebServer *web_server, void *source)
static std::string switch_all_json_generator(WebServer *web_server, void *source)
static std::string time_all_json_generator(WebServer *web_server, void *source)
void add_sorting_group(uint64_t group_id, const std::string &group_name, float weight)
static std::string select_all_json_generator(WebServer *web_server, void *source)
const char * css_include_
static std::string datetime_state_json_generator(WebServer *web_server, void *source)
void handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match)
Handle a climate request under '/climate/<id>'.
void on_text_sensor_update(text_sensor::TextSensor *obj) override
void add_handler(AsyncWebHandler *handler)
uint16_t get_port() const
ClimateSwingMode swing_mode
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
@ CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_SUPPORTS_ACTION
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
ClimateMode
Enum for all modes a climate device can be in.
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
const LogString * cover_operation_to_str(CoverOperation op)
const LogString * lock_state_to_string(LockState state)
LockState
Enum for all states a lock can be in.
const char * get_use_address()
Get the active network hostname.
@ UPDATE_STATE_INSTALLING
const LogString * valve_operation_to_str(ValveOperation op)
std::string(WebServer *, void *) message_generator_t
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Parse a string that contains either on, off or toggle.
int8_t step_to_accuracy_decimals(float step)
Derive accuracy in decimals from an increment step.
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
size_t value_accuracy_with_uom_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals, StringRef unit_of_measurement)
Format value with accuracy and UOM to buffer, returns chars written (excluding null)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
std::string current_version
std::string latest_version
Internal helper struct that is used to parse incoming URLs.
const char * domain
Pointer to domain within URL, for example "sensor".
bool valid
Whether this match is valid.
bool id_equals_entity(EntityBase *entity) const
bool method_empty() const
bool domain_equals(const char *str) const
bool method_equals(const char *str) const
friend class DeferredUpdateEventSource
const size_t ESPHOME_WEBSERVER_INDEX_HTML_SIZE
const size_t ESPHOME_WEBSERVER_CSS_INCLUDE_SIZE
const size_t ESPHOME_WEBSERVER_JS_INCLUDE_SIZE