Browse Source

恢复出厂设置功能

moki 1 ngày trước cách đây
mục cha
commit
2ed9da97ef
3 tập tin đã thay đổi với 49 bổ sung29 xóa
  1. 4 4
      docs/BLE_API.md
  2. 7 13
      firmware/README.md
  3. 38 12
      firmware/ai_light/ai_light.ino

+ 4 - 4
docs/BLE_API.md

@@ -88,10 +88,13 @@
 | mqtt_client | string | 否 | AI-Light | MQTT Client ID |
 | mqtt_topic | string | 否 | opencode/status | 订阅主题 |
 | mqtt_status | string | 否 | openCodeLight/status | 状态发布主题 |
-| factory_reset | boolean | 否 | false | 恢复出厂设置,清除所有配置并重启 |
 
 **注意**:所有字段都是可选的,只更新提供的字段,未提供的字段保持原值。
 
+## 恢复出厂设置
+
+连续短按 BOOT 按钮 3 下(1.5 秒内)可恢复出厂设置,清除所有配置并重启。
+
 ## Go 客户端示例
 
 ### 依赖
@@ -379,9 +382,6 @@ func main() {
 		"mqtt_client": "AI-Light",
 		"mqtt_topic": "opencode/status"
 	}`)
-	
-	// 恢复出厂设置
-	ailight.SetConfig(`{"factory_reset": true}`)
 }
 ```
 

+ 7 - 13
firmware/README.md

@@ -85,17 +85,10 @@ mosquitto_pub -h 192.168.1.100 -t "agent/status/config" -m '{
 
 ### 恢复出厂设置
 
-发送 `{"factory_reset": true}` 可清除所有配置并重启:
-
-```bash
-# BLE 方式:向 Config 特征写入
-# {"factory_reset": true}
-
-# MQTT 方式
-mosquitto_pub -h 192.168.1.100 -t "agent/status/config" -m '{"factory_reset": true}'
-```
-
-设备会清除 NVS 中所有配置,重启后进入 BLE 配置模式。
+连续短按 BOOT 按钮 3 下(1.5 秒内)可恢复出厂设置:
+- 红灯闪烁 5 次表示正在清除配置
+- 清除完成后设备自动重启
+- 重启后进入 BLE 配置模式
 
 ## 双模式版
 
@@ -103,7 +96,8 @@ mosquitto_pub -h 192.168.1.100 -t "agent/status/config" -m '{"factory_reset": tr
 
 | 操作 | 效果 |
 |------|------|
-| 运行长按 BOOT 3 秒 | 切换 BLE/MQTT 模式并重启 |
+| 长按 BOOT 3 秒 | 切换 BLE/MQTT 模式并重启 |
+| 连续短按 BOOT 3 下 | 恢复出厂设置(清除所有配置) |
 
 - **开机始终启动 BLE**,可用于灯效控制和 WiFi/MQTT 配置
 - 默认 MQTT 模式,切换后自动保存到 NVS
@@ -165,4 +159,4 @@ ESP32 IO9   -> BOOT 按钮(固定)
 | 只刷写固件(不擦除 flash) | ✅ 保留 |
 | 擦除整个 flash 后刷写 | ❌ 丢失 |
 
-如需完全重置,可通过发送 `{"factory_reset": true}` 或在 Arduino IDE 中擦除 flash。
+如需完全重置,可连续短按 BOOT 按钮 3 下或在 Arduino IDE 中擦除 flash。

+ 38 - 12
firmware/ai_light/ai_light.ino

@@ -13,7 +13,8 @@
 // 功能:
 //   - 开机始终启动 BLE,支持灯效控制 + WiFi/MQTT 配置
 //   - MQTT 模式下同时连接 WiFi/MQTT
-//   - 运行时长按 BOOT 按钮 3 秒 → 切换 BLE/MQTT 模式并重启
+//   - 运行长按 BOOT 按钮 3 秒 → 切换 BLE/MQTT 模式并重启
+//   - 连续短按 BOOT 按钮 3 下 → 恢复出厂设置并重启
 //
 // BLE 配置:
 //   Service:  b8b7e001-7a6b-4f4f-9a8b-11c0ffee0001
@@ -34,8 +35,7 @@
 //     "mqtt_topic_config": "agent/status/config",
 //     "pin_red": 4,
 //     "pin_green": 3,
-//     "pin_yellow": 2,
-//     "factory_reset": true   // 恢复出厂设置,清除所有配置并重启
+//     "pin_yellow": 2
 //   }
 //
 // 接线方式(默认引脚,可通过配置修改):
@@ -75,6 +75,8 @@ const int GREEN_MAX = 220;
 const unsigned long NORMAL_MODE_TIMEOUT_MS = 5UL * 60UL * 1000UL;
 const unsigned long TRAFFIC_MODE_TIMEOUT_MS = 10UL * 60UL * 1000UL;
 const unsigned long LONG_PRESS_MS = 3000;
+const unsigned long TRIPLE_PRESS_WINDOW_MS = 1500;
+const int TRIPLE_PRESS_COUNT = 3;
 
 // =====================================================
 // 全局状态
@@ -159,13 +161,6 @@ void saveConfigFromJson(const String& json) {
     return;
   }
 
-  if (doc.containsKey("factory_reset") && doc["factory_reset"].as<bool>()) {
-    Serial.println("Factory reset! Clearing all config...");
-    preferences.clear();
-    delay(500);
-    ESP.restart();
-  }
-
   if (doc.containsKey("wifi_ssid"))
     preferences.putString("wifi_ssid", doc["wifi_ssid"].as<String>());
   if (doc.containsKey("wifi_pass"))
@@ -444,13 +439,31 @@ void breathingGreen(int times) {
 unsigned long bootPressStart = 0;
 bool bootWasPressed = false;
 bool switchTriggered = false;
+unsigned long lastPressEnd = 0;
+int pressCount = 0;
+
+void factoryReset() {
+  Serial.println("Factory reset! Clearing all config...");
+  allOff();
+  for (int i = 0; i < 5; i++) {
+    setOnly(255, 0, 0); delay(200);
+    allOff(); delay(200);
+  }
+  preferences.clear();
+  Serial.println("NVS cleared. Restarting...");
+  delay(500);
+  ESP.restart();
+}
 
 void checkBootButton() {
   bool pressed = (digitalRead(BUTTON_PIN) == LOW);
+
   if (pressed && !bootWasPressed) {
     bootPressStart = millis();
     bootWasPressed = true;
+    switchTriggered = false;
   }
+
   if (pressed && bootWasPressed && !switchTriggered) {
     if (millis() - bootPressStart >= LONG_PRESS_MS) {
       switchTriggered = true;
@@ -466,9 +479,22 @@ void checkBootButton() {
       ESP.restart();
     }
   }
-  if (!pressed) {
+
+  if (!pressed && bootWasPressed) {
     bootWasPressed = false;
-    switchTriggered = false;
+    unsigned long pressDuration = millis() - bootPressStart;
+    if (pressDuration < LONG_PRESS_MS) {
+      if (millis() - lastPressEnd > TRIPLE_PRESS_WINDOW_MS) {
+        pressCount = 0;
+      }
+      pressCount++;
+      lastPressEnd = millis();
+      Serial.printf("Short press %d/%d\n", pressCount, TRIPLE_PRESS_COUNT);
+      if (pressCount >= TRIPLE_PRESS_COUNT) {
+        pressCount = 0;
+        factoryReset();
+      }
+    }
   }
 }