diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..df146d0 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,33 @@ +name: Lint & Test + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + working-directory: server + run: | + pip install --upgrade pip + pip install -e ".[dev]" + + - name: Lint with ruff + working-directory: server + run: ruff check src/ tests/ + + - name: Run tests + working-directory: server + run: pytest --tb=short -q diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c42c99a --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: + - repo: https://github.com/psf/black + rev: '24.10.0' + hooks: + - id: black + args: [--line-length=100, --target-version=py311] + language_version: python3.11 + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.0 + hooks: + - id: ruff + args: [--line-length=100, --target-version=py311] diff --git a/CLAUDE.md b/CLAUDE.md index 105894e..c9d69ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,196 +7,50 @@ **IMPORTANT for subagents:** When spawning Agent subagents (Plan, Explore, general-purpose, etc.), always instruct them to use `ast-index` via Bash for code search instead of grep/Glob. Example: include "Use `ast-index search`, `ast-index class`, `ast-index usages` etc. via Bash for code search" in the agent prompt. ```bash -# Check if available: -ast-index version - -# Rebuild index (first time or after major changes): -ast-index rebuild - -# Common commands: -ast-index search "Query" # Universal search across files, symbols, modules +ast-index search "Query" # Universal search ast-index class "ClassName" # Find class/struct/interface definitions -ast-index usages "SymbolName" # Find all places a symbol is used -ast-index implementations "BaseClass" # Find all subclasses/implementations -ast-index symbol "FunctionName" # Find any symbol (class, function, property) -ast-index outline "path/to/File.cpp" # Show all symbols in a file -ast-index hierarchy "ClassName" # Show inheritance tree +ast-index usages "SymbolName" # Find all usage sites +ast-index symbol "FunctionName" # Find any symbol ast-index callers "FunctionName" # Find all call sites +ast-index outline "path/to/File.py" # Show all symbols in a file ast-index changed --base master # Show symbols changed in current branch -ast-index update # Incremental update after file changes ``` -## CRITICAL: Git Commit and Push Policy +## Git Commit and Push Policy -**🚨 NEVER CREATE COMMITS WITHOUT EXPLICIT USER APPROVAL 🚨** +**NEVER commit or push without explicit user approval.** Wait for the user to review changes and explicitly say "commit" or "push". Completing a task, "looks good", or "thanks" do NOT count as approval. See the system-level instructions for the full commit workflow. -**🚨 NEVER PUSH TO REMOTE WITHOUT EXPLICIT USER APPROVAL 🚨** +## Auto-Restart and Rebuild Policy -### Strict Rules - -1. **DO NOT** create commits automatically after making changes -2. **DO NOT** commit without being explicitly instructed by the user -3. **DO NOT** push to remote repository without explicit instruction -4. **ALWAYS WAIT** for the user to review changes and ask you to commit -5. **ALWAYS ASK** if you're unsure whether to commit - -### Workflow - -1. Make code changes as requested -2. **STOP** - Inform user that changes are complete -3. **WAIT** - User reviews the changes -4. **ONLY IF** user explicitly says "commit" or "create a commit": - - Stage the files with `git add` - - Create the commit with a descriptive message - - **STOP** - Do NOT push -5. **ONLY IF** user explicitly says "push" or "commit and push": - - Push to remote repository - -### What Counts as Explicit Approval - -✅ **YES - These mean you can commit:** -- "commit" -- "create a commit" -- "commit these changes" -- "git commit" - -✅ **YES - These mean you can push:** -- "push" -- "commit and push" -- "push to remote" -- "git push" - -❌ **NO - These do NOT mean you should commit:** -- "that looks good" -- "thanks" -- "perfect" -- User silence after you make changes -- Completing a feature/fix - -### Example Bad Behavior (DON'T DO THIS) - -``` -❌ User: "Fix the MSS engine test issue" -❌ Claude: [fixes the issue] -❌ Claude: [automatically commits without asking] <-- WRONG! -``` - -### Example Good Behavior (DO THIS) - -``` -✅ User: "Fix the MSS engine test issue" -✅ Claude: [fixes the issue] -✅ Claude: "I've fixed the MSS engine test issue by adding auto-initialization..." -✅ [WAITS FOR USER] -✅ User: "Looks good, commit it" -✅ Claude: [now creates the commit] -``` - -## IMPORTANT: Auto-Restart Server on Code Changes - -**Whenever server-side Python code is modified** (any file under `/server/src/` **excluding** `/server/src/wled_controller/static/`), **automatically restart the server** so the changes take effect immediately. Do NOT wait for the user to ask for a restart. - -**No restart needed for frontend-only changes** — but you **MUST rebuild the bundle**. The browser loads the esbuild bundle (`static/dist/app.bundle.js`, `static/dist/app.bundle.css`), NOT the source files. After ANY change to frontend files (JS, CSS under `/server/src/wled_controller/static/`), run: - -```bash -cd server && npm run build -``` - -Without this step, changes will NOT take effect. No server restart is needed — just rebuild and refresh the browser. - -### Restart procedure - -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" -``` - -**Do NOT use** `Stop-Process -Name python` (kills unrelated Python processes like VS Code extensions) or bash background `&` jobs (get killed when the shell session ends). - -## IMPORTANT: Server Startup Commands - -There are two 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. - -### Restarting after code changes - -- **Real server**: Use the PowerShell restart script (it only targets the real server process): - - ```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.). +- **Python code changes** (`server/src/` excluding `static/`): Auto-restart the server. See [contexts/server-operations.md](contexts/server-operations.md) for the restart procedure. +- **Frontend changes** (`static/js/`, `static/css/`): Run `cd server && npm run build` to rebuild the bundle. No server restart needed. ## Project Structure -This is a monorepo containing: -- `/server` - Python FastAPI backend (see `server/CLAUDE.md` for detailed instructions) -- `/client` - Future frontend client (if applicable) +- `/server` — Python FastAPI backend (see [server/CLAUDE.md](server/CLAUDE.md)) +- `/contexts` — Context files for Claude (frontend conventions, graph editor, Chrome tools, server ops, demo mode) -## Working with Server +## Context Files -For detailed server-specific instructions (restart policy, testing, etc.), see: -- `server/CLAUDE.md` - -## Frontend (HTML, CSS, JS, i18n) - -For all frontend conventions (CSS variables, UI patterns, modals, localization, tutorials), see [`contexts/frontend.md`](contexts/frontend.md). +| File | When to read | +| ---- | ------------ | +| [contexts/frontend.md](contexts/frontend.md) | HTML, CSS, JS/TS, i18n, modals, icons, bundling | +| [contexts/graph-editor.md](contexts/graph-editor.md) | Visual graph editor changes | +| [contexts/server-operations.md](contexts/server-operations.md) | Server restart, startup modes, demo mode | +| [contexts/chrome-tools.md](contexts/chrome-tools.md) | Chrome MCP tool usage for testing | +| [server/CLAUDE.md](server/CLAUDE.md) | Backend architecture, API patterns, common tasks | ## Task Tracking via TODO.md Use `TODO.md` in the project root as the primary task tracker. **Do NOT use the TodoWrite tool** — all progress tracking goes through `TODO.md`. -- **When starting a multi-step task**: add sub-steps as `- [ ]` items under the relevant section -- **When completing a step**: mark it `- [x]` immediately — don't batch updates -- **When a task is fully done**: mark it `- [x]` and leave it for the user to clean up -- **When the user requests a new feature/fix**: add it to the appropriate section with a priority tag - ## Documentation Lookup -**Use context7 MCP tools for library/framework documentation lookups.** When you need to check API signatures, usage patterns, or current behavior of external libraries (e.g., FastAPI, OpenCV, Pydantic, yt-dlp), use `mcp__plugin_context7_context7__resolve-library-id` to find the library, then `mcp__plugin_context7_context7__query-docs` to fetch up-to-date docs. This avoids relying on potentially outdated training data. - -## IMPORTANT: 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` — the `model_post_init()` auto-rewrites `data/` → `data/demo/` paths when demo is active. -2. **New capture engines**: If a new engine is added, verify demo mode filtering still 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**: If discovery is added, gate it with `is_demo_mode()` like `DemoDeviceProvider.discover()`. -5. **New seed data**: When adding new entity types that should appear in demo mode, update `server/src/wled_controller/core/demo_seed.py` to include sample entities. -6. **Frontend indicators**: Demo mode state is 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**: If new stores are added to `STORE_MAP` in `system.py`, they 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` +**Use context7 MCP tools for library/framework documentation lookups** (FastAPI, OpenCV, Pydantic, yt-dlp, etc.) instead of relying on potentially outdated training data. ## General Guidelines - Always test changes before marking as complete - Follow existing code style and patterns - Update documentation when changing behavior -- Write clear, descriptive commit messages when explicitly instructed - Never make commits or pushes without explicit user approval diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d46ee17 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,85 @@ +# Contributing + +## Prerequisites + +- Python 3.11+ +- Node.js 20+ (for frontend bundle) +- Git + +## Development Setup + +```bash +git clone https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed.git +cd wled-screen-controller-mixed/server + +# Python environment +python -m venv venv +source venv/bin/activate # Linux/Mac +# venv\Scripts\activate # Windows +pip install -e ".[dev]" + +# Frontend dependencies +npm install +npm run build +``` + +## Running the Server + +```bash +cd server +export PYTHONPATH=$(pwd)/src # Linux/Mac +# set PYTHONPATH=%CD%\src # Windows +python -m wled_controller.main +``` + +Open http://localhost:8080 to access the dashboard. + +## Running Tests + +```bash +cd server +pytest +``` + +Tests use pytest with pytest-asyncio. Coverage reports are generated automatically. + +## Code Style + +This project uses **black** for formatting and **ruff** for linting (both configured in `pyproject.toml` with a line length of 100). + +```bash +cd server +black src/ tests/ +ruff check src/ tests/ +``` + +## Frontend Changes + +After modifying any file under `server/src/wled_controller/static/js/` or `static/css/`, rebuild the bundle: + +```bash +cd server +npm run build +``` + +The browser loads the esbuild bundle (`static/dist/`), not the source files directly. + +## Commit Messages + +Follow the [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +feat: add new capture engine +fix: correct LED color mapping +refactor: extract filter pipeline +docs: update API reference +test: add audio source tests +chore: update dependencies +``` + +## Pull Requests + +1. Create a feature branch from `master` +2. Make your changes with tests +3. Ensure `ruff check` and `pytest` pass +4. Open a PR with a clear description of the change diff --git a/INSTALLATION.md b/INSTALLATION.md index 7e0ae45..ef0e865 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -1,281 +1,222 @@ # Installation Guide -Complete installation guide for WLED Screen Controller server and Home Assistant integration. +Complete installation guide for LED Grab (WLED Screen Controller) server and Home Assistant integration. ## Table of Contents -1. [Server Installation](#server-installation) -2. [Home Assistant Integration](#home-assistant-integration) -3. [Quick Start](#quick-start) +1. [Docker Installation (recommended)](#docker-installation) +2. [Manual Installation](#manual-installation) +3. [First-Time Setup](#first-time-setup) +4. [Home Assistant Integration](#home-assistant-integration) +5. [Configuration Reference](#configuration-reference) +6. [Troubleshooting](#troubleshooting) --- -## Server Installation +## Docker Installation -### Option 1: Python (Development/Testing) +The fastest way to get running. Requires [Docker](https://docs.docker.com/get-docker/) with Compose. -**Requirements:** -- Python 3.11 or higher -- Windows, Linux, or macOS +1. **Clone and start:** -**Steps:** + ```bash + git clone https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed.git + cd wled-screen-controller/server + docker compose up -d + ``` + +2. **Verify:** + + ```bash + curl http://localhost:8080/health + # → {"status":"healthy", ...} + ``` + +3. **Open the dashboard:** + +4. **View logs:** + + ```bash + docker compose logs -f + ``` + +5. **Stop / restart:** + + ```bash + docker compose down # stop + docker compose up -d # start again (data is persisted) + ``` + +### Docker manual build (without Compose) + +```bash +cd server +docker build -t ledgrab . + +docker run -d \ + --name wled-screen-controller \ + -p 8080:8080 \ + -v $(pwd)/data:/app/data \ + -v $(pwd)/logs:/app/logs \ + -v $(pwd)/config:/app/config:ro \ + ledgrab +``` + +### Linux screen capture in Docker + +Screen capture from inside a container requires X11 access. Uncomment `network_mode: host` in `docker-compose.yml` and ensure the `DISPLAY` variable is set. Wayland is not currently supported for in-container capture. + +--- + +## Manual Installation + +### Requirements + +| Dependency | Version | Purpose | +| ---------- | ------- | ------- | +| Python | 3.11+ | Backend server | +| Node.js | 18+ | Frontend build (esbuild) | +| pip | latest | Python package installer | +| npm | latest | Node package manager | + +### Steps 1. **Clone the repository:** + ```bash - git clone https://github.com/yourusername/wled-screen-controller.git + git clone https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed.git cd wled-screen-controller/server ``` -2. **Create virtual environment:** +2. **Build the frontend bundle:** + + ```bash + npm ci + npm run build + ``` + + This compiles TypeScript and bundles JS/CSS into `src/wled_controller/static/dist/`. + +3. **Create a virtual environment:** + ```bash python -m venv venv - # Windows + # Linux / macOS + source venv/bin/activate + + # Windows (cmd) venv\Scripts\activate - # Linux/Mac - source venv/bin/activate + # Windows (PowerShell) + venv\Scripts\Activate.ps1 ``` -3. **Install dependencies:** +4. **Install Python dependencies:** + ```bash pip install . ``` -4. **Configure (optional):** - Edit `config/default_config.yaml` to customize settings. + Optional extras: -5. **Run the server:** ```bash - # Set PYTHONPATH - export PYTHONPATH=$(pwd)/src # Linux/Mac - set PYTHONPATH=%CD%\src # Windows + pip install ".[camera]" # Webcam capture via OpenCV + pip install ".[perf]" # DXCam, BetterCam, WGC (Windows only) + pip install ".[notifications]" # OS notification capture + pip install ".[dev]" # pytest, black, ruff (development) + ``` - # Start server +5. **Set PYTHONPATH and start the server:** + + ```bash + # Linux / macOS + export PYTHONPATH=$(pwd)/src + uvicorn wled_controller.main:app --host 0.0.0.0 --port 8080 + + # Windows (cmd) + set PYTHONPATH=%CD%\src uvicorn wled_controller.main:app --host 0.0.0.0 --port 8080 ``` -6. **Verify:** - Open http://localhost:8080/docs in your browser. +6. **Verify:** open in your browser. -### Option 2: Docker (Recommended for Production) +--- -**Requirements:** -- Docker -- Docker Compose +## First-Time Setup -**Steps:** +### Change the default API key -1. **Clone the repository:** - ```bash - git clone https://github.com/yourusername/wled-screen-controller.git - cd wled-screen-controller/server - ``` +The server ships with a development API key (`development-key-change-in-production`). **Change it before exposing the server on your network.** -2. **Start with Docker Compose:** - ```bash - docker-compose up -d - ``` +Option A -- edit the config file: -3. **View logs:** - ```bash - docker-compose logs -f - ``` +```yaml +# server/config/default_config.yaml +auth: + api_keys: + main: "your-secure-key-here" # replace the dev key +``` -4. **Verify:** - Open http://localhost:8080/docs in your browser. - -### Option 3: Docker (Manual Build) +Option B -- set an environment variable: ```bash -cd server -docker build -t wled-screen-controller . - -docker run -d \ - --name wled-controller \ - -p 8080:8080 \ - -v $(pwd)/data:/app/data \ - -v $(pwd)/logs:/app/logs \ - --network host \ - wled-screen-controller +export WLED_AUTH__API_KEYS__main="your-secure-key-here" ``` +Generate a random key: + +```bash +openssl rand -hex 32 +``` + +### Configure CORS for LAN access + +By default the server only allows requests from `http://localhost:8080`. To access the dashboard from another machine on your LAN, add its origin: + +```yaml +# server/config/default_config.yaml +server: + cors_origins: + - "http://localhost:8080" + - "http://192.168.1.100:8080" # your server's LAN IP +``` + +Or via environment variable: + +```bash +WLED_SERVER__CORS_ORIGINS='["http://localhost:8080","http://192.168.1.100:8080"]' +``` + +### Discover devices + +Open the dashboard and go to the **Devices** tab. Click **Discover** to find WLED devices on your network via mDNS. You can also add devices manually by IP address. + --- ## Home Assistant Integration -### Option 1: HACS (Recommended) +### Option 1: HACS (recommended) -1. **Install HACS** if not already installed: - - Follow instructions at https://hacs.xyz/docs/setup/download +1. Install [HACS](https://hacs.xyz/docs/setup/download) if you have not already. +2. Open HACS in Home Assistant. +3. Click the three-dot menu, then **Custom repositories**. +4. Add URL: `https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed` +5. Set category to **Integration** and click **Add**. +6. Search for "WLED Screen Controller" in HACS and click **Download**. +7. Restart Home Assistant. +8. Go to **Settings > Devices & Services > Add Integration** and search for "WLED Screen Controller". +9. Enter your server URL (e.g., `http://192.168.1.100:8080`) and API key. -2. **Add Custom Repository:** - - Open HACS in Home Assistant - - Click the three dots menu → Custom repositories - - Add URL: `https://github.com/yourusername/wled-screen-controller` - - Category: Integration - - Click Add +### Option 2: Manual -3. **Install Integration:** - - In HACS, search for "WLED Screen Controller" - - Click Download - - Restart Home Assistant +Copy the `custom_components/wled_screen_controller/` folder from this repository into your Home Assistant `config/custom_components/` directory, then restart Home Assistant and add the integration as above. -4. **Configure Integration:** - - Go to Settings → Devices & Services - - Click "+ Add Integration" - - Search for "WLED Screen Controller" - - Enter your server URL (e.g., `http://192.168.1.100:8080`) - - Click Submit - -### Option 2: Manual Installation - -1. **Download Integration:** - ```bash - cd /config # Your Home Assistant config directory - mkdir -p custom_components - ``` - -2. **Copy Files:** - Copy the `custom_components/wled_screen_controller` folder to your Home Assistant `custom_components` directory. - -3. **Restart Home Assistant** - -4. **Configure Integration:** - - Go to Settings → Devices & Services - - Click "+ Add Integration" - - Search for "WLED Screen Controller" - - Enter your server URL - - Click Submit - ---- - -## Quick Start - -### 1. Start the Server - -```bash -cd wled-screen-controller/server -docker-compose up -d -``` - -### 2. Attach Your WLED Device - -```bash -curl -X POST http://localhost:8080/api/v1/devices \ - -H "Content-Type: application/json" \ - -d '{ - "name": "Living Room TV", - "url": "http://192.168.1.100", - "led_count": 150 - }' -``` - -### 3. Configure in Home Assistant - -1. Add the integration (see above) -2. Your WLED devices will appear automatically -3. Use the switch to turn processing on/off -4. Use the select to choose display -5. Monitor FPS and status via sensors - -### 4. Start Processing - -Either via API: -```bash -curl -X POST http://localhost:8080/api/v1/devices/{device_id}/start -``` - -Or via Home Assistant: -- Turn on the "{Device Name} Processing" switch - -### 5. Enjoy Ambient Lighting! - -Your WLED strip should now sync with your screen content! - ---- - -## Troubleshooting - -### Server Won't Start - -**Check Python version:** -```bash -python --version # Should be 3.11+ -``` - -**Check dependencies:** -```bash -pip list | grep fastapi -``` - -**Check logs:** -```bash -# Docker -docker-compose logs -f - -# Python -tail -f logs/wled_controller.log -``` - -### Home Assistant Integration Not Appearing - -1. Check HACS installation -2. Clear browser cache -3. Restart Home Assistant -4. Check Home Assistant logs: - - Settings → System → Logs - - Search for "wled_screen_controller" - -### Can't Connect to Server from Home Assistant - -1. Verify server is running: - ```bash - curl http://YOUR_SERVER_IP:8080/health - ``` - -2. Check firewall rules -3. Ensure Home Assistant can reach server IP -4. Try http:// not https:// - -### WLED Device Not Responding - -1. Check WLED device is powered on -2. Verify IP address is correct -3. Test WLED directly: - ```bash - curl http://YOUR_WLED_IP/json/info - ``` - -4. Check network connectivity - -### Low FPS / Performance Issues - -1. Reduce target FPS (Settings → Devices) -2. Reduce `border_width` in settings -3. Check CPU usage on server -4. Consider reducing LED count - ---- - -## Configuration Examples - -### Server Environment Variables - -```bash -# Docker .env file -WLED_SERVER__HOST=0.0.0.0 -WLED_SERVER__PORT=8080 -WLED_SERVER__LOG_LEVEL=INFO -WLED_PROCESSING__DEFAULT_FPS=30 -WLED_PROCESSING__BORDER_WIDTH=10 -``` - -### Home Assistant Automation Example +### Automation example ```yaml automation: - - alias: "Auto Start WLED on TV On" + - alias: "Start ambient lighting when TV turns on" trigger: - platform: state entity_id: media_player.living_room_tv @@ -285,7 +226,7 @@ automation: target: entity_id: switch.living_room_tv_processing - - alias: "Auto Stop WLED on TV Off" + - alias: "Stop ambient lighting when TV turns off" trigger: - platform: state entity_id: media_player.living_room_tv @@ -298,8 +239,89 @@ automation: --- +## Configuration Reference + +The server reads configuration from three sources (in order of priority): + +1. **Environment variables** -- prefix `WLED_`, double underscore as nesting delimiter (e.g., `WLED_SERVER__PORT=9090`) +2. **YAML config file** -- `server/config/default_config.yaml` (or set `WLED_CONFIG_PATH` to override) +3. **Built-in defaults** + +See [`server/.env.example`](server/.env.example) for every available variable with descriptions. + +### Key settings + +| Variable | Default | Description | +| -------- | ------- | ----------- | +| `WLED_SERVER__PORT` | `8080` | HTTP listen port | +| `WLED_SERVER__LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` | +| `WLED_SERVER__CORS_ORIGINS` | `["http://localhost:8080"]` | Allowed CORS origins (JSON array) | +| `WLED_AUTH__API_KEYS` | `{"dev":"development-key..."}` | API keys (JSON object) | +| `WLED_MQTT__ENABLED` | `false` | Enable MQTT for HA auto-discovery | +| `WLED_MQTT__BROKER_HOST` | `localhost` | MQTT broker address | +| `WLED_DEMO` | `false` | Enable demo mode (sandbox with virtual devices) | + +--- + +## Troubleshooting + +### Server will not start + +**Check Python version:** + +```bash +python --version # must be 3.11+ +``` + +**Check the frontend bundle exists:** + +```bash +ls server/src/wled_controller/static/dist/app.bundle.js +``` + +If missing, run `cd server && npm ci && npm run build`. + +**Check logs:** + +```bash +# Docker +docker compose logs -f + +# Manual install +tail -f logs/wled_controller.log +``` + +### Cannot access the dashboard from another machine + +1. Verify the server is reachable: `curl http://SERVER_IP:8080/health` +2. Check your firewall allows inbound traffic on port 8080. +3. Add your server's LAN IP to `cors_origins` (see [Configure CORS](#configure-cors-for-lan-access) above). + +### Home Assistant integration not appearing + +1. Verify HACS installed the component: check that `config/custom_components/wled_screen_controller/` exists. +2. Clear your browser cache. +3. Restart Home Assistant. +4. Check logs at **Settings > System > Logs** and search for `wled_screen_controller`. + +### WLED device not responding + +1. Confirm the device is powered on and connected to Wi-Fi. +2. Test it directly: `curl http://DEVICE_IP/json/info` +3. Check that the server and the device are on the same subnet. +4. Try restarting the WLED device. + +### Low FPS or high latency + +1. Lower the target FPS in the stream settings. +2. Reduce `border_width` to decrease the number of sampled pixels. +3. Check CPU usage on the server (`htop` or Task Manager). +4. On Windows, install the `perf` extra for GPU-accelerated capture: `pip install ".[perf]"` + +--- + ## Next Steps - [API Documentation](docs/API.md) - [Calibration Guide](docs/CALIBRATION.md) -- [GitHub Issues](https://github.com/yourusername/wled-screen-controller/issues) +- [Repository Issues](https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed/issues) diff --git a/README.md b/README.md index 44d2274..d12f663 100644 --- a/README.md +++ b/README.md @@ -84,26 +84,42 @@ A Home Assistant integration exposes devices as entities for smart home automati ## Quick Start +### Docker (recommended) + ```bash -git clone https://github.com/yourusername/wled-screen-controller.git +git clone https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed.git +cd wled-screen-controller/server +docker compose up -d +``` + +### Manual + +Requires Python 3.11+ and Node.js 18+. + +```bash +git clone https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed.git cd wled-screen-controller/server -# Option A: Docker (recommended) -docker-compose up -d +# Build the frontend bundle +npm ci && npm run build -# Option B: Python +# Create a virtual environment and install python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows pip install . + +# Start the server export PYTHONPATH=$(pwd)/src # Linux/Mac # set PYTHONPATH=%CD%\src # Windows uvicorn wled_controller.main:app --host 0.0.0.0 --port 8080 ``` -Open `http://localhost:8080` to access the dashboard. The default API key for development is `development-key-change-in-production`. +Open **http://localhost:8080** to access the dashboard. -See [INSTALLATION.md](INSTALLATION.md) for the full installation guide, including Docker manual builds and Home Assistant setup. +> **Important:** The default API key is `development-key-change-in-production`. Change it before exposing the server outside localhost. See [INSTALLATION.md](INSTALLATION.md) for details. + +See [INSTALLATION.md](INSTALLATION.md) for the full installation guide, including configuration, Docker manual builds, and Home Assistant setup. ## Architecture @@ -146,7 +162,7 @@ wled-screen-controller/ ## Configuration -Edit `server/config/default_config.yaml` or use environment variables with the `LED_GRAB_` prefix: +Edit `server/config/default_config.yaml` or use environment variables with the `WLED_` prefix: ```yaml server: @@ -168,7 +184,7 @@ logging: max_size_mb: 100 ``` -Environment variable override example: `LED_GRAB_SERVER__PORT=9090`. +Environment variable override example: `WLED_SERVER__PORT=9090`. ## API diff --git a/contexts/frontend.md b/contexts/frontend.md index 219273a..174b1c6 100644 --- a/contexts/frontend.md +++ b/contexts/frontend.md @@ -72,17 +72,17 @@ For `EntitySelect` with `allowNone: true`, pass the same i18n string as `noneLab Plain `` with a visual grid of icon+label+description cells. See `_ensureCSSTypeIconSelect()`, `_ensureEffectTypeIconSelect()`, `_ensureInterpolationIconSelect()` in `color-strips.js` for examples. +- **Predefined options** (source types, effect types, palettes, waveforms, viz modes) → use `IconSelect` from `js/core/icon-select.ts`. This replaces the `` with a searchable command-palette-style picker. See `_cssPictureSourceEntitySelect` in `color-strips.js` or `_lineSourceEntitySelect` in `advanced-calibration.js` for examples. +- **Entity references** (picture sources, audio sources, devices, templates, clocks) → use `EntitySelect` from `js/core/entity-palette.ts`. This replaces the `` but keep it in the DOM with its value in sync. After programmatically changing the `