diff --git a/src/main.py b/src/main.py index c059916..4ebe71e 100644 --- a/src/main.py +++ b/src/main.py @@ -15,7 +15,11 @@ presets.load(settings) presets.b = settings.get("brightness", 255) # Use the default preset name from settings (set via controller or defaults) default_preset = settings.get("default") -if default_preset: +if ( + isinstance(default_preset, str) + and default_preset + and default_preset in presets.presets +): presets.select(default_preset) print(f"Selected startup preset: {default_preset}") @@ -35,9 +39,14 @@ while True: wdt.feed() presets.tick() if e.any(): - host, msg = e.recv() - print(msg) - data = json.loads(msg) + try: + host, msg = e.recv() + data = json.loads(msg) + print(msg) + except (ValueError, TypeError): + continue + if not isinstance(data, dict): + continue # Only handle messages with the expected version. if data.get("v") != "1": continue @@ -53,23 +62,60 @@ while True: last_brightness_save = now except (TypeError, ValueError): pass - if "presets" in data: + if isinstance(data.get("presets"), dict): for id, preset_data in data["presets"].items(): - # Convert hex color strings to RGB tuples and reorder based on device color order - if "c" in preset_data: - preset_data["c"] = convert_and_reorder_colors(preset_data["c"], settings) + if not isinstance(preset_data, dict): + continue + # Convert hex color strings to RGB tuples and reorder based on device colour order. + color_key = "c" if "c" in preset_data else ("colors" if "colors" in preset_data else None) + if color_key is not None: + try: + preset_data[color_key] = convert_and_reorder_colors( + preset_data[color_key], settings + ) + except (TypeError, ValueError): + continue presets.edit(id, preset_data) print(f"Edited preset {id}: {preset_data.get('name', '')}") - if settings.get("name") in data.get("select", {}): + if isinstance(data.get("select"), dict) and settings.get("name") in data["select"]: select_list = data["select"][settings.get("name")] # Select value is always a list: ["preset_name"] or ["preset_name", step] - if select_list: + if isinstance(select_list, list) and select_list: preset_name = select_list[0] step = select_list[1] if len(select_list) > 1 else None - presets.select(preset_name, step=step) + if isinstance(preset_name, str): + presets.select(preset_name, step=step) if "default" in data: - settings["default"] = data["default"] - print(f"Set startup preset to: {data['default']}") - settings.save() + default_name = data["default"] + this_device_name = settings.get("name") + this_device_name_norm = ( + this_device_name.strip().lower() + if isinstance(this_device_name, str) + else None + ) + should_apply_default = True + if "targets" in data: + # When targets are present, default must only apply to named targets. + should_apply_default = False + targets = data.get("targets") + if isinstance(targets, list) and this_device_name_norm: + normalized_targets = [ + target.strip().lower() + for target in targets + if isinstance(target, str) and target.strip() + ] + should_apply_default = this_device_name_norm in normalized_targets + if not should_apply_default: + print("Ignored default: device not in targets") + if ( + should_apply_default + and + isinstance(default_name, str) + and default_name + and default_name in presets.presets + ): + settings["default"] = default_name + print(f"Set startup preset to: {default_name}") + settings.save() if "save" in data: presets.save() diff --git a/src/presets.py b/src/presets.py index 56ce690..c5163dd 100644 --- a/src/presets.py +++ b/src/presets.py @@ -55,9 +55,10 @@ class Presets: order = settings if settings is not None else "rgb" self.presets = {} for name, preset_data in data.items(): - if "c" in preset_data: - preset_data["c"] = convert_and_reorder_colors( - preset_data["c"], order + color_key = "c" if "c" in preset_data else ("colors" if "colors" in preset_data else None) + if color_key is not None: + preset_data[color_key] = convert_and_reorder_colors( + preset_data[color_key], order ) self.presets[name] = Preset(preset_data) if self.presets: @@ -89,6 +90,9 @@ class Presets: next(self.generator) except StopIteration: self.generator = None + except Exception as e: + print(f"Error in tick: {e}") + self.generator = None def select(self, preset_name, step=None): # Auto-create simple built-in presets for common names on first use