diff --git a/Pipfile b/Pipfile index 4b72a0c..611b2d3 100644 --- a/Pipfile +++ b/Pipfile @@ -19,5 +19,5 @@ websocket-client = "*" python_version = "3.12" [scripts] -main = "python main.py" +main = "python src/main.py" dev = 'watchfiles "python src/main.py" src' diff --git a/settings.json b/settings.json index 34a58c3..faee374 100644 --- a/settings.json +++ b/settings.json @@ -9,8 +9,8 @@ "colors": [ "#968a00" ], - "brightness": 21, - "pattern": "off", + "brightness": 57, + "pattern": "on", "delay": 99, "n1": 10, "n2": 10, @@ -21,12 +21,12 @@ "patterns": { "pulse": { "colors": [ - "#000000" + "#ff00ff" ], - "delay": 99, - "n1": 10, + "delay": 657, + "n1": 100, "n2": 10, - "n3": 10, + "n3": 100, "n4": 10, "n5": 10, "n6": 10 @@ -45,7 +45,7 @@ }, "on": { "colors": [ - "#968a00" + "#ff00ff" ], "delay": 99, "n1": 10, @@ -72,7 +72,7 @@ "#000000" ], "delay": 99, - "n1": 10, + "n1": -17, "n2": 10, "n3": 10, "n4": 10, @@ -90,6 +90,38 @@ "n4": 10, "n5": 10, "n6": 10 + }, + "transition": { + "colors": [ + "#ff00ff", + "#ffff00" + ], + "delay": 10000, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "circle": { + "colors": [ + "#0000f8" + ], + "delay": 1538, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "chase": { + "colors": [ + "#000091", + "#00d800" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 } } } @@ -103,8 +135,8 @@ "#0000ff", "#ff0000" ], - "brightness": 73, - "pattern": "transition", + "brightness": 39, + "pattern": "on", "delay": 10000, "n1": 10, "n2": 10, @@ -127,8 +159,8 @@ }, "on": { "colors": [ - "#ffff00", - "#0000ff" + "#ff0062", + "#000000" ], "delay": 99, "n1": 10, @@ -168,7 +200,7 @@ "#0000ff", "#ff0000" ], - "delay": 10000, + "delay": 399, "n1": 10, "n2": 10, "n3": 10, @@ -178,12 +210,12 @@ }, "n_chase": { "n1": 11, - "n2": 11, + "n2": 13, "n3": 10, "n4": 10, "n5": 10, "n6": 10, - "delay": 99, + "delay": 639, "colors": [ "#0000ff" ] @@ -197,6 +229,28 @@ "n2": 10, "n3": 10, "n4": 10 + }, + "circle": { + "colors": [ + "#0001bd", + "#00ff00" + ], + "delay": 1778, + "n1": 10, + "n2": 40, + "n3": 40, + "n4": 0 + }, + "chase": { + "colors": [ + "#8d00ff", + "#ff0077" + ], + "delay": 69, + "n1": 30, + "n2": 30, + "n3": 5, + "n4": 30 } } } @@ -215,8 +269,8 @@ "#00ff00", "#000000" ], - "brightness": 6, - "pattern": "flicker", + "brightness": 44, + "pattern": "on", "delay": 520, "patterns": { "flicker": { @@ -228,6 +282,26 @@ "n2": 10, "n3": 10, "n4": 10 + }, + "on": { + "colors": [ + "#ff00ff" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 } } } @@ -244,11 +318,21 @@ "#00ff00", "#000000" ], - "brightness": 6, + "brightness": 13, "pattern": "on", "delay": 520, "patterns": { "on": { + "colors": [ + "#ff00ff" + ], + "delay": 988, + "n1": 100, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { "colors": [ "#000000" ], @@ -257,6 +341,16 @@ "n2": 10, "n3": 10, "n4": 10 + }, + "pulse": { + "n1": 100, + "n2": 100, + "n3": 100, + "n4": 10, + "delay": 411, + "colors": [ + "#ff00ff" + ] } } } @@ -272,8 +366,8 @@ "#00ff00", "#000000" ], - "brightness": 6, - "pattern": "transition", + "brightness": 76, + "pattern": "on", "delay": 520, "n1": -17, "n2": 10, @@ -284,7 +378,7 @@ "patterns": { "on": { "colors": [ - "#000000" + "#ff00ff" ], "delay": 99, "n1": 10, @@ -301,6 +395,16 @@ "n2": 10, "n3": 10, "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 } } } @@ -316,8 +420,8 @@ "#00ff00", "#000000" ], - "brightness": 6, - "pattern": "flicker", + "brightness": 59, + "pattern": "on", "delay": 520, "n1": 10, "n2": 10, @@ -326,7 +430,67 @@ "n5": 10, "n6": 10, "patterns": { - "flicker": {} + "flicker": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "on": { + "colors": [ + "#ff00ff" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "pulse": { + "delay": 1096, + "colors": [ + "#0000ff" + ], + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "rainbow": { + "n1": 1, + "n2": 10, + "n3": 10, + "n4": 10, + "delay": 2884, + "colors": [ + "#000000" + ] + }, + "transition": { + "colors": [ + "#0000ff", + "#ff0000" + ], + "delay": 269, + "n1": 5, + "n2": 10, + "n3": 10, + "n4": 10 + } } } }, @@ -341,11 +505,51 @@ "#00ff00", "#000000" ], - "brightness": 6, - "pattern": "flicker", + "brightness": 141, + "pattern": "on", "delay": 520, "patterns": { - "flicker": {} + "flicker": { + "colors": [ + "#000078" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "on": { + "colors": [ + "#ff00ff" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "pulse": { + "colors": [ + "#0000a0", + "#720000" + ], + "delay": 4102, + "n1": 100, + "n2": 10, + "n3": 100, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } } } }, @@ -361,10 +565,39 @@ "#000000" ], "brightness": 6, - "pattern": "flicker", + "pattern": "on", "delay": 520, "patterns": { - "flicker": {} + "flicker": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "on": { + "colors": [ + "#00c4a5" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } } } }, @@ -380,20 +613,260 @@ "#000000" ], "brightness": 6, - "pattern": "flicker", + "pattern": "on", "delay": 520, "patterns": { - "flicker": {} + "flicker": { + "colors": [ + "#ff00d6" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "on": { + "colors": [ + "#ff00ff" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } + } + } + }, + "front1": { + "names": [ + "front1" + ], + "settings": { + "colors": [ + "#0000ff", + "#c30074", + "#00ff00", + "#000000" + ], + "brightness": 255, + "pattern": "on", + "delay": 520, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10, + "n5": 10, + "n6": 10, + "patterns": { + "on": { + "colors": [ + "#ff00ff", + "#0000ff" + ], + "delay": 2409, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "pulse": { + "colors": [ + "#000090" + ], + "delay": 1051, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "transition": { + "colors": [ + "#ff0000", + "#0000ff" + ], + "delay": 2564, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } + } + } + }, + "front2": { + "names": [ + "front2" + ], + "settings": { + "colors": [ + "#0000ff", + "#c30074", + "#00ff00", + "#000000" + ], + "brightness": 255, + "pattern": "off", + "delay": 520, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10, + "n5": 10, + "n6": 10, + "patterns": { + "on": { + "colors": [ + "#ff00ff" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "rainbow": { + "colors": [ + "#00006b" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "transition": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } + } + } + }, + "front3": { + "names": [ + "front3" + ], + "settings": { + "colors": [ + "#0000ff", + "#c30074", + "#00ff00", + "#000000" + ], + "brightness": 29, + "pattern": "on", + "delay": 520, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10, + "n5": 10, + "n6": 10, + "patterns": { + "on": { + "colors": [ + "#d200d1" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "off": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "rainbow": { + "colors": [ + "#00006b" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + }, + "transition": { + "colors": [ + "#000000" + ], + "delay": 99, + "n1": 10, + "n2": 10, + "n3": 10, + "n4": 10 + } } } } }, - "patterns": [ - "on", - "off", - "rainbow", - "transition", - "n_chase", - "pulse" - ] + "patterns": { + "on": {}, + "off": {}, + "rainbow": { + "Step Rate": "n1" + }, + "transition": {}, + "chase": { + "Colour 1 Length": "n1", + "Colour 2 Length": "n2", + "Step 1": "n3", + "Step 2": "n4" + }, + "pulse": { + "Attack": "n1", + "Hold": "n2", + "Decay": "n3" + }, + "circle": { + "Head Rate": "n1", + "Max Length": "n2", + "Tail Rate": "n3", + "Min Length": "n4" + } + } } \ No newline at end of file diff --git a/src/main.py b/src/main.py index 8651e25..f29a0c2 100644 --- a/src/main.py +++ b/src/main.py @@ -95,6 +95,38 @@ class App: async_mainloop(self.root) + def get_n_parameter_name(self, pattern_name, n_index): + """Get the descriptive name for an n parameter based on the pattern. + Returns None if no description exists.""" + patterns_config = self.settings.get("patterns", {}) + pattern_config = patterns_config.get(pattern_name, {}) + + # Find which n parameter this index maps to + n_key = f"n{n_index}" + for desc_name, mapped_n in pattern_config.items(): + if mapped_n == n_key: + return desc_name + + # If no mapping found, return None + return None + + def update_n_labels(self, tab, pattern_name): + """Update the n parameter labels to show descriptive names and hide/show inputs.""" + for i in range(1, 5): + label_key = f"n{i}_label" + frame_key = f"n{i}_frame" + + if label_key in tab.widgets and frame_key in tab.widgets: + desc_name = self.get_n_parameter_name(pattern_name, i) + + if desc_name: + # Show the input and update label + tab.widgets[frame_key].grid() + tab.widgets[label_key].config(text=desc_name) + else: + # Hide the input if no description + tab.widgets[frame_key].grid_remove() + def get_pattern_settings(self, tab_name, pattern_name): """Get pattern-specific settings (colors, delay, n params). Returns defaults if not found.""" light_settings = self.settings["lights"][tab_name]["settings"] @@ -283,8 +315,11 @@ class App: for i in range(1, 5): n_frame = tk.Frame(n_inputs_inner_frame, bg=bg_color) n_frame.grid(row=(i-1)//2, column=(i-1)%2, padx=10, pady=10) + n_inputs[f"n{i}_frame"] = n_frame # Store frame reference for hiding/showing - tk.Label(n_frame, text=f"n{i}", font=("Arial", 20), bg=bg_color, fg=fg_color).pack(pady=(0, 5)) + n_label = tk.Label(n_frame, text=f"n{i}", font=("Arial", 20), bg=bg_color, fg=fg_color) + n_label.pack(pady=(0, 5)) + n_inputs[f"n{i}_label"] = n_label # Store label reference # Create a frame for the input with arrows on both sides input_container = tk.Frame(n_frame, bg=bg_color) @@ -377,6 +412,14 @@ class App: "n3_var": n_inputs["n3_var"], "n4": n_inputs["n4"], "n4_var": n_inputs["n4_var"], + "n1_label": n_inputs["n1_label"], + "n2_label": n_inputs["n2_label"], + "n3_label": n_inputs["n3_label"], + "n4_label": n_inputs["n4_label"], + "n1_frame": n_inputs["n1_frame"], + "n2_frame": n_inputs["n2_frame"], + "n3_frame": n_inputs["n3_frame"], + "n4_frame": n_inputs["n4_frame"], "selected_color_index": 0, # Default to the first color } tab.colors_in_palette = initial_colors.copy() # Store the list of hex colors for this tab @@ -476,6 +519,7 @@ class App: # The initial call to update_ui_for_pattern now only sets slider values and highlights self.update_ui_for_pattern(tab, initial_pattern) + self.update_n_labels(tab, initial_pattern) # Update n parameter labels def refresh_color_palette_display(self, tab): """Clears and repopulates the color swatches in the palette display.""" @@ -678,6 +722,7 @@ class App: # Update UI visibility based on the current pattern self.update_ui_for_pattern(current_tab_widget, initial_pattern) + self.update_n_labels(current_tab_widget, initial_pattern) # Update n parameter labels def reload_config(self): print("Reloading configuration...") @@ -1003,6 +1048,7 @@ class App: self.highlight_pattern_button(current_tab_widget, pattern_name) self.update_ui_for_pattern(current_tab_widget, pattern_name) # Update UI based on new pattern + self.update_n_labels(current_tab_widget, pattern_name) # Update n parameter labels await self.websocket_client.send_data(payload) print(f"Sent pattern payload: {payload}")