import { createSignal, createEffect, For, Show, onCleanup } from 'solid-js'; import { invoke } from '@tauri-apps/api/core'; interface BoardInfo { fullname: string; host: string; address: string; port: number; connect_status: string; } interface TestPattern { name: string; description: string; effect_type: string; } interface TestEffectConfig { effect_type: string; led_count: number; led_type: string; speed: number; } export const LedStripTest = () => { const [boards, setBoards] = createSignal([]); const [selectedBoard, setSelectedBoard] = createSignal(null); const [ledCount, setLedCount] = createSignal(60); const [ledType, setLedType] = createSignal<'RGB' | 'RGBW'>('RGB'); const [isRunning, setIsRunning] = createSignal(false); const [currentPattern, setCurrentPattern] = createSignal(null); const [animationSpeed, setAnimationSpeed] = createSignal(33); // ~30fps // Load available boards createEffect(() => { invoke('get_boards').then((boardList) => { setBoards(boardList); if (boardList.length > 0 && !selectedBoard()) { setSelectedBoard(boardList[0]); } }).catch((error) => { console.error('Failed to load boards:', error); }); }); // Cleanup when component is unmounted onCleanup(() => { if (isRunning() && selectedBoard()) { // Stop the test effect in backend invoke('stop_led_test_effect', { boardAddress: `${selectedBoard()!.address}:${selectedBoard()!.port}`, ledCount: ledCount(), ledType: ledType() }).catch((error) => { console.error('Failed to stop test during cleanup:', error); }); // Update local state immediately setIsRunning(false); setCurrentPattern(null); } }); // Test patterns const testPatterns: TestPattern[] = [ { name: '流光效果', description: '彩虹色流光,用于测试灯带方向', effect_type: 'FlowingRainbow' }, { name: '十个一组计数', description: '每十个LED一组不同颜色,用于快速计算灯珠数量', effect_type: 'GroupCounting' }, { name: '单色扫描', description: '单个LED依次点亮,用于精确测试每个LED位置', effect_type: 'SingleScan' }, { name: '呼吸灯', description: '整条灯带呼吸效果,用于测试整体亮度', effect_type: 'Breathing' } ]; // Test effect management - now handled by Rust backend const startTest = async (pattern: TestPattern) => { if (isRunning()) { await stopTest(); } if (!selectedBoard()) { console.error('No board selected'); return; } try { const effectConfig: TestEffectConfig = { effect_type: pattern.effect_type, led_count: ledCount(), led_type: ledType(), speed: 1.0 / (animationSpeed() / 50) // Convert animation speed to effect speed }; // Start the test effect in Rust backend await invoke('start_led_test_effect', { boardAddress: `${selectedBoard()!.address}:${selectedBoard()!.port}`, effectConfig: effectConfig, updateIntervalMs: animationSpeed() }); setCurrentPattern(pattern); setIsRunning(true); } catch (error) { console.error('Failed to start test effect:', error); } }; const stopTest = async () => { if (!selectedBoard()) { setIsRunning(false); setCurrentPattern(null); return; } try { // Stop the test effect in Rust backend await invoke('stop_led_test_effect', { boardAddress: `${selectedBoard()!.address}:${selectedBoard()!.port}`, ledCount: ledCount(), ledType: ledType() }); // Only update UI state after successful backend call setIsRunning(false); setCurrentPattern(null); } catch (error) { console.error('Failed to stop test effect:', error); // Still update UI state even if backend call fails setIsRunning(false); setCurrentPattern(null); } }; return (

LED Strip Testing

{/* Hardware Selection */}
{/* LED Configuration */}
setLedCount(parseInt(e.target.value) || 60)} />
setAnimationSpeed(parseInt(e.target.value) || 33)} />
{/* Test Patterns */}

Test Patterns

{(pattern) => (

{pattern.name}

{pattern.description}

startTest(pattern)} disabled={!selectedBoard()} > Start Test } >
)}
Test pattern "{currentPattern()?.name}" is running on {selectedBoard()?.host}
Please select a hardware board to start testing
); };