fix(presets): normalize loaded colours before pattern math

This commit is contained in:
2026-03-22 00:36:53 +13:00
parent 4c7646b2fe
commit 8403f36a1f
4 changed files with 16 additions and 7 deletions

View File

@@ -11,7 +11,7 @@ settings = Settings()
print(settings) print(settings)
presets = Presets(settings["led_pin"], settings["num_leds"]) presets = Presets(settings["led_pin"], settings["num_leds"])
presets.load() presets.load(settings)
presets.b = settings.get("brightness", 255) presets.b = settings.get("brightness", 255)
# Use the default preset name from settings (set via controller or defaults) # Use the default preset name from settings (set via controller or defaults)
default_preset = settings.get("default") default_preset = settings.get("default")

View File

@@ -2,6 +2,7 @@ from machine import Pin
from neopixel import NeoPixel from neopixel import NeoPixel
from preset import Preset from preset import Preset
from patterns import Blink, Rainbow, Pulse, Transition, Chase, Circle from patterns import Blink, Rainbow, Pulse, Transition, Chase, Circle
from utils import convert_and_reorder_colors
import json import json
@@ -35,8 +36,13 @@ class Presets:
json.dump({name: preset.to_dict() for name, preset in self.presets.items()}, f) json.dump({name: preset.to_dict() for name, preset in self.presets.items()}, f)
return True return True
def load(self): def load(self, settings=None):
"""Load presets from a file.""" """Load presets from a file.
`settings` is used to convert hex strings in `c` to RGB tuples and apply
the device's colour order (same as ESPNow receive). If omitted, RGB order
is assumed.
"""
try: try:
with open("presets.json", "r") as f: with open("presets.json", "r") as f:
data = json.load(f) data = json.load(f)
@@ -46,10 +52,13 @@ class Presets:
self.save() self.save()
return True return True
order = settings if settings is not None else "rgb"
self.presets = {} self.presets = {}
for name, preset_data in data.items(): for name, preset_data in data.items():
if "c" in preset_data: if "c" in preset_data:
preset_data["c"] = [tuple(color) for color in preset_data["c"]] preset_data["c"] = convert_and_reorder_colors(
preset_data["c"], order
)
self.presets[name] = Preset(preset_data) self.presets[name] = Preset(preset_data)
if self.presets: if self.presets:
print("Loaded presets:") print("Loaded presets:")

View File

@@ -43,8 +43,8 @@ def convert_and_reorder_colors(colors, settings_or_color_order):
reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]]) reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]])
converted_colors.append(reordered) converted_colors.append(reordered)
elif isinstance(color, (list, tuple)) and len(color) == 3: elif isinstance(color, (list, tuple)) and len(color) == 3:
# Already a tuple/list, just reorder # Already a tuple/list, just reorder (JSON may use string numbers)
rgb = tuple(color) rgb = tuple(int(x) for x in color)
reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]]) reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]])
converted_colors.append(reordered) converted_colors.append(reordered)
else: else:

View File

@@ -644,7 +644,7 @@ def test_preset_save_load():
assert patterns.save(), "Save should return True" assert patterns.save(), "Save should return True"
reloaded = Presets(settings["led_pin"], settings["num_leds"]) reloaded = Presets(settings["led_pin"], settings["num_leds"])
assert reloaded.load(), "Load should return True" assert reloaded.load(settings), "Load should return True"
preset = reloaded.presets.get("saved_preset") preset = reloaded.presets.get("saved_preset")
assert preset is not None, "Preset should be loaded" assert preset is not None, "Preset should be loaded"