diff --git a/src/display_manager.py b/src/display_manager.py index b945f9b9..ee7a1522 100644 --- a/src/display_manager.py +++ b/src/display_manager.py @@ -82,6 +82,7 @@ class DisplayManager: options.pixel_mapper_config = hardware_config.get('pixel_mapper_config', '') options.row_address_type = hardware_config.get('row_address_type', 0) options.multiplexing = hardware_config.get('multiplexing', 0) + options.panel_type = hardware_config.get('panel_type', '') options.disable_hardware_pulsing = hardware_config.get('disable_hardware_pulsing', False) options.show_refresh_rate = hardware_config.get('show_refresh_rate', False) options.limit_refresh_rate_hz = hardware_config.get('limit_refresh_rate_hz', 90) diff --git a/web_interface/blueprints/api_v3.py b/web_interface/blueprints/api_v3.py index b837099f..bd9f6cb1 100644 --- a/web_interface/blueprints/api_v3.py +++ b/web_interface/blueprints/api_v3.py @@ -702,7 +702,7 @@ def save_main_config(): display_fields = ['rows', 'cols', 'chain_length', 'parallel', 'brightness', 'hardware_mapping', 'gpio_slowdown', 'scan_mode', 'disable_hardware_pulsing', 'inverse_colors', 'show_refresh_rate', 'pwm_bits', 'pwm_dither_bits', 'pwm_lsb_nanoseconds', 'limit_refresh_rate_hz', 'use_short_date_format', - 'max_dynamic_duration_seconds'] + 'max_dynamic_duration_seconds', 'led_rgb_sequence', 'multiplexing', 'panel_type'] if any(k in data for k in display_fields): if 'display' not in current_config: @@ -712,12 +712,35 @@ def save_main_config(): if 'runtime' not in current_config['display']: current_config['display']['runtime'] = {} + # Allowed values for validated string fields + LED_RGB_ALLOWED = {'RGB', 'RBG', 'GRB', 'GBR', 'BRG', 'BGR'} + PANEL_TYPE_ALLOWED = {'', 'FM6126A', 'FM6127'} + + # Validate led_rgb_sequence + if 'led_rgb_sequence' in data and data['led_rgb_sequence'] not in LED_RGB_ALLOWED: + return jsonify({'status': 'error', 'message': f"Invalid LED RGB sequence '{data['led_rgb_sequence']}'. Allowed values: {', '.join(sorted(LED_RGB_ALLOWED))}"}), 400 + + # Validate panel_type + if 'panel_type' in data and data['panel_type'] not in PANEL_TYPE_ALLOWED: + return jsonify({'status': 'error', 'message': f"Invalid panel type '{data['panel_type']}'. Allowed values: Standard (empty), FM6126A, FM6127"}), 400 + + # Validate multiplexing + if 'multiplexing' in data: + try: + mux_val = int(data['multiplexing']) + if mux_val < 0 or mux_val > 22: + return jsonify({'status': 'error', 'message': f"Invalid multiplexing value '{data['multiplexing']}'. Must be an integer from 0 to 22."}), 400 + except (ValueError, TypeError): + return jsonify({'status': 'error', 'message': f"Invalid multiplexing value '{data['multiplexing']}'. Must be an integer from 0 to 22."}), 400 + # Handle hardware settings for field in ['rows', 'cols', 'chain_length', 'parallel', 'brightness', 'hardware_mapping', 'scan_mode', - 'pwm_bits', 'pwm_dither_bits', 'pwm_lsb_nanoseconds', 'limit_refresh_rate_hz']: + 'pwm_bits', 'pwm_dither_bits', 'pwm_lsb_nanoseconds', 'limit_refresh_rate_hz', + 'led_rgb_sequence', 'multiplexing', 'panel_type']: if field in data: if field in ['rows', 'cols', 'chain_length', 'parallel', 'brightness', 'scan_mode', - 'pwm_bits', 'pwm_dither_bits', 'pwm_lsb_nanoseconds', 'limit_refresh_rate_hz']: + 'pwm_bits', 'pwm_dither_bits', 'pwm_lsb_nanoseconds', 'limit_refresh_rate_hz', + 'multiplexing']: current_config['display']['hardware'][field] = int(data[field]) else: current_config['display']['hardware'][field] = data[field] diff --git a/web_interface/templates/v3/partials/display.html b/web_interface/templates/v3/partials/display.html index 1d80d275..aeebd915 100644 --- a/web_interface/templates/v3/partials/display.html +++ b/web_interface/templates/v3/partials/display.html @@ -94,6 +94,61 @@ +
Color channel order for your LED panels
+Multiplexing scheme for your LED panels
+Special panel chipset initialization (use Standard unless your panel requires it)
+