From 6bfeaf1b15032119410025ec01dcc3a34d72296a Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Wed, 29 Jul 2026 19:33:14 +0200 Subject: [PATCH] fix(pi): reiniciar en modo Linux vuelve a arrancar el guest connect() se rendia si el socket no estaba CLOSED, y uno en CLOSING pasa esa prueba: pulsar "Linux terminal" justo despues de una ejecucion cerraba el socket y el arranque siguiente no hacia nada -- ni guest, ni error, y la barra seguia mostrando Stop. Ahora solo se rinde con OPEN o CONNECTING y descarta el que se esta cerrando. startBoard marca ademas running en la rama Pi: el boton de Linux reinicia la placa por su cuenta, sin pasar por la barra, asi que el flag se quedaba con lo que hubiera dejado la ejecucion anterior. --- frontend/src/simulation/RaspberryPi3Bridge.ts | 8 +++++++- frontend/src/store/useSimulatorStore.ts | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/frontend/src/simulation/RaspberryPi3Bridge.ts b/frontend/src/simulation/RaspberryPi3Bridge.ts index dc1e9760..4428f2b1 100644 --- a/frontend/src/simulation/RaspberryPi3Bridge.ts +++ b/frontend/src/simulation/RaspberryPi3Bridge.ts @@ -105,7 +105,13 @@ export class RaspberryPi3Bridge { } connect(): void { - if (this.socket && this.socket.readyState !== WebSocket.CLOSED) return; + const state = this.socket?.readyState; + if (state === WebSocket.OPEN || state === WebSocket.CONNECTING) return; + // A socket in CLOSING is on its way out, not usable: the old guard + // treated it as live and returned, so "restart in Linux mode" right + // after a run silently did nothing — no boot, and the toolbar still + // showing Stop. Drop it and open a fresh one. + this.socket = null; const base = API_BASE(); const wsProtocol = base.startsWith('https') ? 'wss:' : 'ws:'; diff --git a/frontend/src/store/useSimulatorStore.ts b/frontend/src/store/useSimulatorStore.ts index a2cab443..0bf8cea4 100644 --- a/frontend/src/store/useSimulatorStore.ts +++ b/frontend/src/store/useSimulatorStore.ts @@ -1929,11 +1929,18 @@ export const useSimulatorStore = create((set, get) => { // booting a Linux guest (a backend process + ~90 s). The detector // lives in the overlay; `enginePinned` lets the user override it. const decision = decideEngine(boardId, board.enginePinned); + // `running` is set here (not only by the toolbar): the Linux-mode + // button restarts the board directly, and without this the flag + // kept whatever the previous run left, so the UI showed Stop for + // a board that was not running. set((s) => ({ boards: s.boards.map((b) => - b.id === boardId ? { ...b, engineMode: decision.engine } : b, + b.id === boardId + ? { ...b, engineMode: decision.engine, running: true } + : b, ), serialMonitorOpen: true, + ...(s.activeBoardId === boardId ? { running: true } : {}), })); if (decision.engine === 'instant') { const instant = getInstantEngine();