Add new pattern 'alternating_pulse' (ap): odd beat pulses color1 on odd bars, even beat pulses color2 on even bars; preserve existing alternating_phase; compact payloads and white guard retained

This commit is contained in:
2025-10-04 01:58:02 +13:00
parent dc6d48a44b
commit 8ad7f41d77
2 changed files with 57 additions and 2 deletions

View File

@@ -42,8 +42,8 @@
}
],
"selected_color_indices": [
5,
2
4,
3
],
"pattern_parameters": {
"alternating": {
@@ -136,6 +136,13 @@
"n2": 10,
"n3": 1,
"n4": 1
},
"alternating_pulse": {
"delay": 100,
"n1": 10,
"n2": 10,
"n3": 1,
"n4": 1
}
}
}

View File

@@ -47,6 +47,8 @@ PATTERN_NAMES = {
"specto": "s",
"radiate": "rd",
"segmented_movement": "sm",
# New: alternate two palette colors by pulsing per beat (backend-only logical name)
"alternating_pulse": "apu",
# Short names pass through (for frontend use)
"o": "o",
"f": "f",
@@ -415,6 +417,47 @@ class LightingController:
await self.led_controller.send_data(payload)
async def _handle_alternating_pulse(self):
"""Handle APU: color1 on odd beat for odd bars, color2 on even beat for even bars."""
phase = self.beat_index % 2
color1 = self._palette_color(0)
color2 = self._palette_color(1)
if color1 == (255, 255, 255):
color1 = (254, 254, 254)
if color2 == (255, 255, 255):
color2 = (254, 254, 254)
# Define bar groups by numeric parity
even_bars = ["100", "102", "104", "106"]
odd_bars = ["101", "103", "105", "107"]
# Default: turn bars off this beat
payload = {
"d": {
"t": "b",
"pt": "o", # off by default
# Provide pulse envelope params in defaults for bars we enable
"n1": self.n1,
"n2": self.n2,
"dl": self.delay,
}
}
# Activate the correct half with the correct color
if phase == 0:
# Even beat -> even bars use color2
active_bars = even_bars
active_color = color2
else:
# Odd beat -> odd bars use color1
active_bars = odd_bars
active_color = color1
for bar_name in active_bars:
payload[bar_name] = {"pt": "p", "cl": [active_color]}
await self.led_controller.send_data(payload)
async def handle_beat(self, bpm_value):
"""Handle beat from sound detector."""
if not self.beat_sending_enabled or not self.current_pattern:
@@ -435,6 +478,8 @@ class LightingController:
await self._handle_sequential_pulse()
elif self.current_pattern == "alternating_phase":
await self._handle_alternating_phase()
elif self.current_pattern == "alternating_pulse":
await self._handle_alternating_pulse()
elif self.current_pattern:
await self._send_normal_pattern()
@@ -645,6 +690,9 @@ class ControlServer:
self.lighting_controller._save_pattern_parameters(self.lighting_controller.current_pattern)
# Switch to new pattern and load its parameters
# Normalize shortnames for backend-only patterns
if pattern == "ap":
pattern = "alternating_pulse"
self.lighting_controller.current_pattern = pattern
self.lighting_controller._load_pattern_parameters(pattern)