4#if USE_WEBSERVER_VERSION == 1
9static void write_html_escaped(AsyncResponseStream *stream,
const char *text) {
10 for (
const char *p = text; *p; ++p) {
13 stream->print(
""");
16 stream->print(
"&");
19 stream->print(
"<");
22 stream->print(
">");
31void write_row(AsyncResponseStream *stream, EntityBase *obj,
const std::string &klass,
const std::string &action,
32 const std::function<
void(AsyncResponseStream &stream, EntityBase *obj)> &action_func =
nullptr) {
33 stream->print(
"<tr class=\"");
34 stream->print(klass.c_str());
35 if (obj->is_internal())
36 stream->print(
" internal");
37 stream->print(
"\" id=\"");
38 stream->print(klass.c_str());
40 char object_id_buf[OBJECT_ID_MAX_LEN];
41 stream->print(obj->get_object_id_to(object_id_buf).c_str());
43 stream->print(
"\" data-domain=\"");
44 stream->print(klass.c_str());
45 stream->print(
"\" data-name=\"");
46 write_html_escaped(stream, obj->get_name().c_str());
48 Device *device = obj->get_device();
49 if (device !=
nullptr) {
50 stream->print(
"\" data-device=\"");
51 write_html_escaped(stream, device->get_name());
54 stream->print(
"\"><td>");
56 if (device !=
nullptr) {
58 write_html_escaped(stream, device->get_name());
62 write_html_escaped(stream, obj->get_name().c_str());
63 stream->print(
"</td><td></td><td>");
64 stream->print(action.c_str());
66 action_func(*stream, obj);
68 stream->print(
"</td>");
69 stream->print(
"</tr>");
73 AsyncResponseStream *stream = request->beginResponseStream(ESPHOME_F(
"text/html"));
75 stream->print(ESPHOME_F(
"<!DOCTYPE html><html lang=\"en\"><head><meta charset=UTF-8><meta "
76 "name=viewport content=\"width=device-width, initial-scale=1,user-scalable=no\"><title>"));
77 stream->print(title.c_str());
78 stream->print(ESPHOME_F(
"</title>"));
79#ifdef USE_WEBSERVER_CSS_INCLUDE
80 stream->print(ESPHOME_F(
"<link rel=\"stylesheet\" href=\"/0.css\">"));
83 stream->print(ESPHOME_F(R
"(<link rel="stylesheet" href=")"));
85 stream->print(ESPHOME_F("\">"));
87 stream->print(ESPHOME_F(
"</head><body>"));
88 stream->print(ESPHOME_F(
"<article class=\"markdown-body\"><h1>"));
89 stream->print(title.c_str());
90 stream->print(ESPHOME_F(
"</h1>"));
91 stream->print(ESPHOME_F(
"<h2>States</h2><table id=\"states\"><thead><tr><th>Name<th>State<th>Actions<tbody>"));
94 for (
auto *obj :
App.get_sensors()) {
96 write_row(stream, obj,
"sensor",
"");
101 for (
auto *obj :
App.get_switches()) {
103 write_row(stream, obj,
"switch",
"<button>Toggle</button>");
108 for (
auto *obj :
App.get_buttons())
109 write_row(stream, obj,
"button",
"<button>Press</button>");
112#ifdef USE_BINARY_SENSOR
113 for (
auto *obj :
App.get_binary_sensors()) {
115 write_row(stream, obj,
"binary_sensor",
"");
120 for (
auto *obj :
App.get_fans()) {
122 write_row(stream, obj,
"fan",
"<button>Toggle</button>");
127 for (
auto *obj :
App.get_lights()) {
129 write_row(stream, obj,
"light",
"<button>Toggle</button>");
133#ifdef USE_TEXT_SENSOR
134 for (
auto *obj :
App.get_text_sensors()) {
136 write_row(stream, obj,
"text_sensor",
"");
141 for (
auto *obj :
App.get_covers()) {
143 write_row(stream, obj,
"cover",
"<button>Open</button><button>Close</button>");
148 for (
auto *obj :
App.get_numbers()) {
150 write_row(stream, obj,
"number",
"", [](AsyncResponseStream &stream, EntityBase *obj) {
151 number::Number *number = (number::Number *) obj;
152 stream.print(R
"(<input type="number" min=")");
153 stream.print(number->traits.get_min_value());
154 stream.print(R"(" max=")");
155 stream.print(number->traits.get_max_value());
156 stream.print(R"(" step=")");
157 stream.print(number->traits.get_step());
158 stream.print(R"(" value=")");
159 stream.print(number->state);
160 stream.print(R"("/>)");
167 for (
auto *obj :
App.get_texts()) {
169 write_row(stream, obj,
"text",
"", [](AsyncResponseStream &stream, EntityBase *obj) {
170 text::Text *text = (text::Text *) obj;
171 auto mode = (int) text->traits.get_mode();
172 stream.print(R
"(<input type=")");
174 stream.print(R
"(password)");
176 stream.print(R
"(text)");
178 stream.print(R"(" minlength=")");
179 stream.print(text->traits.get_min_length());
180 stream.print(R"(" maxlength=")");
181 stream.print(text->traits.get_max_length());
182 stream.print(R"(" pattern=")");
183 stream.print(text->traits.get_pattern_c_str());
184 stream.print(R"(" value=")");
185 stream.print(text->state.c_str());
186 stream.print(R"("/>)");
193 for (
auto *obj :
App.get_selects()) {
195 write_row(stream, obj,
"select",
"", [](AsyncResponseStream &stream, EntityBase *obj) {
196 select::Select *select = (select::Select *) obj;
197 stream.print(
"<select>");
198 stream.print(
"<option></option>");
199 for (
auto const &option : select->traits.get_options()) {
200 stream.print(
"<option>");
201 stream.print(option);
202 stream.print(
"</option>");
204 stream.print(
"</select>");
211 for (
auto *obj :
App.get_locks()) {
213 write_row(stream, obj,
"lock",
"", [](AsyncResponseStream &stream, EntityBase *obj) {
214 lock::Lock *
lock = (lock::Lock *) obj;
215 stream.print(
"<button>Lock</button><button>Unlock</button>");
216 if (
lock->traits.get_supports_open()) {
217 stream.print(
"<button>Open</button>");
225 for (
auto *obj :
App.get_climates()) {
227 write_row(stream, obj,
"climate",
"");
231#ifdef USE_WATER_HEATER
232 for (
auto *obj :
App.get_water_heaters()) {
234 write_row(stream, obj,
"water_heater",
"");
238 stream->print(ESPHOME_F(
"</tbody></table><p>See <a href=\"https://esphome.io/web-api/\">ESPHome Web API</a> for "
239 "REST API documentation.</p>"));
240#if defined(USE_WEBSERVER_OTA) && !defined(USE_WEBSERVER_OTA_DISABLED)
244 ESPHOME_F(
"<h2>OTA Update</h2><form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\"><input "
245 "type=\"file\" name=\"update\"><input type=\"submit\" value=\"Update\"></form>"));
247 stream->print(ESPHOME_F(
"<h2>Debug Log</h2><pre id=\"log\"></pre>"));
248#ifdef USE_WEBSERVER_JS_INCLUDE
250 stream->print(ESPHOME_F(
"<script type=\"module\" src=\"/0.js\"></script>"));
253 if (strlen(this->
js_url_) > 0) {
254 stream->print(ESPHOME_F(
"<script src=\""));
256 stream->print(ESPHOME_F(
"\"></script>"));
258 stream->print(ESPHOME_F(
"</article></body></html>"));
259 request->send(stream);
BedjetMode mode
BedJet operating mode.
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
void handle_index_request(AsyncWebServerRequest *request)
Handle an index request under '/'.
Application App
Global storage of Application pointer - only one Application can exist.