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; }