diff --git a/bambu_run/forms.py b/bambu_run/forms.py index 09ba672..0c81920 100644 --- a/bambu_run/forms.py +++ b/bambu_run/forms.py @@ -52,7 +52,7 @@ class FilamentForm(forms.ModelForm): model = Filament fields = [ 'tray_uuid', 'tag_uid', 'tag_id', 'created_by', - 'filament_type', 'type', 'sub_type', 'brand', 'color', 'color_hex', + 'filament_type', 'type', 'sub_type', 'brand', 'color', 'color_hex', 'is_transparent', 'diameter', 'initial_weight_grams', 'remaining_percent', 'remaining_weight_grams', 'is_loaded_in_ams', 'current_tray_id', @@ -71,10 +71,10 @@ class FilamentForm(forms.ModelForm): }), 'tag_id': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional - User-defined ID'}), 'created_by': forms.Select(attrs={'class': 'form-select'}), - 'filament_type': forms.Select(attrs={'class': 'form-select'}), - 'type': forms.HiddenInput(), - 'sub_type': forms.HiddenInput(), - 'brand': forms.HiddenInput(), + 'filament_type': forms.Select(attrs={'class': 'form-select', 'id': 'id_filament_type'}), + 'type': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g., PLA, PETG, ABS'}), + 'sub_type': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g., PLA Basic (optional)'}), + 'brand': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g., Bambu Lab'}), 'color': forms.Select(attrs={'class': 'form-select', 'id': 'id_color'}), 'color_hex': forms.TextInput(attrs={ 'class': 'form-control', @@ -85,6 +85,7 @@ class FilamentForm(forms.ModelForm): 'initial_weight_grams': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '1000'}), 'remaining_percent': forms.NumberInput(attrs={'class': 'form-control', 'min': '0', 'max': '100'}), 'remaining_weight_grams': forms.NumberInput(attrs={'class': 'form-control', 'readonly': 'readonly'}), + 'is_transparent': forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'id_is_transparent'}), 'is_loaded_in_ams': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'current_tray_id': forms.NumberInput(attrs={'class': 'form-control', 'min': '0', 'max': '3'}), 'purchase_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), diff --git a/bambu_run/management/commands/bambu_collector.py b/bambu_run/management/commands/bambu_collector.py index a94742e..1f097e8 100644 --- a/bambu_run/management/commands/bambu_collector.py +++ b/bambu_run/management/commands/bambu_collector.py @@ -316,7 +316,7 @@ class Command(BaseCommand): def _auto_create_filament(self, tray_data): from bambu_run.models import Filament, FilamentType - from bambu_run.utils import strip_color_padding, match_filament_color + from bambu_run.utils import strip_color_padding, match_filament_color, is_mqtt_color_transparent tray_uuid = tray_data.get('tray_uuid') tag_uid = tray_data.get('tag_uid') @@ -329,6 +329,7 @@ class Command(BaseCommand): default_brand = app_settings.AUTO_CREATE_BRAND + transparent = is_mqtt_color_transparent(mqtt_color) color_code = strip_color_padding(mqtt_color) color_hex = f"#{color_code}" if color_code else None @@ -341,6 +342,7 @@ class Command(BaseCommand): if filament_color: color_name = filament_color.color_name + transparent = transparent or filament_color.is_transparent if self.verbose: logger.info(f"Matched color from database: {color_name} (#{color_code})") else: @@ -368,6 +370,7 @@ class Command(BaseCommand): brand=default_brand, color=color_name, color_hex=color_hex, + is_transparent=transparent, diameter=diameter, initial_weight_grams=initial_weight, remaining_percent=remain_percent, diff --git a/bambu_run/management/commands/bambu_import_colors.py b/bambu_run/management/commands/bambu_import_colors.py index 832c6f1..f6bfe0e 100644 --- a/bambu_run/management/commands/bambu_import_colors.py +++ b/bambu_run/management/commands/bambu_import_colors.py @@ -371,6 +371,11 @@ class Command(BaseCommand): return "created" return "no_type" + # ── Transparent detection ──────────────────────────────────────────── + # "Translucent" (no colour qualifier) + #000000 = clear/transparent filament. + # Bambu Lab AMS reports these as 00000000 (alpha=00). + is_transparent = color_name.strip().lower() == "translucent" and hex_code == "000000" + # ── Duplicate check ────────────────────────────────────────────────── # All five fields must match to be considered a duplicate: # color_code (exact), color_name (case-insensitive), brand, @@ -388,9 +393,10 @@ class Command(BaseCommand): return "duplicate" if dry_run: + transparent_note = " [transparent]" if is_transparent else "" self.stdout.write( f" [dry-run] Would create: {color_name!r} #{hex_code} " - f"({filament_type} / {filament_sub_type})" + f"({filament_type} / {filament_sub_type}){transparent_note}" ) return "created" @@ -404,6 +410,7 @@ class Command(BaseCommand): filament_type=filament_type, filament_sub_type=filament_sub_type, brand=BRAND, + is_transparent=is_transparent, ) self.stdout.write( f" + {color_name!r} #{hex_code} ({filament_type} / {filament_sub_type})" diff --git a/bambu_run/models.py b/bambu_run/models.py index f471fef..38f6b9e 100644 --- a/bambu_run/models.py +++ b/bambu_run/models.py @@ -259,6 +259,10 @@ class FilamentColor(models.Model): default='Bambu Lab', help_text="Manufacturer name" ) + is_transparent = models.BooleanField( + default=False, + help_text="True for clear/transparent filaments — display as checkerboard, not solid color" + ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -329,6 +333,10 @@ class Filament(models.Model): max_length=7, null=True, blank=True, help_text="Color hex code for display (#RRGGBB)" ) + is_transparent = models.BooleanField( + default=False, + help_text="True for clear/transparent filaments — display as checkerboard, not solid color" + ) # Physical properties diameter = models.DecimalField( diff --git a/bambu_run/static/bambu_run/js/printer_charts.js b/bambu_run/static/bambu_run/js/printer_charts.js index 7acb95d..857dfb1 100644 --- a/bambu_run/static/bambu_run/js/printer_charts.js +++ b/bambu_run/static/bambu_run/js/printer_charts.js @@ -646,8 +646,20 @@ function hexToRgba(hex, alpha) { function applyFilamentColors() { // Apply colors to filament cards document.querySelectorAll('.filament-card').forEach(card => { + const isTransparent = card.getAttribute('data-filament-transparent') === 'true'; const colorHex = card.getAttribute('data-filament-color'); - if (colorHex) { + + if (isTransparent) { + // Checkerboard left border and subtle background for clear filaments + card.style.borderLeft = '4px solid #aaa'; + card.style.background = 'repeating-conic-gradient(rgba(180,180,180,0.15) 0% 25%, transparent 0% 50%) 0 0/10px 10px'; + + const badge = card.querySelector('.filament-badge'); + if (badge) { + badge.style.backgroundColor = '#aaa'; + badge.style.color = '#fff'; + } + } else if (colorHex) { const color = '#' + colorHex; // Set card background with gradient diff --git a/bambu_run/templates/bambu_run/filament_color_list.html b/bambu_run/templates/bambu_run/filament_color_list.html index c777595..a3189ce 100644 --- a/bambu_run/templates/bambu_run/filament_color_list.html +++ b/bambu_run/templates/bambu_run/filament_color_list.html @@ -54,11 +54,19 @@ {% for color in colors %}