Skip to content

Commit 5c5c85a

Browse files
committed
fix: webserver optimized && remove mDNS dep
1 parent 6c33f29 commit 5c5c85a

File tree

8 files changed

+105
-71
lines changed

8 files changed

+105
-71
lines changed

.devcontainer/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ENV LANG=C.UTF-8
66
ENV EDITOR=nvim
77
ARG USER=ubuntu
88
ENV PATH /opt/esp/idf/components/spiffs:$PATH
9+
ENV ESPPORT /dev/ttyACM0
910

1011
RUN set -xe; \
1112
apt-get update \

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ Before setting up SmartClimate, ensure you have the following installed:
7272
idf.py monitor
7373
```
7474

75+
## Features
76+
77+
- [x] Captive portal functionality compatible with both Android and iOS for easy Wi-Fi configuration.
78+
7579
## Roadmap
7680

7781
- [ ] First release

dependencies.lock

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,6 @@ dependencies:
99
registry_url: https://components.espressif.com/
1010
type: service
1111
version: 2.5.5
12-
espressif/mdns:
13-
component_hash: 77ece55f01ce3723d8f1baff6e586fdb342adcbf956e39509a4fa323f278f290
14-
dependencies:
15-
- name: idf
16-
require: private
17-
version: '>=5.0'
18-
source:
19-
registry_url: https://components.espressif.com/
20-
type: service
21-
version: 1.8.1
2212
idf:
2313
source:
2414
type: idf
@@ -32,9 +22,8 @@ dependencies:
3222
version: 8.3.11
3323
direct_dependencies:
3424
- espressif/led_strip
35-
- espressif/mdns
3625
- idf
3726
- lvgl/lvgl
38-
manifest_hash: c663c3088ad6f4a8448e8c6000fc321b153779ca531545b2c162543bea70b5bd
27+
manifest_hash: 7f5441cfbe41ef1dd7c33d5b252c1e300dbbeaebba48fe575e26539d06f94caf
3928
target: esp32c6
4029
version: 2.0.0

main/idf_component.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
dependencies:
2-
idf: '>=4.4'
2+
idf: ">=4.4"
33
lvgl/lvgl: ~8.3.0
44
espressif/led_strip: ^2.4.1
5-
espressif/mdns: '*'

main/webserver/html/index.html

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Setup SmartClimate</title>
7-
<link
8-
rel="stylesheet"
9-
href="http://smartclimate.local/css/milligram.min.css"
10-
/>
7+
<link rel="stylesheet" href="css/milligram.min.css" />
118
<style>
129
html,
1310
body {
@@ -34,12 +31,23 @@ <h2>Welcome to SmartClimate</h2>
3431
SmartClimate helps you monitor and optimize your environment. Follow
3532
the steps below to set up your system.
3633
</p>
37-
<button class="button">Get Started</button>
34+
<button class="button" id="get-started-btn">Get Started</button>
3835
</section>
3936
</main>
4037

4138
<footer class="container">
42-
<p>&copy; 2025 SmartClimate.</p>
39+
<p>&copy; <span id="current-year"></span> SmartClimate.</p>
40+
<script>
41+
document.getElementById("current-year").textContent =
42+
new Date().getFullYear();
43+
</script>
4344
</footer>
45+
46+
<script src="js/umbrella.min.js"></script>
47+
<script>
48+
u("#get-started-btn").on("click", function () {
49+
alert("Welcome to SmartClimate setup!");
50+
});
51+
</script>
4452
</body>
4553
</html>

main/webserver/html/js/umbrella.min.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main/webserver/webserver.c

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,84 @@
33
static const char *TAG = "HTTP_SERVER";
44
extern const char *SPIFFS_MOUNTPOINT;
55
static char CSS_PATH[128];
6+
static char JS_PATH[128];
67

8+
/// @brief Serve a file from the SPIFFS filesystem
9+
/// @param req httpd_req_t
10+
/// @param file_path const char*
11+
/// @param content_type const char*
12+
/// @return esp_err_t
13+
static esp_err_t serve_file(httpd_req_t *req, const char *file_path, const char *content_type) {
14+
FILE *file = fopen(file_path, "r");
15+
if (file == NULL) {
16+
ESP_LOGE(TAG, "Failed to open file: %s", file_path);
17+
return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to open file");
18+
}
19+
20+
httpd_resp_set_type(req, content_type);
21+
char buffer[1024];
22+
size_t bytes_read;
23+
while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
24+
esp_err_t send_status = httpd_resp_send_chunk(req, buffer, bytes_read);
25+
if (send_status != ESP_OK) {
26+
fclose(file);
27+
ESP_LOGE(TAG, "Error sending chunk from file: %s", file_path);
28+
return send_status;
29+
}
30+
}
31+
fclose(file);
32+
return httpd_resp_send_chunk(req, NULL, 0);
33+
}
34+
35+
/// @brief Log the request URI and status
36+
/// @param req httpd_req_t
37+
/// @param status esp_err_t
38+
/// @return esp_err_t
739
static esp_err_t log_request(httpd_req_t *req, esp_err_t status) {
840
ESP_LOGI(TAG, "Request URI : %s | Status : %d", req->uri, status);
941
return status;
1042
}
1143

44+
/// @brief setup page handler
45+
/// @param req httpd_req_t
46+
/// @return esp_err_t
47+
static esp_err_t setup_handler(httpd_req_t *req) {
48+
esp_err_t status = serve_file(req, "/spiffs/index.html", "text/html");
49+
return log_request(req, status);
50+
}
51+
52+
/// @brief Handler for milligram CSS
53+
/// @param req httpd_req_t
54+
/// @return esp_err_t
1255
static esp_err_t milligram_handler(httpd_req_t *req) {
13-
char resp[1024];
14-
FILE *file = fopen(CSS_PATH, "r");
15-
if (file == NULL) {
16-
ESP_LOGE(TAG, "Failed to open %s", CSS_PATH);
17-
return log_request(req, ESP_FAIL);
18-
}
19-
size_t read_bytes = fread(resp, 1, sizeof(resp) - 1, file);
20-
fclose(file);
21-
if (read_bytes == 0) {
22-
ESP_LOGE(TAG, "Failed to read %s", CSS_PATH);
23-
return log_request(req, ESP_FAIL);
24-
}
25-
resp[read_bytes] = '\0';
26-
httpd_resp_set_type(req, "text/css");
27-
esp_err_t status = httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN);
56+
esp_err_t status = serve_file(req, CSS_PATH, "text/css");
2857
return log_request(req, status);
2958
}
3059

31-
static esp_err_t setup(httpd_req_t *req) {
32-
char resp[1024];
33-
FILE *file = fopen("/spiffs/index.html", "r");
34-
if (file == NULL) {
35-
ESP_LOGE(TAG, "Failed to open /spiffs/index.html");
36-
return log_request(req, ESP_FAIL);
37-
}
38-
size_t read_bytes = fread(resp, 1, sizeof(resp) - 1, file);
39-
fclose(file);
40-
if (read_bytes == 0) {
41-
ESP_LOGE(TAG, "Failed to read /spiffs/index.html");
42-
return log_request(req, ESP_FAIL);
43-
}
44-
resp[read_bytes] = '\0';
45-
esp_err_t status = httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN);
60+
/// @brief Handler for milligram CSS
61+
/// @param req httpd_req_t
62+
/// @return esp_err_t
63+
static esp_err_t umbrella_handler(httpd_req_t *req) {
64+
esp_err_t status = serve_file(req, JS_PATH, "text/javascript");
4665
return log_request(req, status);
4766
}
4867

68+
/// @brief Connectivity check handler (captive portal)
69+
/// @param req httpd_req_t
70+
/// @return esp_err_t
4971
static esp_err_t connectivity_check(httpd_req_t *req) {
50-
httpd_resp_set_hdr(req, "Location", "http://smartclimate.local/setup");
72+
httpd_resp_set_hdr(req, "Location", "http://smartclimate/setup");
5173
httpd_resp_set_status(req, "301 Moved Permanently");
52-
return log_request(req, httpd_resp_send(req, "", HTTPD_RESP_USE_STRLEN));
74+
esp_err_t status = httpd_resp_send(req, "", HTTPD_RESP_USE_STRLEN);
75+
return log_request(req, status);
5376
}
5477

78+
/// @brief Default request handler for undefined URIs
79+
/// @param req httpd_req_t
80+
/// @param err httpd_err_code_t
81+
/// @return esp_err_t
5582
static esp_err_t default_handler(httpd_req_t *req, httpd_err_code_t err) {
56-
ESP_LOGW(TAG, "Undefined URI requested : %s | Error code : %d", req->uri, err);
83+
ESP_LOGW(TAG, "Undefined URI requested: %s | Error code: %d", req->uri, err);
5784
const char resp[] = "404 Not Found";
5885
esp_err_t status = httpd_resp_set_status(req, "404 Not Found");
5986
if (status == ESP_OK) {
@@ -62,39 +89,41 @@ static esp_err_t default_handler(httpd_req_t *req, httpd_err_code_t err) {
6289
return log_request(req, status);
6390
}
6491

65-
httpd_uri_t setup_uri = {.uri = "/setup", .method = HTTP_GET, .handler = setup, .user_ctx = NULL};
66-
static httpd_uri_t connectivity_uris[] = {
67-
{.uri = "/generate_204", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
68-
{.uri = "/library/test/success.html", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
69-
{.uri = "/hotspot-detect.html", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
70-
{.uri = "/", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
71-
};
72-
httpd_uri_t css_uri = {
73-
.uri = "/css/milligram.min.css", .method = HTTP_GET, .handler = milligram_handler, .user_ctx = NULL};
74-
92+
/// @brief Start the webserver
93+
/// @param void
94+
/// @return httpd_handle_t
7595
httpd_handle_t webserver_start(void) {
7696
snprintf(CSS_PATH, sizeof(CSS_PATH), "%s/css/milligram.min.css", SPIFFS_MOUNTPOINT);
97+
snprintf(JS_PATH, sizeof(JS_PATH), "%s/js/umbrella.min.js", SPIFFS_MOUNTPOINT);
98+
7799
httpd_handle_t server = NULL;
78100
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
79101

80-
ESP_ERROR_CHECK(mdns_init());
102+
httpd_uri_t setup_uri = {.uri = "/setup", .method = HTTP_GET, .handler = setup_handler, .user_ctx = NULL};
81103

82-
mdns_hostname_set(APP_NAME);
83-
mdns_instance_name_set("esp device");
104+
static httpd_uri_t connectivity_uris[] = {
105+
{.uri = "/generate_204", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
106+
{.uri = "/library/test/success.html", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
107+
{.uri = "/hotspot-detect.html", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
108+
{.uri = "/", .method = HTTP_GET, .handler = connectivity_check, .user_ctx = NULL},
109+
};
84110

85-
ESP_LOGI(TAG, "Webserver started on port : %d", config.server_port);
111+
httpd_uri_t css_uri = {
112+
.uri = "/css/milligram.min.css", .method = HTTP_GET, .handler = milligram_handler, .user_ctx = NULL};
113+
httpd_uri_t js_uri = {
114+
.uri = "/js/umbrella.min.js", .method = HTTP_GET, .handler = umbrella_handler, .user_ctx = NULL};
115+
116+
ESP_LOGI(TAG, "Webserver starting on port: %d", config.server_port);
86117
if (httpd_start(&server, &config) == ESP_OK) {
87118
httpd_register_uri_handler(server, &setup_uri);
88119
httpd_register_uri_handler(server, &css_uri);
120+
httpd_register_uri_handler(server, &js_uri);
89121

90122
for (size_t i = 0; i < sizeof(connectivity_uris) / sizeof(connectivity_uris[0]); i++) {
91123
httpd_register_uri_handler(server, &connectivity_uris[i]);
92124
}
93125

94126
httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, default_handler);
95-
96-
mdns_service_add("HTTP webserver", "_http", "_tcp", 80, NULL, 0);
97-
98127
return server;
99128
}
100129
ESP_LOGE(TAG, "Error on webserver boot");

main/webserver/webserver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include <stdio.h>
22
#include "esp_http_server.h"
33
#include "esp_log.h"
4-
#include "espressif__mdns/include/mdns.h"
4+
#include <stdio.h>
5+
#include <string.h>
56

67
extern const char *APP_NAME;
78

0 commit comments

Comments
 (0)