ble2wled.simulator - LED Simulator and Mock Beacons
LED strip simulator with visual CLI output.
This module provides a simulator for testing beacon visualization without requiring a real WLED device. The simulator displays the LED strip state as colored dots in the terminal using ANSI escape codes.
The simulator implements the LEDController interface and can be used as a drop-in replacement for WLEDHTTPController or WLEDUDPController.
Example
Simulate beacon visualization:
from ble2wled.simulator import LEDSimulator
from ble2wled import BeaconState, run_wled_beacons
# Create simulator
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
# Create beacon state
beacon_state = BeaconState()
# Run animation with simulator (no real WLED needed)
run_wled_beacons(
simulator,
led_count=60,
beacon_state=beacon_state,
update_interval=0.05
)
- class ble2wled.simulator.LEDSimulator(led_count: int = 60, rows: int = 10, cols: int = 6)[source]
Bases:
LEDControllerLED strip simulator with visual terminal output.
Displays the LED strip as a grid of colored dots in the terminal using ANSI 24-bit color codes. Useful for testing beacon visualization without a real WLED device.
The grid is arranged in rows x cols format. For example, with 60 LEDs in a 10x6 grid, LED 0 is top-left, LED 5 is top-right, LED 6 is second-row-left, etc.
- lock
Thread-safe access to LED data.
- Type:
Example
Create a 10x6 grid simulator:
simulator = LEDSimulator(led_count=60, rows=10, cols=6) leds = [[255, 0, 0] for _ in range(60)] # All red simulator.update(leds)
- __init__(led_count: int = 60, rows: int = 10, cols: int = 6)[source]
Initialize the LED simulator.
- Parameters:
- Raises:
ValueError – If rows x cols does not equal led_count.
Example
Create 120-LED simulator (12 rows x 10 cols):
simulator = LEDSimulator(led_count=120, rows=12, cols=10)
- update(leds: List[List[int]]) None[source]
Update and display the LED strip.
Updates the current LED state and renders the grid to terminal. Uses ANSI 24-bit true color escape codes for each LED.
- Parameters:
leds (List[List[int]]) – LED data as list of [R, G, B] triplets. Expected length: led_count.
Example
Display a gradient:
import time from ble2wled.simulator import LEDSimulator simulator = LEDSimulator(led_count=60) for i in range(60): leds = [[0, 0, 0] for _ in range(60)] leds[i] = [255, 100, 0] # Orange simulator.update(leds) time.sleep(0.05)
- class ble2wled.simulator.MockBeaconGenerator(num_beacons: int = 3, rssi_range: tuple = (-90, -30))[source]
Bases:
objectGenerate mock beacon data for simulator testing.
Creates synthetic BLE beacon data that changes over time to simulate real beacon movement and signal strength variation.
Example
Generate beacon updates:
from ble2wled.simulator import MockBeaconGenerator from ble2wled import BeaconState generator = MockBeaconGenerator(num_beacons=3) beacon_state = BeaconState() for _ in range(100): beacons = generator.update() for beacon_id, rssi in beacons.items(): beacon_state.update(beacon_id, rssi)
- __init__(num_beacons: int = 3, rssi_range: tuple = (-90, -30))[source]
Initialize mock beacon generator.
- Parameters:
Example
Generate 5 beacons with custom RSSI range:
generator = MockBeaconGenerator( num_beacons=5, rssi_range=(-100, -20) )
- update(time_delta: float = 0.1) dict[source]
Update beacon positions and signal strengths.
Beacons move in a circular pattern and signal strength oscillates around their base RSSI value, simulating realistic beacon movement.
- Parameters:
time_delta (float) – Time step for simulation. Default: 0.1 seconds.
- Returns:
Beacon data as {beacon_id: rssi_value}.
- Return type:
Example
Step through beacon updates:
import time generator = MockBeaconGenerator(num_beacons=3) for _ in range(100): beacons = generator.update(time_delta=0.05) # Update beacon_state with beacons data time.sleep(0.05)
Overview
The simulator module provides tools for testing beacon visualization without requiring a real WLED device or MQTT broker. It includes:
LEDSimulator - Visual LED display in terminal using ANSI colors
MockBeaconGenerator - Generates realistic simulated beacon data
CLI interface - Command-line tool for testing
Quick Example
from ble2wled.simulator import LEDSimulator, MockBeaconGenerator
from ble2wled.states import BeaconState
from ble2wled.animation import run_wled_beacons
# Create simulator
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
# Create beacon state
state = BeaconState()
# Generate mock beacons
generator = MockBeaconGenerator(state, num_beacons=3, led_count=60)
generator.start()
# Run animation
try:
run_wled_beacons(simulator, 60, state, update_interval=0.1)
finally:
generator.stop()
Classes
LEDSimulator
Displays LEDs as colored blocks in terminal using ANSI 24-bit colors.
Attributes:
led_count(int) - Total number of LEDsrows(int, default 10) - Grid rowscols(int, default 6) - Grid columnswidth(int) - Terminal width needed (cols * 4)height(int) - Terminal height needed (rows + 5)
Methods:
update(leds: List[List[int]])- Display LED dataclear()- Clear display
Requirements:
Terminal must support ANSI 24-bit colors
Terminal width must be at least
cols * 4Terminal height must be at least
rows + 5
Example:
from ble2wled.simulator import LEDSimulator
# Create 60-LED display in 10×6 grid
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
# Display colors
leds = [[255, 0, 0]] * 30 + [[0, 255, 0]] * 30
simulator.update(leds)
# Clear display
simulator.clear()
LED Count and Grid Layout
The LED count must equal rows × cols:
# 60 LEDs (10 rows × 6 columns)
sim = LEDSimulator(led_count=60, rows=10, cols=6)
# 100 LEDs (20 rows × 5 columns)
sim = LEDSimulator(led_count=100, rows=20, cols=5)
# 120 LEDs (12 rows × 10 columns)
sim = LEDSimulator(led_count=120, rows=12, cols=10)
MockBeaconGenerator
Generates simulated beacon data for testing.
Attributes:
beacon_state(BeaconState) - State to update with beaconsnum_beacons(int) - Number of beacons to simulateled_count(int) - Total LEDs (for position bounds)update_interval(float, default 0.1) - Update interval in seconds
Methods:
start()- Start generating beacons (non-blocking, background thread)stop()- Stop generatoris_running(property) - Whether generator is running
Behavior:
Generates random beacon movements:
Beacons move randomly along LED strip
RSSI values change realistically (-20 to -90 dBm)
Updates at specified interval
Beacons persist until stopped
Example:
from ble2wled.simulator import MockBeaconGenerator
from ble2wled.states import BeaconState
state = BeaconState()
# Generate 5 mock beacons
gen = MockBeaconGenerator(state, num_beacons=5, led_count=60)
gen.start()
# Beacons are now updating in background
import time
time.sleep(5)
# Stop generator
gen.stop()
Examples
Visual LED Display
from ble2wled.simulator import LEDSimulator
from ble2wled.states import BeaconState
from ble2wled.colors import beacon_id_to_hue, hsv_to_rgb
import time
# Create display
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
state = BeaconState()
# Add some beacons
state.update_or_create('beacon_1', position=15, rssi=-50)
state.update_or_create('beacon_2', position=30, rssi=-60)
state.update_or_create('beacon_3', position=45, rssi=-70)
# Render beacons
leds = [[0, 0, 0]] * 60
for beacon_id, beacon in state.beacons.items():
pos = int(beacon.position)
hue = beacon_id_to_hue(beacon_id)
r, g, b = hsv_to_rgb(hue, 1.0, 1.0)
leds[pos] = [r, g, b]
# Display
simulator.update(leds)
Mock Beacon Animation
from ble2wled.simulator import LEDSimulator, MockBeaconGenerator
from ble2wled.states import BeaconState
from ble2wled.animation import run_wled_beacons
# Setup
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
state = BeaconState()
# Generate mock beacons
generator = MockBeaconGenerator(state, num_beacons=3, led_count=60)
generator.start()
# Run animation
try:
run_wled_beacons(
simulator,
led_count=60,
beacon_state=state,
update_interval=0.1,
trail_length=8,
fade_factor=0.75
)
finally:
generator.stop()
Custom Grid Layouts
Adjust grid for different terminal sizes:
from ble2wled.simulator import LEDSimulator
# Narrow terminal (12 columns wide)
sim_narrow = LEDSimulator(led_count=60, rows=5, cols=12)
# Wide terminal (4 columns wide)
sim_wide = LEDSimulator(led_count=60, rows=15, cols=4)
# Very wide display
sim_very_wide = LEDSimulator(led_count=120, rows=6, cols=20)
Programmatic LED Display
from ble2wled.simulator import LEDSimulator
simulator = LEDSimulator(led_count=60, rows=10, cols=6)
# Rainbow gradient
leds = []
for i in range(60):
hue = (i / 60) * 360
from ble2wled.colors import hsv_to_rgb
r, g, b = hsv_to_rgb(hue, 1.0, 1.0)
leds.append([r, g, b])
simulator.update(leds)
Display Output Format
The simulator displays LEDs as colored blocks:
██████████████████████████████
██████████████████████████████
██████████████████████████████
███░░░░███░░░░██████████░░████
██░░░░░░░░░░░░██████████████░░
██░░░░░░░░░░░░██████████░░░░░░
██████████░░░░██░░░░██░░░░░░░░
██████████░░░░██░░░░██░░░░░░░░
██████████░░░░██░░░░██░░░░░░░░
██████████████████████████░░░░
Bright colors = bright LEDs
Dim colors = dim LEDs
Each block is one LED
CLI Usage
Run simulator from command line:
python -m ble2wled.cli_simulator
With options:
python -m ble2wled.cli_simulator \
--led-count 120 \
--rows 12 \
--cols 10 \
--beacons 5 \
--update-interval 0.05 \
--trail-length 15 \
--fade-factor 0.75 \
--duration 60
With MQTT:
python -m ble2wled.cli_simulator --mqtt \
--mqtt-broker 192.168.1.100 \
--mqtt-location living_room \
--mqtt-username user \
--mqtt-password pass
Performance
Terminal Requirements
For smooth animation:
Terminal must support ANSI 24-bit colors
Terminal width >= cols * 4
Terminal height >= rows + 5
Adequate CPU for rendering
Typical Performance
60 LEDs (10×6): ~50fps on modern CPU
120 LEDs (12×10): ~25fps
300 LEDs (20×15): ~5-10fps
Optimization Tips
For CPU-constrained systems:
# Use fewer LEDs
simulator = LEDSimulator(led_count=30, rows=5, cols=6)
# Use slower update interval
run_wled_beacons(controller, ..., update_interval=0.2)
# Use shorter trails
run_wled_beacons(controller, ..., trail_length=4)
For high-speed animation:
# Use moderate LED count
simulator = LEDSimulator(led_count=100, rows=10, cols=10)
# Use fast update interval
run_wled_beacons(controller, ..., update_interval=0.02)
Troubleshooting
Nothing displays or error about terminal:
Try smaller grid:
simulator = LEDSimulator(led_count=30, rows=5, cols=6)
Colors look wrong:
Ensure terminal supports 24-bit colors. Most modern terminals do.
Animation stutters:
Reduce LED count or increase update_interval.
See Also
CLI Simulator Guide - CLI simulator guide
ble2wled.animation - Animation Loop - Animation loop
ble2wled.states - Beacon State Management - Beacon state
ble2wled.colors - Color Calculations - Color calculations