# Dangerous Pi - Visualization & Guided Workflows Plan **Status**: 🎯 In Planning **Priority**: High (Post-MVP Phase 1) **Target Timeline**: 4-6 weeks implementation **Last Updated**: 2025-11-26 --- ## Executive Summary Dangerous Pi will implement data visualization and guided workflows using **Victory Charts**, a cross-platform charting library that works seamlessly across Web (Remix), React Native (mobile), and Electron (desktop) applications. ### Key Decisions - **Charting Library**: Victory (cross-platform, mobile-first) - **Bundle Impact**: ~50KB (acceptable via code splitting) - **Primary Target**: Mobile/smartphone users (📱 80% of usage) - **Architecture**: Shared components across all platforms --- ## 1. Why Victory Charts? ### Cross-Platform Requirements | Platform | Framework | Victory Package | Rendering | |----------|-----------|-----------------|-----------| | **Web** | Remix.js + React | `victory` | SVG/Canvas | | **Mobile** | React Native | `victory-native` | Native | | **Desktop** | Electron + React | `victory` | SVG/Canvas | **Code Reuse**: ~90% of chart components shared across platforms ### Comparison with Alternatives | Feature | Victory | Chart.js | Recharts | Nivo | |---------|---------|----------|----------|------| | React Native Support | ✅ Native | ❌ None | ⚠️ Wrapper | ❌ None | | Touch Gestures | ✅ Built-in | ⚠️ Limited | ⚠️ Limited | ✅ Good | | Bundle Size | 50KB | 30KB | 45KB | 120KB | | Mobile-First | ✅ Yes | ❌ No | ❌ No | ✅ Yes | | **Score** | **9/10** | 5/10 | 6/10 | 6/10 | **Winner**: Victory (only library with true cross-platform support) --- ## 2. Architecture Overview ### Data Flow ``` Proxmark3 Hardware ↓ USB Pi Zero 2 W Backend (Python) ↓ Execute PM3 command PM3 Python Module (SWIG) ↓ Text output Parser Layer (NEW) ↓ Structured JSON FastAPI Endpoint (Enhanced) ↓ REST/SSE Frontend (Remix/React) ↓ Victory Charts User (Mobile/Desktop) ``` ### New Backend Components #### Parser Module (`app/backend/parsers/pm3_output.py`) ```python """ Convert PM3 text output into structured data for visualization. """ def parse_antenna_tuning(output: str) -> dict: """ Parse hw tune / hf tune / lf tune output. Input: "# LF antenna: 50.00 V @ 125.00 kHz" Output: { "frequency": 125.0, "voltage": 50.0, "type": "lf", "optimal": voltage > 45.0 } """ def parse_waveform_data(output: str) -> dict: """ Parse data samples command output. Output: { "samples": [1, 2, 3, ...], "sample_rate": 48000, "total_samples": 10000 } """ def parse_protocol_trace(output: str) -> dict: """ Parse hf list / lf list output into timeline. Output: { "frames": [ { "timestamp": 1234, "direction": "tag_to_reader", "data": "0x01 0x02", "crc": "ok" }, ... ] } """ def parse_tag_detection(output: str) -> dict: """ Parse hf search / lf search results. Output: { "found": true, "tag_type": "MIFARE Classic 1K", "uid": "01234567", "signal_strength": "good" } """ ``` #### Enhanced API Response ```python # app/backend/api/pm3.py class CommandWithDataResponse(BaseModel): """Enhanced response with visualization data.""" success: bool output: str # Original text (backwards compatible) data: Optional[Dict] = None # Structured data for charts visualization_type: Optional[str] = None # Chart type hint # visualization_type values: "waveform", "tune", "trace", "summary" @router.post("/command-with-data", response_model=CommandWithDataResponse) async def execute_command_with_visualization(request: CommandRequest): """Execute PM3 command and return structured data.""" # Execute command result = await pm3_worker.execute_command(request.command) # Parse output based on command type data = None viz_type = None if request.command.startswith(('hw tune', 'hf tune', 'lf tune')): data = parse_antenna_tuning(result.output) viz_type = "tune" elif request.command.startswith('data'): data = parse_waveform_data(result.output) viz_type = "waveform" elif request.command.startswith(('hf list', 'lf list')): data = parse_protocol_trace(result.output) viz_type = "trace" elif request.command.startswith(('hf search', 'lf search')): data = parse_tag_detection(result.output) viz_type = "summary" return CommandWithDataResponse( success=result.success, output=result.output, data=data, visualization_type=viz_type ) ``` ### Frontend Components #### Shared Chart Library (`app/shared/components/charts/`) **Cross-platform components used by Web + React Native + Electron** ```typescript // TuneChart.tsx import { VictoryLine, VictoryChart, VictoryAxis, VictoryTheme } from 'victory' interface TuneData { frequency: number voltage: number optimal?: boolean } export function TuneChart({ data, title, thresholdVoltage = 40 }: { data: TuneData[], title: string, thresholdVoltage?: number }) { return ( {/* Threshold line */} d.frequency)), y: thresholdVoltage }, { x: Math.max(...data.map(d => d.frequency)), y: thresholdVoltage } ]} style={{ data: { stroke: "#ffaa00", strokeWidth: 1, strokeDasharray: "4,4" } }} /> {/* Actual data */} ) } ``` ```typescript // WaveformChart.tsx import { VictoryLine, VictoryChart, VictoryZoomContainer } from 'victory' export function WaveformChart({ samples }: { samples: number[] }) { // Downsample if > 1000 points for performance const displaySamples = samples.length > 1000 ? downsample(samples, 1000) : samples const data = displaySamples.map((value, index) => ({ x: index, y: value })) return ( } > ) } function downsample(data: number[], targetSize: number): number[] { const step = Math.floor(data.length / targetSize) return data.filter((_, i) => i % step === 0) } ``` --- ## 3. Guided Workflows ### Framework Architecture ```typescript // app/frontend/app/components/GuidedWorkflow.tsx interface WorkflowStep { id: string title: string description: string component: React.ComponentType validation?: (data: any) => boolean helpText?: string } interface StepProps { data: Record onUpdate: (data: Record) => void onComplete: () => void } export function GuidedWorkflow({ steps, onComplete }: { steps: WorkflowStep[], onComplete: (data: any) => void }) { const [currentStep, setCurrentStep] = useState(0) const [stepData, setStepData] = useState>({}) const canProceed = () => { const step = steps[currentStep] return !step.validation || step.validation(stepData) } const CurrentStepComponent = steps[currentStep].component return (
{/* Progress bar */}
{steps.map((step, i) => (
{i < currentStep ? '✓' : i + 1} {step.title}
))}
{/* Current step */}

