Raspberri pi 4 y 5

This commit is contained in:
David Montero Crespo 2026-06-15 11:57:10 -03:00
parent 6e468e1a30
commit cf6a609671
13 changed files with 49 additions and 17 deletions

View File

@ -196,6 +196,26 @@ describe('useEditorStore — file groups', () => {
expect(updated['group-raspberry-pi-3'][0].name).toMatch(/\.py$/);
});
// Regression: every Linux Pi (not just the 3) must default to a Python file
// and the Pi workspace, never the Arduino sketch. The Pico (RP2040) is a
// microcontroller and must stay on .ino.
it.each(['raspberry-pi-zero', 'raspberry-pi-1', 'raspberry-pi-2', 'raspberry-pi-4', 'raspberry-pi-5'])(
'createFileGroup creates a .py file for %s',
(kind) => {
const { createFileGroup } = useEditorStore.getState();
createFileGroup(`group-${kind}`);
const updated = useEditorStore.getState().fileGroups;
expect(updated[`group-${kind}`][0].name).toMatch(/\.py$/);
},
);
it('createFileGroup keeps the Raspberry Pi Pico on a .ino sketch (not Linux)', () => {
const { createFileGroup } = useEditorStore.getState();
createFileGroup('group-raspberry-pi-pico');
const updated = useEditorStore.getState().fileGroups;
expect(updated['group-raspberry-pi-pico'][0].name).toMatch(/\.ino$/);
});
it('createFileGroup accepts custom initial files', () => {
const { createFileGroup } = useEditorStore.getState();
createFileGroup('group-custom', [

View File

@ -13,6 +13,7 @@ import { VirtualFileSystem } from './VirtualFileSystem';
import { useVfsStore } from '../../store/useVfsStore';
import { getBoardBridge, useSimulatorStore } from '../../store/useSimulatorStore';
import { attachSlavesFromCanvas } from '../../simulation/piSlaveScanner';
import { boardDisplayName } from '../../types/board';
// Lazy-load PiTerminal so @xterm/xterm is only bundled when needed
const PiTerminal = lazy(() => import('./PiTerminal').then((m) => ({ default: m.PiTerminal })));
@ -37,6 +38,10 @@ export const RaspberryPiWorkspace: React.FC<RaspberryPiWorkspaceProps> = ({ boar
const setContent = useVfsStore((s) => s.setContent);
const getNode = useVfsStore((s) => s.getNode);
// Display the active board's real name (Pi 3B / 4B / 5 / Zero / …) instead of
// a hardcoded "Raspberry Pi 3B" — the workspace serves the whole Pi family.
const boardLabel = board ? boardDisplayName(board) : 'Raspberry Pi';
// Auto-connect terminal when board starts running
useEffect(() => {
if (!board?.running) {
@ -127,7 +132,7 @@ export const RaspberryPiWorkspace: React.FC<RaspberryPiWorkspaceProps> = ({ boar
<div style={styles.main}>
{/* Pi-specific toolbar */}
<div style={styles.toolbar}>
<span style={styles.toolbarTitle}>Raspberry Pi 3B</span>
<span style={styles.toolbarTitle}>{boardLabel}</span>
<div style={styles.toolbarActions}>
{/* Status indicator */}
<span
@ -218,7 +223,7 @@ export const RaspberryPiWorkspace: React.FC<RaspberryPiWorkspaceProps> = ({ boar
<div style={styles.offlineOverlay}>
<div style={styles.offlineBox}>
<div style={styles.offlineIcon}>🖥</div>
<div style={styles.offlineTitle}>{t('editor.pi.offlineTitle')}</div>
<div style={styles.offlineTitle}>{t('editor.pi.offlineTitle', { board: boardLabel })}</div>
<div style={styles.offlineSubtitle}>{t('editor.pi.offlineSubtitle')}</div>
<button style={styles.startBtn} onClick={() => startBoard(boardId)}>
{t('editor.pi.startPi')}

View File

@ -277,7 +277,7 @@
"disconnect": "Trennen",
"terminal": "Terminal",
"close": "Schließen",
"offlineTitle": "Raspberry Pi 3B ist ausgeschaltet",
"offlineTitle": "{{board}} ist ausgeschaltet",
"offlineSubtitle": "Starten Sie den Pi, um ein Terminal zu öffnen und mit dem Linux-System zu interagieren.",
"offlineNote1": "Hinweis: Der Dateiexplorer zeigt einen Staging-Bereich an.",
"offlineNote2": "Verwenden Sie „Auf Pi hochladen“ nach dem Start, um Dateien auf den laufenden Pi zu übertragen.",

View File

@ -279,7 +279,7 @@
"disconnect": "Disconnect",
"terminal": "Terminal",
"close": "Close",
"offlineTitle": "Raspberry Pi 3B is powered off",
"offlineTitle": "{{board}} is powered off",
"offlineSubtitle": "Start the Pi to open a terminal and interact with the Linux system.",
"offlineNote1": "Note: The file explorer shows a staging area.",
"offlineNote2": "Use \"Upload to Pi\" after starting to transfer files to the running Pi.",

View File

@ -279,7 +279,7 @@
"disconnect": "Desconectar",
"terminal": "Terminal",
"close": "Cerrar",
"offlineTitle": "Raspberry Pi 3B está apagada",
"offlineTitle": "{{board}} está apagada",
"offlineSubtitle": "Inicia la Pi para abrir un terminal e interactuar con el sistema Linux.",
"offlineNote1": "Nota: El explorador de archivos muestra un área de preparación.",
"offlineNote2": "Usa \"Subir a Pi\" después de iniciar para transferir archivos a la Pi en ejecución.",

View File

@ -277,7 +277,7 @@
"disconnect": "Déconnecter",
"terminal": "Terminal",
"close": "Fermer",
"offlineTitle": "Raspberry Pi 3B est éteint",
"offlineTitle": "{{board}} est éteint",
"offlineSubtitle": "Démarrez le Pi pour ouvrir un terminal et interagir avec le système Linux.",
"offlineNote1": "Remarque : L'explorateur de fichiers affiche une zone de préparation.",
"offlineNote2": "Utilisez \"Téléverser vers Pi\" après le démarrage pour transférer des fichiers vers le Pi en cours d'exécution.",

View File

@ -277,7 +277,7 @@
"disconnect": "Disconnetti",
"terminal": "Terminale",
"close": "Chiudi",
"offlineTitle": "Raspberry Pi 3B è spento",
"offlineTitle": "{{board}} è spento",
"offlineSubtitle": "Avvia il Pi per aprire un terminale e interagire con il sistema Linux.",
"offlineNote1": "Nota: L'esplora file mostra un'area di staging.",
"offlineNote2": "Usa \"Carica su Pi\" dopo l'avvio per trasferire file al Pi in esecuzione.",

View File

@ -277,7 +277,7 @@
"disconnect": "切断",
"terminal": "端末",
"close": "閉じる",
"offlineTitle": "Raspberry Pi 3B の電源がオフです",
"offlineTitle": "{{board}} の電源がオフです",
"offlineSubtitle": "Pi を起動して端末を開き、Linux システムと対話します。",
"offlineNote1": "注: ファイルエクスプローラはステージング領域を表示します。",
"offlineNote2": "起動後、「Pi にアップロード」を使用してファイルを実行中の Pi に転送します。",

View File

@ -279,7 +279,7 @@
"disconnect": "Desconectar",
"terminal": "Terminal",
"close": "Fechar",
"offlineTitle": "Raspberry Pi 3B está desligado",
"offlineTitle": "{{board}} está desligado",
"offlineSubtitle": "Inicie o Pi para abrir um terminal e interagir com o sistema Linux.",
"offlineNote1": "Nota: O explorador de arquivos mostra uma área de preparação.",
"offlineNote2": "Use \"Enviar para Pi\" após iniciar para transferir arquivos para o Pi em execução.",

View File

@ -277,7 +277,7 @@
"disconnect": "Отключиться",
"terminal": "Терминал",
"close": "Закрыть",
"offlineTitle": "Raspberry Pi 3B выключен",
"offlineTitle": "{{board}} выключен",
"offlineSubtitle": "Запустите Pi, чтобы открыть терминал и взаимодействовать с системой Linux.",
"offlineNote1": "Примечание: Проводник файлов показывает промежуточную область.",
"offlineNote2": "Используйте «Загрузить на Pi» после запуска для передачи файлов на работающий Pi.",

View File

@ -279,7 +279,7 @@
"disconnect": "断开",
"terminal": "终端",
"close": "关闭",
"offlineTitle": "Raspberry Pi 3B 已关机",
"offlineTitle": "{{board}} 已关机",
"offlineSubtitle": "启动 Pi 以打开终端并与 Linux 系统交互。",
"offlineNote1": "注意:文件浏览器显示暂存区域。",
"offlineNote2": "启动后使用“上传到 Pi”将文件传输到正在运行的 Pi。",

View File

@ -31,6 +31,7 @@ import { useOscilloscopeStore } from '../store/useOscilloscopeStore';
import { useProjectStore } from '../store/useProjectStore';
import { useAutoSaveProject } from '../hooks/useAutoSaveProject';
import type { CompilationLog } from '../utils/compilationLogger';
import { isPiBoardKind } from '../types/board';
import '../App.css';
const MOBILE_BREAKPOINT = 768;
@ -77,7 +78,9 @@ export const EditorPage: React.FC = () => {
const activeBoardKind = useSimulatorStore(
(s) => s.boards.find((b) => b.id === s.activeBoardId)?.boardKind,
);
const isRaspberryPi3 = activeBoardKind === 'raspberry-pi-3';
// Pi 3/4/5 and Zero/1/2 all run the QEMU Linux workspace (terminal + Python),
// not the Arduino/Monaco editor. Pico (RP2040) is browser-emulated, not a Pi here.
const isLinuxPi = isPiBoardKind(activeBoardKind ?? '');
const oscilloscopeOpen = useOscilloscopeStore((s) => s.open);
const [consoleOpen, setConsoleOpen] = useState(false);
// compileLogs live in a Zustand store so the velxio-pro agent overlay
@ -459,7 +462,7 @@ export const EditorPage: React.FC = () => {
setConsoleOpen={setConsoleOpen}
compileLogs={compileLogs}
setCompileLogs={setCompileLogs}
centerSlot={!isRaspberryPi3 ? <FileTabs /> : null}
centerSlot={!isLinuxPi ? <FileTabs /> : null}
/>
</div>
<div className="unified-toolbar-canvas" ref={setCanvasHeaderSlot} />
@ -540,7 +543,7 @@ export const EditorPage: React.FC = () => {
setConsoleOpen={setConsoleOpen}
compileLogs={compileLogs}
setCompileLogs={setCompileLogs}
centerSlot={!isRaspberryPi3 ? <FileTabs /> : null}
centerSlot={!isLinuxPi ? <FileTabs /> : null}
/>
</div>
</div>
@ -548,7 +551,7 @@ export const EditorPage: React.FC = () => {
{/* Editor area: Pi workspace or Monaco editor */}
<div className="editor-wrapper" style={{ flex: 1, overflow: 'hidden', minHeight: 0 }}>
{isRaspberryPi3 && activeBoardId ? (
{isLinuxPi && activeBoardId ? (
<Suspense
fallback={
<div style={{ color: '#666', padding: 16, fontSize: 12 }}>

View File

@ -348,8 +348,12 @@ export const useEditorStore = create<EditorState>((set, get) => ({
modified: false,
}));
} else {
// Determine default file by group name convention or language mode
const isPi = groupId.includes('raspberry-pi-3');
// Determine default file by group name convention or language mode.
// All Linux Pi boards (Zero/1/2/3/4/5) default to script.py; the Pico
// (RP2040) is browser-emulated and not a Linux Pi. Mirrors
// isPiBoardKind() in types/board.ts, adapted to the `group-<id>` convention.
const isPi =
groupId.includes('raspberry-pi-') && !groupId.includes('raspberry-pi-pico');
const isMicroPython = languageMode === 'micropython';
const mainId = `${groupId}-main`;
let fileName: string;