# WLED Central Controller A web-based central controller for multiple WLED instances, allowing you to discover, manage, group, and schedule actions across your WLED devices. ## Features - **Device Management**: Add, edit, and monitor multiple WLED devices - **Grouping**: Organize devices into logical groups (e.g., "Living Room", "Garden") - **Group Actions**: Apply presets and playlists to individual devices or groups - **Scheduling**: Automate preset/playlist changes with cron-based schedules - **UK Timezone Support**: All times displayed in Europe/London timezone (dd/MM/yyyy HH:mm format) - **RESTful API**: Complete backend API for integration with other systems - **Modern UI**: Clean, responsive web interface built with React ## Tech Stack ### Backend - Node.js v20+ with TypeScript - Express.js for HTTP API - SQLite via Prisma ORM - node-cron for scheduling - Zod for validation ### Frontend - React 18 with TypeScript - Vite build tool - React Router for navigation - Luxon for date/time handling ## Quick Start with Docker The easiest way to run the WLED Controller is using Docker Compose: ```bash # Clone the repository cd wled-controller # Start the services docker-compose up -d # Access the web UI # Open http://localhost in your browser ``` The backend API will be available at `http://localhost:3000/api`. ## Manual Setup ### Backend Setup ```bash cd backend # Copy environment file cp .env.example .env # Install dependencies npm install # Generate Prisma Client npm run prisma:generate # Run database migrations npm run prisma:migrate # Development mode npm run dev # Production build npm run build npm start ``` ### Frontend Setup ```bash cd frontend # Copy environment file cp .env.example .env # Install dependencies npm install # Development mode npm run dev # Production build npm run build npm run preview ``` ## Configuration ### Backend Environment Variables Create a `.env` file in the `backend` directory: ```env PORT=3000 DATABASE_URL="file:./dev.db" LOG_LEVEL=info ``` ### Frontend Environment Variables Create a `.env` file in the `frontend` directory: ```env VITE_API_BASE_URL=http://localhost:3000/api ``` ## Usage Guide ### 1. Add Devices 1. Navigate to the **Devices** page 2. Click **Add Device** 3. Enter device details: - Name (e.g., "Kitchen Strip") - IP Address (e.g., "192.168.1.50") - Port (default: 80) - Enabled checkbox 4. Use **Ping** to verify connectivity ### 2. Create Groups 1. Navigate to the **Groups** page 2. Click **Create Group** 3. Enter group name 4. Select devices to include 5. Save ### 3. Control Groups 1. Click **Control** on any group 2. Apply a preset: - Enter preset ID - Click **Apply Preset** 3. Or apply a playlist: - Enter comma-separated preset IDs - Configure duration, transition, repeat options - Click **Apply Playlist** ### 4. Schedule Actions 1. Navigate to the **Schedules** page 2. Click **Create Schedule** 3. Configure: - Name - Group - Type (Preset or Playlist) - Cron expression (e.g., `30 18 * * *` for 6:30 PM daily) - Timezone (default: Europe/London) - Action payload (preset ID or playlist config) 4. Enable/disable schedules with the toggle ## API Documentation ### Devices - `GET /api/devices` - List all devices - `POST /api/devices` - Create device - `GET /api/devices/:id` - Get device - `PUT /api/devices/:id` - Update device - `DELETE /api/devices/:id` - Delete device - `POST /api/devices/:id/ping` - Ping device ### Groups - `GET /api/groups` - List all groups - `POST /api/groups` - Create group - `GET /api/groups/:id` - Get group - `PUT /api/groups/:id` - Update group - `DELETE /api/groups/:id` - Delete group - `POST /api/groups/:id/preset` - Apply preset to group - `POST /api/groups/:id/playlist` - Apply playlist to group ### Schedules - `GET /api/schedules` - List all schedules - `POST /api/schedules` - Create schedule - `GET /api/schedules/:id` - Get schedule - `PUT /api/schedules/:id` - Update schedule - `DELETE /api/schedules/:id` - Delete schedule ## WLED Integration The controller communicates with WLED devices over HTTP using the JSON API: - `/json/info` - Device information - `/json/state` - Device state and control ### Preset Application ```json POST /json/state { "ps": 5 } ``` ### Playlist Application ```json POST /json/state { "playlist": { "ps": [1, 2, 3], "dur": [30, 30, 30], "transition": 0, "repeat": 0, "end": 1 } } ``` ## Cron Expression Format Schedules use standard cron syntax: ``` * * * * * ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ └─ day of week (0-7, 0 and 7 are Sunday) │ │ │ └────── month (1-12) │ │ └─────────── day of month (1-31) │ └──────────────── hour (0-23) └───────────────────── minute (0-59) ``` ### Examples - `30 18 * * *` - Every day at 6:30 PM - `0 9 * * 1-5` - Weekdays at 9:00 AM - `*/15 * * * *` - Every 15 minutes - `0 22 * * 0` - Sundays at 10:00 PM ## Development ### Backend Tests ```bash cd backend npm test ``` ### Code Formatting ```bash # Backend cd backend npm run format # Frontend cd frontend npm run format ``` ### Linting ```bash # Backend cd backend npm run lint # Frontend cd frontend npm run lint ``` ## Deployment ### Behind a Reverse Proxy The application is designed to work behind HTTPS reverse proxies. Configure your reverse proxy to: 1. Serve the frontend on your domain 2. Proxy `/api/*` requests to the backend 3. Set appropriate CORS headers if needed Example Nginx configuration: ```nginx server { listen 443 ssl; server_name wled.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://localhost:80; } location /api { proxy_pass http://localhost:3000; } } ``` ## Troubleshooting ### Device Not Reachable - Verify the device IP address is correct - Ensure the device is on the same network - Check firewall rules - Use the **Ping** button to test connectivity ### Schedule Not Triggering - Verify the cron expression is correct - Check the schedule is enabled - Ensure the group has enabled devices - Review backend logs for errors ### Database Issues ```bash cd backend # Reset database rm dev.db npm run prisma:migrate # View database npm run prisma:studio ``` ## License MIT ## Contributing Contributions welcome! Please open an issue or pull request.