# Server Operations **Read this file when restarting, starting, or managing the server process.** ## Server Modes Two independent server modes with separate configs, ports, and data directories: | Mode | Command | Config | Port | API Key | Data | | ---- | ------- | ------ | ---- | ------- | ---- | | **Real** | `python -m wled_controller.main` | `config/default_config.yaml` | 8080 | `development-key-change-in-production` | `data/` | | **Demo** | `python -m wled_controller.demo` | `config/demo_config.yaml` | 8081 | `demo` | `data/demo/` | Both can run simultaneously on different ports. ## Restart Procedure ### Real server Use the PowerShell restart script — it reliably stops only the server process and starts a new detached instance: ```bash powershell -ExecutionPolicy Bypass -File "c:\Users\Alexei\Documents\wled-screen-controller\server\restart.ps1" ``` ### Demo server Find and kill the process on port 8081, then restart: ```bash # Find PID powershell -Command "netstat -ano | Select-String ':8081.*LISTEN'" # Kill it powershell -Command "Stop-Process -Id -Force" # Restart cd server && python -m wled_controller.demo ``` **Do NOT use** `Stop-Process -Name python` — it kills unrelated Python processes (VS Code extensions, etc.). **Do NOT use** bash background `&` jobs — they get killed when the shell session ends. ## When to Restart **Restart required** for changes to: - API routes (`api/routes/`, `api/schemas/`) - Core logic (`core/*.py`) - Configuration (`config.py`) - Utilities (`utils/*.py`) - Data models (`storage/`) **No restart needed** for: - Static files (`static/js/`, `static/css/`) — but **must rebuild bundle**: `cd server && npm run build` - Locale files (`static/locales/*.json`) — loaded by frontend - Documentation files (`*.md`) ## Auto-Reload Note Auto-reload is disabled (`reload=False` in `main.py`) due to watchfiles causing an infinite reload loop. Manual restart is required after server code changes. ## Demo Mode Awareness **When adding new entity types, engines, device providers, or stores — keep demo mode in sync:** 1. **New entity stores**: Add the store's file path to `StorageConfig` in `config.py` — `model_post_init()` auto-rewrites `data/` to `data/demo/` paths when demo is active. 2. **New capture engines**: Verify demo mode filtering works — demo engines use `is_demo_mode()` gate in `is_available()`. 3. **New audio engines**: Same as capture engines — `is_available()` must respect `is_demo_mode()`. 4. **New device providers**: Gate discovery with `is_demo_mode()` like `DemoDeviceProvider.discover()`. 5. **New seed data**: Update `server/src/wled_controller/core/demo_seed.py` to include sample entities. 6. **Frontend indicators**: Demo state exposed via `GET /api/v1/version` -> `demo_mode: bool`. Frontend stores it as `demoMode` in app state and sets `document.body.dataset.demo = 'true'`. 7. **Backup/Restore**: New stores added to `STORE_MAP` in `system.py` automatically work in demo mode since the data directory is already isolated. ### Key files - Config flag: `server/src/wled_controller/config.py` -> `Config.demo`, `is_demo_mode()` - Demo engines: `core/capture_engines/demo_engine.py`, `core/audio/demo_engine.py` - Demo devices: `core/devices/demo_provider.py` - Seed data: `core/demo_seed.py`