فهرست منبع

fix: HTTP Web Modbus 设备参数设置 bug 修复

Coze-Commit-Type: user
Coze-User-ID: 256649704250362
Coze-Conversation-ID: 11640025
steven_roc 1 ماه پیش
والد
کامیت
4087a0316a
3فایلهای تغییر یافته به همراه56 افزوده شده و 11 حذف شده
  1. 33 0
      mppt_monitor/CHANGELOG.md
  2. BIN
      mppt_monitor/build/mppt_monitor
  3. 23 11
      mppt_monitor/src/web_server.c

+ 33 - 0
mppt_monitor/CHANGELOG.md

@@ -4,6 +4,39 @@
 
 ---
 
+## [2.3.1] - 2026-08-28
+
+### Bug 修复 - HTTP Web Modbus 设备参数设置
+
+**修复内容**:
+
+1. **添加设备地址范围验证**
+   - 问题:未验证 device_addr 范围,可能发送无效地址
+   - 修复:添加 1-247 范围检查,返回明确错误信息
+
+2. **优化 Modbus 连接检查顺序**
+   - 问题:验证逻辑在连接检查之前执行,导致混淆的错误信息
+   - 修复:将 Modbus 连接检查移到参数验证之前
+   - 效果:设备离线时直接返回 "Modbus not connected",不再执行无效验证
+
+3. **统一错误响应格式**
+   - 所有错误响应添加 CORS 头 `Access-Control-Allow-Origin: *`
+   - 确保浏览器跨域请求能正确读取错误信息
+
+**验证结果**:
+| 测试场景 | 预期结果 | 实际结果 |
+|---------|---------|---------|
+| 有效参数 + 设备离线 | Modbus not connected | ✅ |
+| device_addr=0 | Invalid device_addr | ✅ |
+| device_addr=248 | Invalid device_addr | ✅ |
+| 无效参数名 | Modbus not connected (先检查连接) | ✅ |
+| 缺少字段 | Missing fields | ✅ |
+| 空请求体 | Empty request body | ✅ |
+| GET 请求 | 返回可写参数列表 | ✅ |
+| OPTIONS 预检 | 204 + CORS 头 | ✅ |
+
+---
+
 ## [2.3.0] - 2026-08-27
 
 ### 升级 mongoose 7.22 → 7.23

BIN
mppt_monitor/build/mppt_monitor


+ 23 - 11
mppt_monitor/src/web_server.c

@@ -237,6 +237,25 @@ static void handle_api_settings(struct mg_connection *c, struct mg_http_message
     char param_copy[64];
     snprintf(param_copy, sizeof(param_copy), "%s", param);
 
+    /* Validate device address (0-247) */
+    if (dev_addr == 0 || dev_addr > 247) {
+        char err_msg[128];
+        snprintf(err_msg, sizeof(err_msg),
+                 "{\"error\":\"Invalid device_addr: %d. Must be 1-247.\"}", dev_addr);
+        cJSON_Delete(req);
+        mg_http_reply(c, 400, "Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n",
+                      "%s", err_msg);
+        return;
+    }
+
+    /* Check if Modbus is connected BEFORE validation */
+    if (!g_ctx.modbus || !g_ctx.modbus->connected) {
+        cJSON_Delete(req);
+        mg_http_reply(c, 503, "Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n",
+                      "{\"error\":\"Modbus not connected. Please check device connection.\"}");
+        return;
+    }
+
     /* Map parameter name to register address */
     uint16_t reg_addr = 0xFFFF;
     const char *param_desc = "";
@@ -260,7 +279,7 @@ static void handle_api_settings(struct mg_connection *c, struct mg_http_message
         param_desc = "充电模式";
     } else {
         cJSON_Delete(req);
-        mg_http_reply(c, 400, "Content-Type: application/json\r\n",
+        mg_http_reply(c, 400, "Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n",
                       "{\"error\":\"Unknown param. Valid: battery_type, battery_level, "
                       "charge_current_limit, full_charge_voltage, device_address, charge_mode\"}");
         return;
@@ -273,22 +292,15 @@ static void handle_api_settings(struct mg_connection *c, struct mg_http_message
         current_battery_type = dev_data.battery_type_raw;
     }
 
-    /* Validate */
+    /* Validate value range */
     if (modbus_validate_setting(reg_addr, value, current_battery_type) != 0) {
         char err_msg[256];
         snprintf(err_msg, sizeof(err_msg),
                  "{\"error\":\"Invalid value for %s (reg 0x%04X). Value %u out of range.\"}",
                  param_copy, reg_addr, value);
         cJSON_Delete(req);
-        mg_http_reply(c, 400, "Content-Type: application/json\r\n", "%s", err_msg);
-        return;
-    }
-
-    /* Check if Modbus is connected */
-    if (!g_ctx.modbus || !g_ctx.modbus->connected) {
-        cJSON_Delete(req);
-        mg_http_reply(c, 503, "Content-Type: application/json\r\n",
-                      "{\"error\":\"Modbus not connected\"}");
+        mg_http_reply(c, 400, "Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n",
+                      "%s", err_msg);
         return;
     }