diff --git a/lighting_config.json b/lighting_config.json index 8c8161c..758d176 100644 --- a/lighting_config.json +++ b/lighting_config.json @@ -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 } } } \ No newline at end of file diff --git a/src/control_server.py b/src/control_server.py index bafd472..aa761ac 100644 --- a/src/control_server.py +++ b/src/control_server.py @@ -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)