Merge pull request #20 from electron-rare/codex/rtc-zeroclaw-orchestration-issue-18

[codex] fix esp32dev web init crash and restore STATUS payload
This commit was merged in pull request #20.
This commit is contained in:
Clément SAILLANT
2026-02-21 03:09:10 +01:00
committed by GitHub
4 changed files with 139 additions and 1 deletions
+71
View File
@@ -0,0 +1,71 @@
{
"timestamp_utc": "2026-02-21T03:15:00Z",
"scope": "esp32_audio_dev_a252_only",
"overall_passed": true,
"bench_context": {
"active_env": "esp32dev",
"flash_port": "/dev/cu.SLAB_USBtoUART",
"s3_present": false
},
"results": [
{
"name": "ZeroClaw preflight",
"passed": true,
"details": {
"command": "python3 scripts/zeroclaw_hw_preflight.py --require-port --zeroclaw-bin /Users/cils/Documents/Lelectron_rare/Kill_LIFE/zeroclaw/target/release/zeroclaw",
"ports_seen": [
"/dev/tty.SLAB_USBtoUART",
"/dev/tty.usbserial-0001",
"/dev/tty.usbmodem5AB90753301"
]
}
},
{
"name": "esp32dev build",
"passed": true,
"details": {
"command": "pio run -e esp32dev"
}
},
{
"name": "esp32dev upload",
"passed": true,
"details": {
"command": "pio run -e esp32dev -t upload --upload-port /dev/cu.SLAB_USBtoUART"
}
},
{
"name": "serial smoke",
"passed": true,
"details": {
"ping": "PONG",
"status_keys": [
"board_profile",
"telephony",
"hook",
"full_duplex",
"audio_drop_frames"
],
"status_snapshot": {
"board_profile": "ESP32_A252",
"full_duplex": true,
"audio_drop_frames": 0
}
}
},
{
"name": "startup stability",
"passed": true,
"details": {
"fixed_issue": "lwIP Invalid mbox reboot loop",
"evidence": [
"[RTC_BL_PHONE] AP ready: ssid=RTC_BL_PHONE ip=192.168.4.1",
"[WebServerManager] HTTP server started"
]
}
}
],
"notes": [
"Run execute on ESP32 audio dev only; S3 validation skipped for this bench."
]
}
+31
View File
@@ -45,3 +45,34 @@ Tous les modules ont été testés individuellement et en intégration. Les rés
Tous les modules sont validés, robustes et intégrés. La traçabilité, la sécurité et la documentation sont assurées. Prêt pour la phase suivante ou la livraison.
**Version :** 2026-02-17
---
## Campagne terrain ZeroClaw — 2026-02-21 (ESP32 audio dev)
Contexte:
- Cible active: `esp32dev` (ESP32 audio dev)
- Port flash: `/dev/cu.SLAB_USBtoUART`
- Scope: terminal build/flash/smoke, sans carte S3 sur ce bench
Resultats:
- Preflight ZeroClaw USB: OK
- Build `pio run -e esp32dev`: OK
- Upload `pio run -e esp32dev -t upload --upload-port /dev/cu.SLAB_USBtoUART`: OK
- Smoke serie:
- `PING` => `PONG` (OK)
- `STATUS` => JSON complet (OK)
Incident corrige pendant la campagne:
- Reboot loop `lwIP Invalid mbox` au demarrage web.
- Cause: `AsyncWebServer::begin()` lance avant init reseau.
- Correctif applique:
- init Wi-Fi AP (`RTC_BL_PHONE`) avant `g_web.begin()`
- correction payload `STATUS` (`doc.as<JsonObject>()` au lieu de `doc.to<JsonObject>()`)
Verdict campagne 2026-02-21:
- PASS pour le flux `esp32dev` en terminal.
+23
View File
@@ -45,3 +45,26 @@ Si credentials manquants, choisir un provider:
3. Patch minimal RTC.
4. Tests locaux ciblés.
5. PR dédiée RTC avec logs/artefacts.
## 4) Run local ESP32 audio dev (A252 only)
Contexte bench actuel: carte `esp32dev` (audio dev), sans cible S3 connectee.
Commande de reference:
```bash
cd /Users/cils/Documents/Lelectron_rare/RTC_BL_PHONE
python3 scripts/zeroclaw_hw_preflight.py --require-port --zeroclaw-bin /Users/cils/Documents/Lelectron_rare/Kill_LIFE/zeroclaw/target/release/zeroclaw
pio run -e esp32dev
pio run -e esp32dev -t upload --upload-port /dev/cu.SLAB_USBtoUART
```
Smoke terminal attendu:
- `PING` => `PONG`
- `STATUS` => JSON avec `board_profile`, `telephony`, `hook`, `full_duplex`, metriques audio.
Note technique:
- Sur `esp32dev`, il faut initialiser le stack reseau avant `AsyncWebServer::begin()`
pour eviter le crash `lwIP Invalid mbox`.
+14 -1
View File
@@ -1,5 +1,6 @@
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include "audio/AudioEngine.h"
#include "core/PlatformProfile.h"
@@ -59,7 +60,7 @@ void printStatusLine() {
doc["telephony"] = telephonyStateToString(g_telephony.state());
doc["hook"] = g_slic.isHookOff() ? "OFF_HOOK" : "ON_HOOK";
doc["full_duplex"] = g_audio.supportsFullDuplex();
appendAudioMetrics(doc.to<JsonObject>());
appendAudioMetrics(doc.as<JsonObject>());
String payload;
serializeJson(doc, payload);
Serial.println(payload);
@@ -186,6 +187,18 @@ void setup() {
g_telephony.begin(g_profile, g_slic, g_audio);
// Ensure LWIP/tcpip stack is initialized before AsyncWebServer starts.
if (WiFi.getMode() == WIFI_MODE_NULL) {
const bool mode_ok = WiFi.mode(WIFI_AP);
const bool ap_ok = mode_ok && WiFi.softAP("RTC_BL_PHONE");
if (ap_ok) {
Serial.printf("[RTC_BL_PHONE] AP ready: ssid=RTC_BL_PHONE ip=%s\n",
WiFi.softAPIP().toString().c_str());
} else {
Serial.println("[RTC_BL_PHONE] WARN: WiFi AP init failed; web server may be unavailable");
}
}
g_web.setRateLimitMs(1000);
g_web.setAuthEnabled(false);
g_web.setControlCallback(onWebControl);