{steps[currentStep].title}

{steps[currentStep].description}

setStepData({ ...stepData, ...data })} onComplete={() => { if (currentStep < steps.length - 1) { setCurrentStep(currentStep + 1) } else { onComplete(stepData) } }} /> {steps[currentStep].helpText && (
{steps[currentStep].helpText}
)}
{/* Navigation */}
{currentStep > 0 && ( )}
) } ``` ### Priority Workflows to Implement #### 1. HF/LF/HW Tune (Week 1-2) **Steps**: 1. Select frequency type (HF/LF/HW) 2. Run tuning command 3. Display real-time chart 4. Show optimal/warning indicators **Files**: - `app/frontend/app/routes/workflows/tune.tsx` - `app/shared/components/charts/TuneChart.tsx` #### 2. ID Transponder (Week 2-3) **Steps**: 1. Select frequency (HF/LF) 2. Place tag on antenna 3. Run detection command 4. Display tag information card **Files**: - `app/frontend/app/routes/workflows/id-tag.tsx` - Component: Tag info card with icon #### 3. Clone MIFARE Classic 1K (Week 3-4) **Steps**: 1. Tune HF antenna 2. Read source card (64 blocks) 3. Verify read success 4. Write to target card 5. Verify write success **Files**: - `app/frontend/app/routes/workflows/clone-mifare.tsx` - Progress tracking component #### 4. Clone to T5577 (Week 4-5) **Steps**: 1. Tune LF antenna 2. Read source tag 3. Configure T5577 settings 4. Write to T5577 5. Verify clone **Files**: - `app/frontend/app/routes/workflows/clone-t5577.tsx` #### 5. Sniffing Utility (Week 5-6) **Steps**: 1. Configure sniffing parameters 2. Start capture 3. Real-time frame display 4. Stop capture 5. Analyze captured data **Files**: - `app/frontend/app/routes/workflows/sniff.tsx` - `app/shared/components/charts/ProtocolTimeline.tsx` --- ## 4. Implementation Roadmap ### Phase 1: Foundation (Week 1) **Backend**: - [ ] Create `app/backend/parsers/pm3_output.py` - [ ] Implement antenna tuning parser - [ ] Add `/api/pm3/command-with-data` endpoint - [ ] Write parser unit tests **Frontend**: - [ ] Install Victory: `npm install victory` - [ ] Create `app/shared/components/charts/` directory - [ ] Implement `TuneChart.tsx` - [ ] Test with mock data **Deliverable**: Working HF/LF tune visualization ### Phase 2: Guided Workflows (Week 2-3) **Frontend**: - [ ] Create `GuidedWorkflow.tsx` framework - [ ] Implement HF/LF Tune workflow - [ ] Implement ID Transponder workflow - [ ] Add progress indicators - [ ] Mobile touch optimization **Deliverable**: Two working guided workflows ### Phase 3: Advanced Workflows (Week 3-4) **Backend**: - [ ] Implement waveform parser - [ ] Implement trace parser - [ ] Add streaming support for sniffing **Frontend**: - [ ] Clone MIFARE Classic workflow - [ ] Clone T5577 workflow - [ ] `WaveformChart.tsx` with pan/zoom - [ ] Progress tracking components **Deliverable**: Complete cloning workflows ### Phase 4: Sniffing & Polish (Week 5-6) **Frontend**: - [ ] Sniffing utility implementation - [ ] `ProtocolTimeline.tsx` chart - [ ] Real-time data streaming - [ ] Export capabilities (CSV/JSON) **Polish**: - [ ] Performance optimization - [ ] Code splitting setup - [ ] Mobile gesture improvements - [ ] Accessibility improvements **Deliverable**: Production-ready visualization system --- ## 5. Bundle Size Management ### Code Splitting Strategy ```typescript // Lazy load charts only when needed import { lazy, Suspense } from 'react' const TuneChart = lazy(() => import('~/shared/components/charts/TuneChart')) function TunePage() { return ( Loading chart...}> ) } ``` ### Bundle Impact Analysis | Component | Size (gzipped) | When Loaded | |-----------|----------------|-------------| | Base App | ~120KB | Initial | | Victory Core | +35KB | On-demand | | TuneChart | +5KB | Workflow page | | WaveformChart | +8KB | Workflow page | | **Total (worst case)** | **~170KB** | ✅ Acceptable | **Optimization**: Most users won't load all charts in one session. --- ## 6. Cross-Platform Strategy ### React Native App (Future) ```typescript // Same component, different import! // Web version (Remix) import { VictoryLine } from 'victory' // React Native version import { VictoryLine } from 'victory-native' // Component code is IDENTICAL export function TuneChart({ data }) { return ( ) } ``` ### BLE Integration for Mobile Enhanced BLE Manager will support: - Command execution via BLE (offline PM3 operations) - Status queries via BLE - Guided workflow triggers via BLE - Real-time data streaming via BLE **Use Case**: User operates PM3 with phone via BLE, no WiFi needed. --- ## 7. Testing Strategy ### Backend Parser Tests ```python # test_pm3_parsers.py def test_parse_antenna_tuning(): output = "# LF antenna: 50.00 V @ 125.00 kHz" result = parse_antenna_tuning(output) assert result["voltage"] == 50.0 assert result["frequency"] == 125.0 assert result["optimal"] == True # > 45V threshold ``` ### Frontend Chart Tests ```typescript // Mock data testing (no hardware needed) const mockTuneData = [ { frequency: 120, voltage: 45 }, { frequency: 125, voltage: 50 }, { frequency: 130, voltage: 48 } ] test('TuneChart renders with mock data', () => { render() expect(screen.getByText(/Voltage/)).toBeInTheDocument() }) ``` ### Mobile Touch Testing - Test on actual smartphone (iPhone/Android) - Verify pinch-zoom works smoothly - Check 44px touch target compliance - Test landscape orientation --- ## 8. Dependencies ### NPM Packages ```json { "dependencies": { "victory": "^37.0.0", // ~35KB gzipped "victory-native": "^37.0.0" // For React Native (later) } } ``` ### Python Packages No new dependencies - use standard library for parsing. --- ## 9. Success Metrics ### Technical - [ ] Bundle size stays under 200KB (gzipped) - [ ] Charts render in < 200ms on mobile - [ ] Touch gestures work smoothly (60fps) - [ ] Parser accuracy > 95% for all PM3 commands ### UX - [ ] Users complete workflows 80% faster than manual commands - [ ] Mobile users can operate PM3 with one hand - [ ] Reduce support requests by 50% (guided workflows) --- ## 10. Future Enhancements ### After Initial Implementation 1. **Waveform Annotations** - Mark interesting signal features - Save/load annotated captures 2. **Chart Exports** - Export as PNG/SVG - Export data as CSV/JSON - Share via mobile apps 3. **Advanced Analytics** - Signal quality metrics - Antenna tuning history tracking - Success rate statistics 4. **Offline Support** - Cache chart data locally - Service worker for offline workflows - Sync when reconnected --- ## Summary **Victory Charts** provides the perfect foundation for Dangerous Pi's visualization needs: - ✅ True cross-platform support (Web, Mobile, Desktop) - ✅ Mobile-first with touch gestures built-in - ✅ Shared components = faster development - ✅ Acceptable bundle size with code splitting - ✅ Perfect for guided workflow UX **Next Step**: Begin Phase 1 implementation (Backend parsers + Victory setup) **Questions?** See [UI_GUIDELINES.md](UI_GUIDELINES.md) for styling and [claude.md](claude.md) for architecture details.