feat(restful_server): upgrade the example to use vue3+vuetify3

also cleaned up the backend firmware to use littlefs filesystem.
This commit is contained in:
morris
2025-07-17 23:26:12 +08:00
parent a5d53fc6a6
commit 70d62b1a54
55 changed files with 1263 additions and 597 deletions

View File

@@ -1,30 +1,20 @@
/* HTTP Restful API Server
/*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <fcntl.h>
#include "esp_http_server.h"
#include "esp_chip_info.h"
#include "esp_random.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_vfs.h"
#include "cJSON.h"
static const char *REST_TAG = "esp-rest";
#define REST_CHECK(a, str, goto_tag, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(REST_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
goto goto_tag; \
} \
} while (0)
static const char *TAG = "esp-rest";
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
#define SCRATCH_BUFSIZE (10240)
@@ -36,6 +26,7 @@ typedef struct rest_server_context {
#define CHECK_FILE_EXTENSION(filename, ext) (strcasecmp(&filename[strlen(filename) - strlen(ext)], ext) == 0)
#if CONFIG_EXAMPLE_DEPLOY_WEB_PAGES
/* Set HTTP response content type according to file extension */
static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath)
{
@@ -70,7 +61,7 @@ static esp_err_t rest_common_get_handler(httpd_req_t *req)
}
int fd = open(filepath, O_RDONLY, 0);
if (fd == -1) {
ESP_LOGE(REST_TAG, "Failed to open file : %s", filepath);
ESP_LOGE(TAG, "Failed to open file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
return ESP_FAIL;
@@ -84,12 +75,12 @@ static esp_err_t rest_common_get_handler(httpd_req_t *req)
/* Read file in chunks into the scratch buffer */
read_bytes = read(fd, chunk, SCRATCH_BUFSIZE);
if (read_bytes == -1) {
ESP_LOGE(REST_TAG, "Failed to read file : %s", filepath);
ESP_LOGE(TAG, "Failed to read file : %s", filepath);
} else if (read_bytes > 0) {
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) {
close(fd);
ESP_LOGE(REST_TAG, "File sending failed!");
ESP_LOGE(TAG, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -100,11 +91,12 @@ static esp_err_t rest_common_get_handler(httpd_req_t *req)
} while (read_bytes > 0);
/* Close file after sending complete */
close(fd);
ESP_LOGI(REST_TAG, "File sending complete");
ESP_LOGI(TAG, "File sending complete");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
#endif // CONFIG_EXAMPLE_DEPLOY_WEB_PAGES
/* Simple handler for light brightness control */
static esp_err_t light_brightness_post_handler(httpd_req_t *req)
@@ -133,7 +125,7 @@ static esp_err_t light_brightness_post_handler(httpd_req_t *req)
int red = cJSON_GetObjectItem(root, "red")->valueint;
int green = cJSON_GetObjectItem(root, "green")->valueint;
int blue = cJSON_GetObjectItem(root, "blue")->valueint;
ESP_LOGI(REST_TAG, "Light control: red = %d, green = %d, blue = %d", red, green, blue);
ESP_LOGI(TAG, "Light control: red = %d, green = %d, blue = %d", red, green, blue);
cJSON_Delete(root);
httpd_resp_sendstr(req, "Post control value successfully");
return ESP_OK;
@@ -146,7 +138,8 @@ static esp_err_t system_info_get_handler(httpd_req_t *req)
cJSON *root = cJSON_CreateObject();
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
cJSON_AddStringToObject(root, "version", IDF_VER);
cJSON_AddStringToObject(root, "chip", CONFIG_IDF_TARGET);
cJSON_AddStringToObject(root, "idf_version", IDF_VER);
cJSON_AddNumberToObject(root, "cores", chip_info.cores);
const char *sys_info = cJSON_Print(root);
httpd_resp_sendstr(req, sys_info);
@@ -160,6 +153,7 @@ static esp_err_t temperature_data_get_handler(httpd_req_t *req)
{
httpd_resp_set_type(req, "application/json");
cJSON *root = cJSON_CreateObject();
// Note: we're simulating temperature data with a random number for demonstration purposes
cJSON_AddNumberToObject(root, "raw", esp_random() % 20);
const char *sys_info = cJSON_Print(root);
httpd_resp_sendstr(req, sys_info);
@@ -170,17 +164,18 @@ static esp_err_t temperature_data_get_handler(httpd_req_t *req)
esp_err_t start_rest_server(const char *base_path)
{
REST_CHECK(base_path, "wrong base path", err);
esp_err_t ret = ESP_OK;
ESP_RETURN_ON_FALSE(base_path && strlen(base_path) < ESP_VFS_PATH_MAX, ESP_ERR_INVALID_ARG, TAG, "Invalid base path");
rest_server_context_t *rest_context = calloc(1, sizeof(rest_server_context_t));
REST_CHECK(rest_context, "No memory for rest context", err);
ESP_RETURN_ON_FALSE(rest_context, ESP_ERR_NO_MEM, TAG, "No memory for rest context");
strlcpy(rest_context->base_path, base_path, sizeof(rest_context->base_path));
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.uri_match_fn = httpd_uri_match_wildcard;
ESP_LOGI(REST_TAG, "Starting HTTP Server");
REST_CHECK(httpd_start(&server, &config) == ESP_OK, "Start server failed", err_start);
ESP_LOGI(TAG, "Starting HTTP Server");
ESP_GOTO_ON_ERROR(httpd_start(&server, &config), err, TAG, "Failed to start http server");
/* URI handler for fetching system info */
httpd_uri_t system_info_get_uri = {
@@ -209,6 +204,7 @@ esp_err_t start_rest_server(const char *base_path)
};
httpd_register_uri_handler(server, &light_brightness_post_uri);
#if CONFIG_EXAMPLE_DEPLOY_WEB_PAGES
/* URI handler for getting web server files */
httpd_uri_t common_get_uri = {
.uri = "/*",
@@ -217,10 +213,12 @@ esp_err_t start_rest_server(const char *base_path)
.user_ctx = rest_context
};
httpd_register_uri_handler(server, &common_get_uri);
#endif // CONFIG_EXAMPLE_DEPLOY_WEB_PAGES
return ESP_OK;
err_start:
free(rest_context);
err:
return ESP_FAIL;
if (rest_context) {
free(rest_context);
}
return ret;
}