# DataSets **Repository Path**: NetADs/datasets ## Basic Information - **Project Name**: DataSets - **Description**: ESP32S3开发板上,从网上拉取数据的组件。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-27 - **Last Updated**: 2026-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # datasets 适用于 ESP-IDF v5.x 的轻量级 HTTP JSON 请求组件。提供简洁的接口从 HTTPS 服务器获取并解析 JSON 数据。 ## 功能特点 - 自动 TLS 证书验证(使用 ESP-IDF 内置 CA 证书包) - DNS 解析诊断日志 - 可配置超时时间和重试次数(支持 Kconfig 菜单配置) - 自动 JSON 解析(基于 cJSON) - 内存安全(调用方负责释放返回的 cJSON 对象) - 可选 PSRAM 分配策略(ESP32-S3 大 JSON 场景下降低 DRAM 压力,25KB+ 天气预报等) - 支持 API Key / Bearer Token / 自定义请求头认证 - 支持 GET / POST / PUT 等多种 HTTP 方法 - 符合 ESP-IDF v5.x 标准组件规范 - 可作为独立组件复用于其他项目 ## 目录结构 ``` datasets/ ├── CMakeLists.txt # 组件构建配置 ├── Kconfig # 组件配置菜单(超时、重试、URL 长度、请求头数量) ├── idf_component.yml # 组件描述文件 ├── include/ │ └── datasets.h # 公共头文件 ├── src/ │ └── datasets.c # 组件源代码 ├── examples/ # 示例应用目录 │ ├── CMakeLists.txt │ ├── sdkconfig.defaults │ └── main/ │ ├── CMakeLists.txt │ ├── main.c # 示例主程序(WiFi + 黄历) │ └── include/main.h ├── README.md └── LICENSE ``` ## 快速开始 ### 方式 1:作为独立组件使用 1. **复制组件到你的项目** ```bash cp -r datasets /path/to/your/project/ ``` 2. **在你的项目中添加依赖** 在你的项目的 `main/CMakeLists.txt` 中: ```cmake idf_component_register( SRCS "your_source.c" INCLUDE_DIRS "include" REQUIRES datasets ) ``` 3. **在代码中使用** ```c #include "datasets.h" #include "esp_log.h" #include "cJSON.h" void fetch_data(void) { // 简单 GET 请求 datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/data", .timeout_ms = 30000, .max_retries = 2, }; cJSON *root = datasets_fetch(&req); if (root == NULL) { ESP_LOGE("app", "Request failed"); return; } // 解析 JSON 数据... cJSON *name = cJSON_GetObjectItem(root, "name"); if (name && name->valuestring) { ESP_LOGI("app", "Name: %s", name->valuestring); } cJSON_Delete(root); } ``` ### 方式 2:通过 Git URL 引用 在你的 ESP-IDF 项目的 `idf_component.yml` 中添加: ```yaml dependencies: datasets: git: https://gitee.com/NetADs/datasets.git version: "^1.0.0" ``` 然后运行 `idf.py reconfigure` 自动下载组件。 ### 方式 3:本地路径引用(开发调试) ```yaml dependencies: datasets: path: /path/to/datasets ``` ### 方式 4:编译示例程序 ```bash cd datasets/examples idf.py build ``` ## API 参考 ### `datasets_fetch_raw` ```c char *datasets_fetch_raw(datasets_request_t *req, int *out_len); ``` 获取原始 HTTP 响应体,不进行 JSON 解析。适用于需要在 JSON 解析前对响应做预处理(如 gzip 解压)的场景。 | 参数 | 说明 | |------|------| | `req` | 请求配置结构体指针,`base_url` 为必填字段 | | `out_len` | 输出参数,接收响应体长度 | | 返回值 | 说明 | |--------|------| | `char *` | malloc 分配的 null-terminated 响应体,调用方需 `free()` 释放 | | `NULL` | 请求失败 | ### `datasets_fetch` ```c cJSON *datasets_fetch(datasets_request_t *req); ``` 便捷封装:调用 `datasets_fetch_raw()` 后自动 `cJSON_Parse()`。 | 参数 | 说明 | |------|------| | `req` | 请求配置结构体指针,`base_url` 为必填字段 | | 返回值 | 说明 | |--------|------| | `cJSON *` | 解析后的 JSON 根对象,调用方需调用 `cJSON_Delete()` 释放 | | `NULL` | 请求失败或 JSON 解析失败 | **`datasets_request_t` 结构体:** | 字段 | 类型 | 说明 | |------|------|------| | `base_url` | `const char *` | **必填**:基础 URL(如 `"https://api.example.com"`) | | `path` | `const char *` | 可选:API 路径(如 `"/v1/data"`) | | `query_params` | `const char *` | 可选:查询参数,不含 `?`(如 `"key=abc&limit=10"`) | | `method` | `esp_http_client_method_t` | HTTP 方法,默认 `HTTP_METHOD_GET` | | `post_data` | `const char *` | 可选:POST/PUT 请求体(JSON 字符串) | | `api_key` | `const char *` | 可选:API Key 值 | | `api_key_header` | `const char *` | 可选:API Key 的请求头名称,默认 `"X-API-Key"` | | `bearer_token` | `const char *` | 可选:Bearer Token,自动设置 `Authorization` 请求头 | | `custom_headers` | `const char **` | 可选:自定义请求头数组(`"Header: Value"` 格式) | | `header_count` | `int` | 自定义请求头数量 | | `timeout_ms` | `int` | 超时时间(毫秒),0 使用 Kconfig 默认值 | | `max_retries` | `int` | 最大重试次数,0 使用 Kconfig 默认值 | ## 使用示例 ### 示例 1:简单 GET 请求 ```c datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/users", .query_params = "page=1&limit=10", }; cJSON *root = datasets_fetch(&req); if (root) { // 处理 JSON... cJSON_Delete(root); } ``` ### 示例 2:带浏览器伪装头的请求 很多国内 CDN/WAF 会拦截非浏览器 User-Agent,需要通过自定义请求头伪装。 ```c const char *headers[] = { "User-Agent: Mozilla/5.0 (compatible; ESP32)", "Accept: application/json, text/plain, */*", "Accept-Encoding: identity", /* 告知服务器不压缩 */ "Cache-Control: no-cache", }; datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/endpoint", .query_params = "key=value", .method = HTTP_METHOD_GET, .timeout_ms = 30000, .max_retries = 2, .custom_headers = headers, .header_count = sizeof(headers) / sizeof(headers[0]), }; cJSON *root = datasets_fetch(&req); ``` ### 示例 3:API Key 认证 ```c // 方式 A:使用默认请求头名称 X-API-Key datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/data", .api_key = "your-api-key", }; // 方式 B:自定义请求头名称 datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/data", .api_key = "your-api-key", .api_key_header = "X-My-Custom-Key", }; cJSON *root = datasets_fetch(&req); ``` ### 示例 4:Bearer Token 认证 ```c datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/authenticated", .bearer_token = "your-jwt-token", }; cJSON *root = datasets_fetch(&req); ``` ### 示例 5:POST 请求 ```c cJSON *body = cJSON_CreateObject(); cJSON_AddStringToObject(body, "name", "test"); cJSON_AddNumberToObject(body, "value", 42); char *body_str = cJSON_PrintUnformatted(body); datasets_request_t req = { .base_url = "https://api.example.com", .path = "/v1/create", .method = HTTP_METHOD_POST, .post_data = body_str, }; cJSON *root = datasets_fetch(&req); free(body_str); cJSON_Delete(body); ``` ## 配置选项 通过 `idf.py menuconfig` 可调整以下参数(位于 `datasets Component Configuration` 菜单): | 配置项 | 默认值 | 说明 | |--------|--------|------| | `DATASETS_MAX_RETRIES` | 2 | HTTP 请求最大重试次数 | | `DATASETS_DEFAULT_TIMEOUT_MS` | 30000 | 默认连接超时(毫秒) | | `DATASETS_MAX_URL_LEN` | 1024 | URL 缓冲区最大长度 | | `DATASETS_MAX_HEADERS` | 10 | 最大自定义请求头数量 | | `DATASETS_USE_PSRAM` | y | 启用后将 HTTP 响应 buffer 分配至 PSRAM(需开启 SPIRAM),大幅降低大 JSON 场景下的 DRAM 压力 | ## 依赖项 | 组件 | 说明 | |------|------| | `esp_http_client` | ESP-IDF 内置 HTTP 客户端 | | `json` | ESP-IDF 内置 cJSON 库 | | `mbedtls` | TLS/SSL 支持(证书验证) | | `lwip` | 网络栈(DNS 解析) | ## 系统要求 - ESP-IDF v5.0 或更高版本 - ESP32 系列芯片(ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6) ## 配置要求 需要在 `sdkconfig` 中启用证书包: ``` CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y ``` ## 完整示例 完整的示例代码请参考 `examples/main/main.c` 和 `examples/README.md`。示例演示了 WiFi 连接、黄历 API 调用,并包含 ESP32-S3 HTTPS 常见问题的解决方案。 ## 故障排查 ### DNS 解析失败 检查日志输出确认网络连接正常,必要时配置 DNS 服务器。 ### TLS 证书验证失败 - 确保使用 HTTPS URL - 确认服务器的 SSL 证书是有效的 - 检查 `sdkconfig` 中的证书包配置 ### HTTP 请求超时 - 检查 `timeout_ms` 配置是否合理 - 通过 `idf.py menuconfig` 调整 `DATASETS_DEFAULT_TIMEOUT_MS` - 增大 `max_retries` 以应对网络波动 ### 内存分配失败 - 确保已开启 `SPIRAM` 及 `DATASETS_USE_PSRAM`(默认开启),将大 JSON 响应 buffer 分配至 PSRAM - 减少响应数据大小或增大 `DATASETS_MAX_URL_LEN` - 增加堆内存配置 - 检查是否有内存泄漏 ## 贡献 欢迎提交 Issue 和 Pull Request! ## 许可证 MIT License