Files
spore-ledlab/README.md

410 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SPORE LEDLab
LEDLab is a tool for streaming animations to LED matrices connected to SPORE nodes. Create visual effects with real-time parameter control and individual node management.
![ledlab](assets/ledlab.png)
![editor](assets/editor.png)
## Features
- **Multi-Node Management**: Control multiple SPORE nodes individually
- **Real-Time Preview**: See live canvas preview for each node
- **Dynamic Presets**: Choose from 10+ built-in animation presets
- **Visual Preset Editor**: Create custom animations with building blocks
- **Live Parameter Control**: Adjust animation parameters in real-time
- **Auto-Discovery**: Automatically discovers SPORE nodes on the network
- **Modern UI**: Clean, responsive interface with dark/light theme support
- **Import/Export**: Save and share custom presets as JSON files
## Architecture
### Server
The Node.js server provides the backend for SPORE LEDLab:
- **Gateway Integration**: Subscribes to spore-gateway WebSocket for real-time cluster updates (requires spore-gateway to be running)
- **UDP Frame Streaming**: Sends animation frames to SPORE nodes via UDP on port 4210
- **WebSocket API**: Real-time bidirectional communication with the web UI
- **Preset Management**: Manages animation presets with configurable parameters
- **Multi-Node Streaming**: Streams different presets to individual nodes simultaneously
- **Frame Generation**: Generates animation frames at configurable FPS (1-60)
- **Node State Management**: Tracks configuration and streaming state per node
### Web UI
The web interface provides an intuitive control panel:
- **Node Grid View**: Visual grid showing all discovered nodes with live canvas previews
- **Node Selection**: Click any node to open its control panel
- **Preset Selection**: Choose from available animation presets
- **Parameter Controls**: Real-time sliders and inputs for preset parameters
- **Matrix Configuration**: Configurable matrix dimensions (default: 16x16)
- **Settings Panel**: Test frames and matrix clearing utilities
- **Theme Support**: Toggle between dark and light themes
### Communication Flow
```
Web UI (Browser) <--WebSocket--> Server <--UDP--> SPORE Nodes
|
Preset Engine
|
Frame Generation (60fps)
Gateway WebSocket (Real-time cluster updates)
```
## Build
### Prerequisites
- Node.js (v14 or higher)
- npm (v6 or higher)
- spore-gateway must be running on port 3001
### Installation
1. Clone the repository or navigate to the `spore-ledlab` directory:
```bash
cd spore-ledlab
```
2. Install dependencies:
```bash
npm install
```
This will install:
- `express`: Web server framework
- `ws`: WebSocket library for real-time communication
### Project Structure
```
spore-ledlab/
├── server/ # Backend server
│ ├── index.js # Main server & WebSocket handling
│ ├── gateway-client.js # Gateway client for node discovery
│ └── udp-discovery.js # UDP sender for frame streaming
├── presets/ # Animation preset implementations
│ ├── preset-registry.js
│ ├── base-preset.js
│ ├── building-blocks.js # Reusable shape/animation components
│ ├── custom-preset.js # Configurable preset engine
│ ├── rainbow-preset.js
│ ├── lava-lamp-preset.js
│ ├── examples/ # Example custom preset JSON files
│ └── ...
├── public/ # Frontend web UI
│ ├── index.html
│ ├── scripts/ # JavaScript modules
│ │ ├── preset-editor.js # Visual preset editor
│ │ └── ...
│ └── styles/ # CSS stylesheets
└── package.json # Project dependencies
```
## Run
### Start the Server
```bash
npm start
```
Or use the dev script (same as start):
```bash
npm run dev
```
The server will:
- Start the HTTP server on port 8080 (default)
- Initialize WebSocket server
- Connect to spore-gateway for node discovery
- Initialize UDP sender for frame streaming
- Serve the web UI at http://localhost:8080
### Access the Web UI
Open your browser and navigate to:
```
http://localhost:8080
```
### Configure SPORE Nodes
Ensure your SPORE nodes are:
1. Connected to the same network as the LEDLab server
2. Running firmware with PixelStreamController support
3. Listening on UDP port 4210
4. Discovered by spore-gateway
5. Labeled with `app: pixelstream` (LEDLab only displays nodes with this label)
The nodes will automatically appear in the LEDLab grid view once they are discovered by spore-gateway and have the `app: pixelstream` label.
### Node Labeling
To display nodes in LEDLab, you must set the `app: pixelstream` label on your SPORE nodes. This can be done via the spore-gateway API or from the SPORE node itself.
**From SPORE Node:**
Nodes should advertise their labels via the UDP heartbeat. The PixelStreamController firmware automatically sets the `app: pixelstream` label.
**Manual via Gateway:**
You can also set labels manually using the spore-gateway API or spore-ui interface.
### Disabling Filtering
To display all nodes without filtering, set the environment variable:
```bash
FILTER_APP_LABEL= npm start
```
Or leave it empty to show all discovered nodes.
## Usage
### Basic Workflow
1. **Discover Nodes**: Wait for SPORE nodes to appear in the grid (auto-discovery runs every 5 seconds)
2. **Select a Node**: Click on any node in the grid to open the control panel
3. **Choose a Preset**: Select an animation preset from the dropdown menu
4. **Adjust Parameters**: Use sliders and inputs to modify animation parameters in real-time
5. **Start Streaming**: Click "Start Streaming" to begin sending frames to the selected node
6. **Stop Streaming**: Click "Stop Streaming" to halt the animation
### Available Presets
- **Rainbow**: Classic rainbow cycle effect
- **Lava Lamp**: Organic flowing blobs
- **Aurora Curtains**: Northern lights simulation
- **Bouncing Ball**: Physics-based bouncing ball
- **Circuit Pulse**: Digital circuit patterns
- **Meteor Rain**: Falling meteor trails
- **Nebula Drift**: Cosmic cloud effects
- **Ocean Glimmer**: Wave-like shimmer
- **Spiral Bloom**: Rotating spiral patterns
- **Voxel Fireflies**: 3D particle system
- **Wormhole Tunnel**: Depth tunnel effect
- **Fade Green-Blue**: Simple color fade
### Matrix Configuration
Default matrix size is 16x16 pixels. To change:
1. Click the ⚙️ Settings button
2. Navigate to the Settings view
3. Adjust Width and Height values
4. Click "Apply Changes"
### Testing
In the Settings view:
- **Send Test Frame**: Sends a checkerboard pattern to verify connectivity
- **Clear Matrix**: Turns off all LEDs on the selected node
## Configuration
### Server Configuration
Edit `server/index.js` or use environment variables:
```javascript
const PORT = 8080; // HTTP/WebSocket port
const UDP_PORT = 4210; // UDP frame streaming port
const GATEWAY_URL = 'http://localhost:3001'; // spore-gateway URL
const FILTER_APP_LABEL = 'pixelstream'; // Filter nodes by app label
const DEFAULT_FPS = 20; // Default frame rate
const MATRIX_WIDTH = 16; // Default matrix width
const MATRIX_HEIGHT = 16; // Default matrix height
```
Environment variables:
- `PORT` - HTTP server port (default: 8080)
- `UDP_PORT` - UDP port for frame streaming (default: 4210)
- `GATEWAY_URL` - spore-gateway URL (default: http://localhost:3001)
- `FILTER_APP_LABEL` - Filter nodes by app label (default: pixelstream, set to empty string to disable filtering)
- `MATRIX_WIDTH` - Default matrix width (default: 16)
- `MATRIX_HEIGHT` - Default matrix height (default: 16)
### Adding Custom Presets
1. Create a new preset file in `presets/`:
```javascript
const BasePreset = require('./base-preset');
class MyCustomPreset extends BasePreset {
constructor(width, height) {
super(width, height);
this.name = 'My Custom Preset';
this.description = 'Description of my preset';
}
defineParameters() {
return {
speed: { type: 'range', min: 0.1, max: 5, step: 0.1, default: 1 },
color: { type: 'color', default: 'ff0000' }
};
}
update(frameCount) {
// Animation logic here
}
}
module.exports = MyCustomPreset;
```
2. Register it in `presets/preset-registry.js`:
```javascript
const MyCustomPreset = require('./my-custom-preset');
registerPreset('my-custom', MyCustomPreset);
```
## Preset Editor
The **🎨 Editor** view allows you to create custom animations by combining reusable building blocks without writing code.
### Building Blocks
#### Shapes
- **Circle**: Round shape with adjustable radius
- **Rectangle**: Four-sided shape with width and height
- **Triangle**: Three-sided shape
- **Blob**: Soft circle with energy field falloff
- **Point**: Single pixel
- **Line**: Line between two points
#### Patterns
- **Trail**: Fade effect on previous frames
- **Radial**: Gradient radiating from center
- **Spiral**: Rotating spiral arms
#### Colors
- **Solid**: Single color
- **Gradient**: Linear blend between two colors
- **Palette**: Multi-stop gradient with custom colors
- **Rainbow**: Color wheel effect
#### Animations
- **Move**: Linear movement from point A to B
- **Rotate**: Rotation around center
- **Pulse**: Scale oscillation (breathing effect)
- **Oscillate X/Y**: Sine wave movement on X or Y axis
- **Fade**: Fade in or out
### Creating a Custom Preset
1. Navigate to the **🎨 Editor** view
2. Enter a name and description
3. Add layers (shapes or patterns):
- Select type and configure properties
- Set position, size, and color
- Add optional animation
- Click ** Add Layer**
4. Edit layers with ✏️, reorder with ▲/▼, or delete with ✕
5. Preview with **▶️ Preview** (requires a selected node from Stream view)
6. **💾 Save** to browser localStorage or **📤 Export JSON** to file
### Example Presets
Import example JSON files from `presets/examples/` to learn:
- **Pulsing Circle**: Rainbow circle with pulse animation
- **Bouncing Squares**: Multiple colored squares oscillating
- **Spiral Rainbow**: Rotating spiral with rainbow gradient
- **Moving Triangle**: Triangle with linear movement
Use **📥 Import JSON** to load examples and customize them.
### JSON Format
Presets are stored as JSON:
```json
{
"name": "My Preset",
"description": "Custom animation",
"layers": [
{
"type": "shape",
"shape": "circle",
"position": { "x": 8, "y": 8 },
"size": { "radius": 4 },
"color": { "type": "solid", "value": "ff0000" },
"animation": {
"type": "pulse",
"params": { "minScale": 0.5, "maxScale": 1.5, "frequency": 1.0 }
}
}
]
}
```
See `presets/examples/README.md` for detailed documentation.
## Troubleshooting
### Nodes Not Appearing
- Ensure spore-gateway is running on port 3001
- Verify nodes are on the same network
- Check firewall settings allow UDP port 4210
- Ensure nodes are running PixelStreamController firmware
- Verify spore-gateway has discovered the nodes
- **IMPORTANT**: Nodes must have the `app: pixelstream` label set. LEDLab only displays nodes with this label. Check node labels in spore-gateway.
### WebSocket Connection Issues
- Check browser console for errors
- Verify server is running on port 8080 (default)
- Try refreshing the browser
### Animation Not Streaming
- Select a node first by clicking on it
- Choose a preset from the dropdown
- Verify the node shows "streaming" status
### Custom Preset Issues
- **No preview**: Ensure a node is selected from Stream view first
- **Nothing visible**: Check layer has valid position/size values
- **Errors**: Open browser console (F12) for detailed error messages
## Technology Stack
**Backend:**
- Node.js
- Express.js (HTTP server)
- ws (WebSocket server)
- HTTP client (for querying spore-gateway)
- UDP (Frame streaming only)
**Frontend:**
- Vanilla JavaScript (ES6+)
- Component-based architecture
- CSS3 with CSS variables for theming
- Canvas API for visualization
## License
MIT
## Credits
Based on the SPORE framework and uses styling/components from spore-ui.