Add Dangerous Pi MVP implementation - complete backend and system integration
This commit adds the complete Dangerous Pi web management interface with all MVP features implemented and tested locally. ## New Features ### Backend (Python + FastAPI) - Complete FastAPI backend with async support - 40+ API endpoints (Health, PM3, WiFi, Updates, UPS, BLE, Plugins) - 6 managers: Session, WiFi, Update, UPS, BLE, Plugin - SQLite database with sessions, config, history, crash reports - Server-Sent Events (SSE) for real-time notifications - Mock PM3 worker for development without hardware ### WiFi Manager - Interface detection (USB vs built-in) - Network scanning with signal strength - Mode switching (AP/Client/Dual/Auto/Off) - Network connection with password support - Hidden SSID and saved networks support - Static IP and DHCP configuration - 10 WiFi API endpoints ### Update Manager - GitHub releases API integration - Automatic periodic update checks - Semantic version comparison - Update download with progress tracking - SHA256 checksum verification - Automatic installation with backup and rollback - PM3 client rebuild after updates - 6 Update API endpoints ### UPS Manager - I2C battery monitoring (MAX17040-compatible) - Battery percentage, voltage, current tracking - Power source detection (AC/Battery) - Safe shutdown triggers at configurable thresholds - Event callbacks for battery warnings - SSE and BLE notification integration - 3 UPS API endpoints ### BLE Manager - Bluetooth Low Energy notification support - Auto-detects BLE capability - Multiple notification types (updates, battery, shutdown, etc.) - BLE advertising management - Device connection tracking - 4 BLE API endpoints ### Plugin Framework - Dynamic plugin loading/unloading - Plugin lifecycle management (load, enable, disable, unload) - Hook system for extensibility - JSON-based metadata - Example "Hello World" plugin included - 7 Plugin API endpoints ### Frontend (Remix.js + React) - Cyberpunk-themed responsive UI - Dashboard with system status - PM3 command interface with history - Settings page with WiFi and Update management - Command logs viewer - Theme toggle (Dark/Light/Auto) - Server-side rendering (SSR) - Mobile-first responsive design ### System Integration - Systemd service with security hardening - Automated install/uninstall scripts - Environment configuration template - Hardware access groups (i2c, bluetooth, gpio, dialout) - Pi-gen stage 04 integration for OS image building - Port conflict resolution with ttyd-bash - I2C interface auto-enable for UPS HAT ### Testing - test_backend.py - Backend API tests - test_ups.py - UPS manager tests - test_ble.py - BLE manager tests - test_plugins.py - Plugin manager tests - All tests passing locally ### Documentation - 12 comprehensive documentation files - claude.md - AI development guide - WIFI_MANAGER.md - WiFi management guide - UPDATE_MANAGER.md - Update system guide - PORT_CONFLICT.md - Port conflict resolution guide - MVP_COMPLETE.md - MVP implementation summary - PROJECT_STATUS.md - Project status and roadmap - systemd/README.md - Service management docs - pi-gen integration documentation ## Technical Details - ~5,000+ lines of backend code - 11 Python dependencies (smbus2 added for UPS) - FastAPI with async/await throughout - Type hints and docstrings on all functions - RESTful API design with SSE for notifications - Security hardening (non-root, protected dirs, resource limits) ## Next Steps - Deploy to Raspberry Pi Zero 2 W hardware - Test with real Proxmark3 device - Test UPS HAT integration - Test BLE on Pi hardware - Build custom OS image with pi-gen - Performance optimization for Pi Zero 2 W 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
141
app/backend/main.py
Normal file
141
app/backend/main.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""Main FastAPI application for Dangerous Pi."""
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from . import config
|
||||
from .models.database import init_db
|
||||
from .api import health, pm3, system, wifi, updates, plugins
|
||||
from .sse import events
|
||||
from .managers.update_manager import get_update_manager
|
||||
from .managers.ups_manager import get_ups_manager
|
||||
from .managers.ble_manager import get_ble_manager, NotificationType
|
||||
from .managers.plugin_manager import get_plugin_manager
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""Application lifespan manager."""
|
||||
# Startup
|
||||
print(f"🚀 Starting Dangerous Pi backend...")
|
||||
await init_db()
|
||||
print(f"✅ Database initialized")
|
||||
|
||||
# Start periodic update checks
|
||||
update_manager = get_update_manager()
|
||||
update_task = asyncio.create_task(update_manager.start_periodic_checks())
|
||||
print(f"✅ Update manager started")
|
||||
|
||||
# Initialize and start BLE manager
|
||||
ble_manager = get_ble_manager()
|
||||
await ble_manager.initialize()
|
||||
if ble_manager.is_available():
|
||||
await ble_manager.start_advertising()
|
||||
print(f"✅ BLE manager started")
|
||||
else:
|
||||
print(f"⚠️ BLE not available")
|
||||
|
||||
# Start UPS monitoring
|
||||
ups_manager = get_ups_manager()
|
||||
|
||||
# Register UPS event callbacks for SSE notifications and BLE
|
||||
async def ups_event_handler(event):
|
||||
"""Handle UPS events and broadcast via SSE and BLE."""
|
||||
event_type = event.get("type")
|
||||
data = event.get("data", {})
|
||||
|
||||
if event_type == "battery_warning":
|
||||
await events.notify_ups_warning(data["percentage"], data["threshold"])
|
||||
await ble_manager.send_notification(
|
||||
NotificationType.BATTERY_WARNING,
|
||||
f"Battery low: {data['percentage']:.1f}%",
|
||||
data
|
||||
)
|
||||
elif event_type == "battery_low":
|
||||
await events.notify_ups_critical(data["percentage"])
|
||||
await ble_manager.send_notification(
|
||||
NotificationType.BATTERY_CRITICAL,
|
||||
f"Battery critical: {data['percentage']:.1f}%",
|
||||
data
|
||||
)
|
||||
elif event_type == "battery_critical":
|
||||
await events.notify_ups_shutdown(data.get("delay", 60), data["percentage"])
|
||||
await ble_manager.send_notification(
|
||||
NotificationType.SHUTDOWN_INITIATED,
|
||||
f"Shutdown initiated: {data['percentage']:.1f}% battery",
|
||||
data
|
||||
)
|
||||
|
||||
ups_manager.register_event_callback(ups_event_handler)
|
||||
ups_task = asyncio.create_task(ups_manager.start_monitoring())
|
||||
print(f"✅ UPS manager started")
|
||||
|
||||
# Discover and load plugins
|
||||
plugin_manager = get_plugin_manager()
|
||||
discovered = await plugin_manager.discover_plugins()
|
||||
print(f"✅ Plugin manager started ({len(discovered)} plugins discovered)")
|
||||
|
||||
yield
|
||||
|
||||
# Shutdown
|
||||
print(f"🛑 Shutting down Dangerous Pi backend...")
|
||||
update_task.cancel()
|
||||
ups_task.cancel()
|
||||
try:
|
||||
await update_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
try:
|
||||
await ups_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
# Close UPS manager I2C connection
|
||||
ups_manager.close()
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="Dangerous Pi API",
|
||||
description="Backend API for Proxmark3 management on Raspberry Pi Zero 2 W",
|
||||
version="0.1.0",
|
||||
lifespan=lifespan
|
||||
)
|
||||
|
||||
# CORS middleware for frontend
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"], # TODO: Restrict in production
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Include routers
|
||||
app.include_router(health.router, prefix="/api", tags=["health"])
|
||||
app.include_router(pm3.router, prefix="/api/pm3", tags=["proxmark3"])
|
||||
app.include_router(system.router, prefix="/api/system", tags=["system"])
|
||||
app.include_router(wifi.router, prefix="/api/wifi", tags=["wifi"])
|
||||
app.include_router(updates.router, prefix="/api/updates", tags=["updates"])
|
||||
app.include_router(plugins.router, prefix="/api/plugins", tags=["plugins"])
|
||||
app.include_router(events.router, prefix="/sse", tags=["events"])
|
||||
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def global_exception_handler(request, exc):
|
||||
"""Global exception handler."""
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"error": str(exc)}
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(
|
||||
"app.backend.main:app",
|
||||
host=config.HOST,
|
||||
port=config.PORT,
|
||||
reload=True
|
||||
)
|
||||
Reference in New Issue
Block a user