From 32acf80e0d9f50714d6abb579fb004119e8fc610 Mon Sep 17 00:00:00 2001 From: David Montero Date: Sun, 5 Apr 2026 22:14:40 +0200 Subject: [PATCH] fix: propagate has_wifi from compiler to startBoard for reliable WiFi detection Frontend WiFi detection via file-content scanning was unreliable because fileGroups[board.activeFileGroupId] could be an empty array (not null), bypassing the ?? fallback to editorState.files. Fix: the ESP-IDF compiler now returns has_wifi:bool in its compile response. The frontend stores this on the BoardInstance and uses it in startBoard() instead of scanning file contents. The file-content scan is kept as a fallback for boards that haven't been compiled in this session. Co-Authored-By: Claude Sonnet 4.6 --- backend/app/api/routes/compile.py | 2 ++ backend/app/services/espidf_compiler.py | 5 +++- .../src/components/editor/EditorToolbar.tsx | 11 +++++++- frontend/src/services/compilation.ts | 1 + frontend/src/store/useSimulatorStore.ts | 25 +++++++++++-------- frontend/src/types/board.ts | 1 + 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/backend/app/api/routes/compile.py b/backend/app/api/routes/compile.py index 12e86fc..9ee0c64 100644 --- a/backend/app/api/routes/compile.py +++ b/backend/app/api/routes/compile.py @@ -29,6 +29,7 @@ class CompileResponse(BaseModel): hex_content: str | None = None binary_content: str | None = None # base64-encoded .bin for RP2040 binary_type: str | None = None # 'bin' or 'uf2' + has_wifi: bool = False # True when sketch uses WiFi (ESP32 only) stdout: str stderr: str error: str | None = None @@ -63,6 +64,7 @@ async def compile_sketch(request: CompileRequest): hex_content=result.get("hex_content"), binary_content=result.get("binary_content"), binary_type=result.get("binary_type"), + has_wifi=result.get("has_wifi", False), stdout=result.get("stdout", ""), stderr=result.get("stderr", ""), error=result.get("error"), diff --git a/backend/app/services/espidf_compiler.py b/backend/app/services/espidf_compiler.py index 3ac3d52..dc997d6 100644 --- a/backend/app/services/espidf_compiler.py +++ b/backend/app/services/espidf_compiler.py @@ -477,6 +477,8 @@ class ESPIDFCompiler: # QEMU's WiFi AP broadcasts "Velxio-GUEST" on channel 6. # We normalize ANY user SSID → "Velxio-GUEST", enforce channel 6, # and use open auth (empty password) so the connection always works. + # Detect WiFi BEFORE normalization so the flag reflects the original sketch. + has_wifi = self._detect_wifi_usage(main_content) main_content = self._normalize_wifi_for_qemu(main_content) if self.has_arduino: @@ -622,13 +624,14 @@ class ESPIDFCompiler: } binary_b64 = base64.b64encode(merged_path.read_bytes()).decode('ascii') - logger.info(f'[espidf] Compilation successful — {len(binary_b64) // 1024} KB (base64)') + logger.info(f'[espidf] Compilation successful — {len(binary_b64) // 1024} KB (base64), has_wifi={has_wifi}') return { 'success': True, 'hex_content': None, 'binary_content': binary_b64, 'binary_type': 'bin', + 'has_wifi': has_wifi, 'stdout': all_stdout, 'stderr': all_stderr, } diff --git a/frontend/src/components/editor/EditorToolbar.tsx b/frontend/src/components/editor/EditorToolbar.tsx index ae41d92..966e448 100644 --- a/frontend/src/components/editor/EditorToolbar.tsx +++ b/frontend/src/components/editor/EditorToolbar.tsx @@ -49,6 +49,7 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi boards, activeBoardId, compileBoardProgram, + updateBoard, startBoard, stopBoard, resetBoard, @@ -135,6 +136,9 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi const program = result.hex_content ?? result.binary_content ?? null; if (program && activeBoardId) { compileBoardProgram(activeBoardId, program); + if (result.has_wifi !== undefined) { + updateBoard(activeBoardId, { hasWifi: result.has_wifi }); + } } setMessage({ type: 'success', text: 'Compiled successfully' }); markCompiled(); @@ -279,7 +283,12 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi if (result.success) { const program = result.hex_content ?? result.binary_content ?? null; - if (program) compileBoardProgram(board.id, program); + if (program) { + compileBoardProgram(board.id, program); + if (result.has_wifi !== undefined) { + updateBoard(board.id, { hasWifi: result.has_wifi }); + } + } updateStatus({ state: 'success' }); } else { updateStatus({ state: 'error', error: result.stderr || result.error || 'Compilation failed' }); diff --git a/frontend/src/services/compilation.ts b/frontend/src/services/compilation.ts index 554bd29..f557986 100644 --- a/frontend/src/services/compilation.ts +++ b/frontend/src/services/compilation.ts @@ -12,6 +12,7 @@ export interface CompileResult { hex_content?: string; binary_content?: string; // base64-encoded .bin for RP2040 binary_type?: 'bin' | 'uf2'; + has_wifi?: boolean; // True when sketch uses WiFi (ESP32 only) stdout: string; stderr: string; error?: string; diff --git a/frontend/src/store/useSimulatorStore.ts b/frontend/src/store/useSimulatorStore.ts index 045a69c..b95425a 100644 --- a/frontend/src/store/useSimulatorStore.ts +++ b/frontend/src/store/useSimulatorStore.ts @@ -659,17 +659,20 @@ export const useSimulatorStore = create((set, get) => { } esp32Bridge.setSensors(sensors); - // Auto-detect WiFi usage in this board's sketch files. - // Use the board's file group (not the legacy global files array). - const editorState = useEditorStore.getState(); - const boardFiles = editorState.fileGroups[board.activeFileGroupId] - ?? editorState.files; - const hasWifi = boardFiles.some(f => - f.content.includes('#include ') || - f.content.includes('#include ') || - f.content.includes('#include "WiFi.h"') || - f.content.includes('WiFi.begin(') - ); + // Use WiFi flag set by the compiler (most reliable — avoids stale file group issues). + // Fall back to scanning the active file group if the flag hasn't been set yet. + let hasWifi = board.hasWifi; + if (hasWifi === undefined) { + const editorState = useEditorStore.getState(); + const rawFiles = editorState.fileGroups[board.activeFileGroupId]; + const boardFiles = (rawFiles && rawFiles.length > 0) ? rawFiles : editorState.files; + hasWifi = boardFiles.some(f => + f.content.includes('#include ') || + f.content.includes('#include ') || + f.content.includes('#include "WiFi.h"') || + f.content.includes('WiFi.begin(') + ); + } esp32Bridge.wifiEnabled = hasWifi; // Ensure firmware is loaded into the bridge (handles page-refresh case diff --git a/frontend/src/types/board.ts b/frontend/src/types/board.ts index e0d325c..a95824e 100644 --- a/frontend/src/types/board.ts +++ b/frontend/src/types/board.ts @@ -38,6 +38,7 @@ export interface BoardInstance { serialBaudRate: number; serialMonitorOpen: boolean; activeFileGroupId: string; + hasWifi?: boolean; // set by compiler — true when sketch uses WiFi wifiStatus?: WifiStatus; bleStatus?: BleStatus; }