[Beginners Guide] HTTP Client POST
- liangzn
- Jan 9
- 7 min read
Going through this doc, you will learn how to connect Wifi, add LVGL components and handle HTTP request and response.
This document provides detailed instructions on how to run the http_client_postproject (PATH: examples/protocols/http_client_post) from scratch, including server startup, project configuration, compilation, and program execution flow.
Table of Contents
1. Prerequisites
1.1 Environment Requirements
l Development Environment: TuyaOpen development environment configured
l Python 3: For running the test server
l Development Board: Supports T5AI platform, with LCD display (optional)
l Network: Device and server on the same network
1.2 Project Structure
http_client_post/
├── server.py # Python HTTP test server
├── CMakeLists.txt # CMake build configuration
├── app_default.config # Application configuration file
├── README.md # Project documentation
├── README_CN.md # Chinese documentation
├── include/
│ └── ui.h # UI interface header file
└── src/
├── tuya_main.c # Main program (network and HTTP)
└── ui.c # UI implementation (LVGL display)
2. Starting the Python Server
2.1 Navigate to Project Directory
cd examples/protocols/http_client_post2.2 Start the Server
python3 server.py2.3 Server Output Example
============================================================
HTTP POST Server for TuyaOpen HTTP Client Example
============================================================
Server starting on 0.0.0.0:8080
Local IP address: 192.168.1.181
Access URL: http://192.168.1.181:8080
API Endpoint: http://192.168.1.181:8080/api/random
============================================================Important: Record the displayed IP address (e.g., 192.168.1.181), which will be needed for subsequent configuration.
2.4 Server Functionality
l Listening Port: 8080 (default)
l API Endpoint: /api/random
l Functionality: Receives POST requests and returns random strings (JSON format)
2.5 Custom Port (Optional)
python3 server.py --host 0.0.0.0 --port 90003. Configuring the Project
3.1 Configure Server Information
Edit src/tuya_main.cand modify the following macro definitions:
// Server configuration - HTTP server settings
#define SERVER_HOST "192.168.1.181" // Change to the IP address shown by the server
#define SERVER_PORT 8080 // Server port number (must match server.py)
#define SERVER_PATH "/api/random" // API endpoint path3.2 Configure Wi-Fi (if using Wi-Fi)
Edit src/tuya_main.cand modify Wi-Fi configuration:
// Wi-Fi configuration - Wi-Fi network settings
#define DEFAULT_WIFI_SSID "your-ssid" // Change to your Wi-Fi name
#define DEFAULT_WIFI_PSWD "your-passwd" // Change to your Wi-Fi password3.3 Configure Display (Optional)
Edit app_default.configand ensure display configuration is correct:
CONFIG_BOARD_CHOICE_T5AI=y
CONFIG_TUYA_T5AI_BOARD_EX_MODULE_35565LCD=y
CONFIG_ENABLE_LIBLVGL=y
CONFIG_LVGL_ENABLE_TP=y
CONFIG_ENABLE_LVGL_DEMO=y
3.4 Configure Development Board
Run the configuration command to select the development board:
tos.py config choiceSelect the corresponding development board (e.g., T5AI).
3.5 Configure Display Driver (if using display)
tos.py config menuConfigure in the menu:
l Display driver (e.g., ILI9488, ST7789)
l Display interface (SPI, RGB, 8080)
l Touch driver (if touch is supported)
l GPIO pin configuration
4. Building and Compiling the Project
4.1 Compile the Project
tos.py build4.2 Compilation Output
After successful compilation, a firmware file will be generated, typically located at:
dist/http_client_post_1.0.0/http_client_post_*.bin4.3 Flash to Device
Flash the compiled firmware to the development board (specific method depends on your development board).
tos.py flash
5. Program Entry Point
5.1 Program Entry
The program entry point is the tuya_app_main() function, located at line 249 in src/tuya_main.c.
5.2 Entry Function Call Chain
tuya_app_main() // System entry (line 249)
└─> tal_thread_create_and_start()
└─> tuya_app_thread() // Application thread (line 242)
└─> user_main() // User main function (line 168)5.3 Entry Function Code
void tuya_app_main(void)
{
THREAD_CFG_T thrd_param = {1024 * 4, 4, "tuya_app_main", 0};
tal_thread_create_and_start(&ty_app_thread, NULL, NULL,
tuya_app_thread, NULL, &thrd_param);
}
Explanation:
l Creates an application thread named "tuya_app_main"
l Stack size: 4096 bytes
l Priority: 4
l Thread function: tuya_app_thread
6. Program Execution Flow
6.1 Initialization Phase (user_main function)
6.1.1 Log Initialization
tal_log_init(TAL_LOG_LEVEL_DEBUG, 1024, (TAL_LOG_OUTPUT_CB)tkl_log_output);l Initialize log system
l Log level: DEBUG
l Log buffer: 1024 bytes
6.1.2 Print Application Information
PR_NOTICE("Application information:");
PR_NOTICE("Project name: %s", PROJECT_NAME);
PR_NOTICE("App version: %s", PROJECT_VERSION);
// ... Other information
Outputs project name, version, compilation time, etc.
6.1.3 Print Configuration Information
PR_NOTICE("HTTP Client POST Configuration:");
PR_NOTICE("Server Host: %s", SERVER_HOST);
PR_NOTICE("Server Port: %d", SERVER_PORT);
PR_NOTICE("Server Path: %s", SERVER_PATH);
Displays server configuration information.
6.1.4 UI Initialization (if display is enabled)
#if defined(ENABLE_LIBLVGL) && (ENABLE_LIBLVGL == 1)
ui_http_client_post_init(__button_click_callback);
PR_NOTICE("LVGL display initialized");
#endifUI Initialization Flow (ui.cline 56):
1. Register hardware: board_register_hardware()
2. Initialize LVGL: lv_vendor_init(DISPLAY_NAME)
3. Create screen object
4. Create UI elements:
a. Wi-Fi status label and indicator (top right corner)
b. "Receive" label
c. Response container box
d. Response text label
e. Send button (bottom)
5. Start LVGL: lv_vendor_start(5, 1024 * 8)
6.1.5 System Service Initialization
tal_kv_init(...); // Key-value storage initialization
tal_sw_timer_init(); // Software timer initialization
tal_workq_init(); // Work queue initialization
6.1.6 Subscribe to Network Status Events
tal_event_subscribe(EVENT_LINK_STATUS_CHG, "http_client_post",
__link_status_cb, SUBSCRIBE_TYPE_NORMAL);
Register network status change callback function __link_status_cb.
6.1.7 Network Initialization
#if defined(ENABLE_LIBLWIP) && (ENABLE_LIBLWIP == 1)
TUYA_LwIP_Init();
#endif
netmgr_type_e type = 0;
#if defined(ENABLE_WIFI) && (ENABLE_WIFI == 1)
type |= NETCONN_WIFI;
#endif
netmgr_init(type);Initialize network management module.
6.1.8 Wi-Fi Connection
#if defined(ENABLE_WIFI) && (ENABLE_WIFI == 1)
netconn_wifi_info_t wifi_info = {0};
strcpy(wifi_info.ssid, DEFAULT_WIFI_SSID);
strcpy(wifi_info.pswd, DEFAULT_WIFI_PSWD);
netmgr_conn_set(NETCONN_WIFI, NETCONN_CMD_SSID_PSWD, &wifi_info);
PR_NOTICE("Connecting to Wi-Fi: %s", DEFAULT_WIFI_SSID);
#endif
Start connecting to Wi-Fi network.
6.2 Network Connection Phase
6.2.1 Network Status Callback
When network status changes, the __link_status_cbcallback function is triggered (line 140):
OPERATE_RET __link_status_cb(void *data)
{
netmgr_status_e status = *(netmgr_status_e *)data;
if (status == NETMGR_LINK_UP) {
ui_update_wifi_status(true); // Update Wi-Fi status to green
PR_NOTICE("Network connected");
} else {
ui_update_wifi_status(false); // Update Wi-Fi status to red
PR_NOTICE("Network disconnected");
}
return OPRT_OK;
}Execution Flow:
1. Parse network status data
2. If connection successful (NETMGR_LINK_UP):
a. Update UI to show green Wi-Fi indicator
b. Print connection success log
3. If disconnected:
a. Update UI to show red Wi-Fi indicator
b. Print disconnection log
6.3 User Interaction Phase
6.3.1 Button Click Event
When the user clicks the "Send Request" button on the screen, the button click event handler is triggered (ui.cline 40):
static void button_click_event_cb(lv_event_t *e)
{
if (code == LV_EVENT_CLICKED) {
if (button_click_cb != NULL) {
button_click_cb(); // Call the main program's callback function
}
}
}
6.3.2 Button Click Callback Handling
Calls the __button_click_callbackfunction (tuya_main.cline 120):
static void __button_click_callback(void)
{
// 1. Check network status
netmgr_status_e status = NETMGR_LINK_DOWN;
netmgr_conn_get(NETCONN_AUTO, NETCONN_CMD_STATUS, &status);
if (status != NETMGR_LINK_UP) {
ui_update_response_text("Network Not Connected", true);
return;
}
// 2. Update UI to show "Sending..."
ui_update_response_sending();
// 3. Send HTTP POST request
__send_http_post_request();
}Execution Steps:
1. Check Network: Verify if network is connected
2. Update UI: Show "Sending..." status (blue text)
3. Send Request: Call HTTP POST request function
6.4 HTTP Request Phase
6.4.1 Send HTTP POST Request
The __send_http_post_requestfunction (line 59) performs the following operations:
static void __send_http_post_request(void)
{
// 1. Prepare HTTP response structure
http_client_response_t http_response = {0};
// 2. Set HTTP request headers
http_client_header_t headers[] = {
{.key = "Content-Type", .value = "application/json"},
{.key = "User-Agent", .value = "TuyaOpen-HTTP-Client"}
};
// 3. Prepare POST request body
const char *post_body = "{\"action\":\"get_random_string\"}";
// 4. Send HTTP request
http_client_status_t http_status = http_client_request(
&(const http_client_request_t){
.host = SERVER_HOST,
.port = SERVER_PORT,
.method = "POST",
.path = SERVER_PATH,
.headers = headers,
.headers_count = 2,
.body = (const uint8_t *)post_body,
.body_length = strlen(post_body),
.timeout_ms = HTTP_REQUEST_TIMEOUT // 10 seconds
},
&http_response);
// 5. Process response...
}
HTTP Request Details:
l Method: POST
l Headers: Content-Type: application/json
l Body: {"action":"get_random_string"}
l Timeout: 10 seconds
6.4.2 Process HTTP Response
if (HTTP_CLIENT_SUCCESS != http_status) {
// Request failed
ui_update_response_text("Request Failed", true);
http_client_free(&http_response);
return;
}
if (http_response.status_code == 200 && http_response.body != NULL) {
// 1. Copy raw response data
size_t copy_len = http_response.body_length;
if (copy_len > sizeof(server_response) - 1) {
copy_len = sizeof(server_response) - 1;
}
memcpy(server_response, http_response.body, copy_len);
server_response[copy_len] = '\0';
// 2. Update UI to display response
ui_update_response_text(server_response, false);
// 3. Print log
PR_NOTICE("Server response: %s", server_response);
}
// 4. Free response resources
http_client_free(&http_response);
Response Processing Steps:
1. Check Status: Verify if request was successful
2. Copy Data: Copy response body to local buffer
3. Update UI: Display response text in response container box
4. Print Log: Output response content to console
5. Free Resources: Free HTTP response structure
6.5 UI Update Phase
6.5.1 Update Response Text Display
ui_update_response_textfunction (ui.cline 145):
void ui_update_response_text(const char *text, bool is_error)
{
lv_vendor_disp_lock();
if (text != NULL) {
lv_label_set_text(response_label, text);
lv_obj_set_style_text_color(response_label,
is_error ? lv_color_hex(0xFF0000) :
lv_color_hex(0x000000), 0);
}
lv_vendor_disp_unlock();
}
Functionality:
l Update text in response container box
l Set text color based on is_errorparameter (error=red, normal=black)
7. Usage Instructions
7.1 Startup Process Summary
1. Start Server: Run python3 server.py, record IP address
2. Configure Project: Modify server IP and Wi-Fi information in src/tuya_main.c
3. Compile Project: Run tos.py build
4. Flash Firmware: Flash firmware to development board
5. Power On: Device automatically executes after power on
7.2 Execution Flow Summary
Device Power On
↓
tuya_app_main() - Create application thread
↓
tuya_app_thread() - Application thread execution
↓
user_main() - User main function
├─> Initialize log system
├─> Initialize UI (if enabled)
├─> Initialize system services
├─> Subscribe to network status events
├─> Initialize network
└─> Connect to Wi-Fi
↓
Network Connection Successful → __link_status_cb() → Update Wi-Fi status indicator (green)
↓
User Clicks Button → button_click_event_cb() → __button_click_callback()
├─> Check network status
├─> Update UI to show "Sending..."
└─> __send_http_post_request()
├─> Send HTTP POST request
├─> Receive server response
├─> Copy response data
├─> Update UI to display response
└─> Print log
7.3 Expected Results
On Device Screen:
l Top right corner shows "Wi-Fi" label and status dot (green=connected, red=disconnected)
l Middle shows "Receive" label and response container box
l Bottom shows "Send Request" button
l After clicking button, response container box shows random string returned by server
In Device Logs:
[NOTICE] Network connected
[NOTICE] Button clicked, sending HTTP POST request
[NOTICE] Sending HTTP POST request...
[DEBUG] HTTP POST request successful, status code: 200
[NOTICE] Server response: aB3xK9mP2qR7nT4v
In Server Console:
[192.168.1.50:12345] POST /api/random
Request body: {"action":"get_random_string"}
Response: {"status":"success","message":"aB3xK9mP2qR7nT4v",...}
7.4 Troubleshooting
If encountering issues, please refer to the troubleshooting section in README.md.
Appendix: Key File Descriptions
A. Main Program Files
l src/tuya_main.c:
¡ Program entry: tuya_app_main()(line 249)
¡ User main function: user_main()(line 168)
¡ HTTP POST request: __send_http_post_request()(line 59)
¡ Network status callback: __link_status_cb()(line 140)
B. UI Files
l src/ui.c:
¡ UI initialization: ui_http_client_post_init()(line 56)
¡ Button events: button_click_event_cb()(line 40)
¡ UI update functions: ui_update_response_text(), ui_update_wifi_status()
C. Configuration Files
l app_default.config: Application configuration (display, LVGL, etc.)
l CMakeLists.txt: CMake build configuration
l server.py: Python test server
Document Version: 1.0
Last Updated: 2025-01
Comments