Non-script HA entities (switch/light/input_boolean) on the printer card
always sent turn_on when clicked, which is a no-op when the switch is
already on. Now sends toggle for non-script entities so the badge click
actually changes the switch state. Script entities still use turn_on.
Also fix SmartPlugManager._get_plug_for_printer() using
scalar_one_or_none() which crashes with MultipleResultsFound when
multiple plugs are assigned to the same printer (e.g., Tasmota + HA
switch). Now fetches all plugs and returns the main non-script plug.
Add tests for both fixes: _get_plug_for_printer multi-plug handling
(5 tests) and canonicalFilamentType/filamentTypesCompatible/autoMatch
PA-CF equivalence (8 tests).
Bambu Lab firmware treats PA-CF, PA12-CF, and PAHT-CF as interchangeable,
but the print scheduler and filament override UI used exact string matching.
A 3MF requiring PA-CF wouldn't match PA12-CF in the AMS, leaving the
override dropdown disabled and preventing scheduler assignment.
Add a filament type equivalence system (both backend and frontend) so
these PA variants are treated as compatible in scheduler assignment,
AMS slot matching, force color match validation, and the override dropdown.
Also fix the "Force color match" checkbox click target being too wide
(entire row instead of just the checkbox/label) by changing flex to
inline-flex on the label element.
The embedded camera viewer only handled mouse events (mousedown,
mousemove, mouseup) for window dragging and resizing. On iOS/iPadOS,
touch input doesn't trigger mouse events, so the camera window
couldn't be repositioned — touch just scrolled the page underneath.
Add touch event handlers (touchstart, touchmove, touchend, touchcancel)
alongside mouse handlers for both the header drag handle and the
bottom-right resize handle. Uses preventDefault on touchmove to
prevent page scrolling during drag.
When inventory spool assignments had stale weight_used values, the fill
level fallback chain (Spoolman → Inventory → AMS remain) used nullish
coalescing (??), which doesn't fall through on 0. A stale inventory
fill of 0% permanently shadowed the correct real-time AMS remain value.
Viewer users were unaffected because their group lacked the
inventory:view_assignments permission, so the query never fired.
Now when inventory says 0% but AMS hardware reports positive remain,
the inventory value is bypassed in favor of the live AMS data.
Notify users when the first layer finishes printing so they can check
adhesion remotely. Triggers once per print when layer 2 begins
(layer_num >= 2, capped at <= 5 to handle reconnects). Includes a
camera snapshot attachment. Adds the on_first_layer_complete toggle
to all notification providers, with backend/frontend/i18n support
across all 7 locales.
Start, monitor, and stop drying sessions for AMS 2 Pro (n3f) and
AMS-HT (n3s) directly from the Printers page. Flame icon in AMS card
header opens a popover with filament-based temperature/duration presets
from BambuStudio. Live countdown status bar shows time remaining.
Backend: cache module_type from MQTT get_version, expose dry_time and
module_type in both WebSocket and REST paths, add supports_drying()
with firmware gating, add server-side guard on start_drying endpoint.
Frontend: drying button, popover with filament select + temp/duration
sliders, status bar, start/stop mutations. i18n for all 7 locales.
Supported: X1/X1C (fw 01.09+), P1P/P1S (fw 01.08+), H2D (fw 01.02.30+),
H2D Pro, X1E. Not supported: P2S, A1, A1 Mini, H2S, H2C.
The compatible_printers filter on local presets parsed the stored JSON
array (e.g. '["BBL X1C 0.4 nozzle"]') as a semicolon-delimited string,
so matching always failed and every local preset was silently skipped.
Removed the filter entirely — user-imported profiles should be usable
on any printer.
home_flag bit 18 is set on all printers regardless of hardware,
causing the ethernet badge to appear on WiFi-only models (A1, P1P,
etc.). The previous fix removed the feature entirely, so ethernet
printers lost their badge too.
Now only trusts bit 18 on models with an ethernet port (X1C, X1E,
P1S, P2S, H2D, H2D Pro, H2C, H2S). WiFi-only models always show
the WiFi signal badge.
Sends persistent notifications to the HA dashboard using the existing
HA connection from Settings. Zero config — just select "Home Assistant"
as provider type. Users can forward notifications to mobile via HA
automations.
The "Reprint" and "Schedule" buttons at the bottom of archive cards
overlapped when the browser was narrower than the card grid expected
(e.g. half-screen on a 2K monitor). The text labels used a viewport-
based sm: breakpoint that didn't account for actual card width.
Added overflow-hidden to the flex buttons and truncate to the text
spans so labels clip with ellipsis instead of bleeding into neighbors.
- Remove Bambu Cloud authentication gate from GitHub backup settings card.
K-profiles and app settings backup work without cloud login; the Cloud
Profiles checkbox is disabled with a hint when not authenticated.
- Fix backup log timestamps showing UTC instead of local time by using
the shared parseUTCDate utility for correct timezone conversion.
All filament mapping dropdowns (single-printer, multi-printer, and
"Print to Any" model-based) showed only the base material type (e.g.
"PLA") without distinguishing subtypes like "PLA Basic" vs "PLA Matte",
making entries with different subtypes but same color look identical.
Backend: Add tray_sub_brands to available-filaments response and include
it in the dedup key so different subtypes of the same color appear as
separate entries.
Frontend: Show tray_sub_brands in FilamentMapping, FilamentOverride, and
PrinterSelector dropdowns, falling back to base type when unset. Add
traySubBrands field to LoadedFilament interface.
home_flag bit 18 was incorrectly interpreted as "wired/ethernet
connection", causing the ethernet badge to always show — even on
printers without an ethernet port (e.g. A1, P1S). This hid the
WiFi signal indicator entirely.
Removed the wired_network field and ethernet badge UI. The WiFi
signal badge now shows correctly whenever the printer reports
signal strength.
home_flag bit 18 was incorrectly interpreted as "wired/ethernet
connection", causing the ethernet badge to always show — even on
printers without an ethernet port (e.g. A1, P1S). This hid the
WiFi signal indicator entirely.
Removed the wired_network field and ethernet badge UI. The WiFi
signal badge now shows correctly whenever the printer reports
signal strength.
* Added "Force Color Match" feature to filament override
* Update settings.py
* Update settings.py
* Label updates for warnings and checkbox case
* Initial plan
* Add noMatchingMaterial i18n translations to all 7 locale files
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
* Use {{material}} interpolation in noMatchingMaterial; populate from filament_overrides with getColorName
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
* Updates for PR#625 comments
* Added "Force Color Match" feature to filament override
* Update settings.py
* Update settings.py
* Label updates for warnings and checkbox case
* Initial plan
* Add noMatchingMaterial i18n translations to all 7 locale files
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
* Use {{material}} interpolation in noMatchingMaterial; populate from filament_overrides with getColorName
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
* Updates to PrintersPage and QueuePage
* Update QueuePage.tsx
* Rebase to 0.2.2b3
* Fix compile errors with FilamentOverride
* Updates for PR#625 comments
https://github.com/maziggy/bambuddy/pull/625#pullrequestreview-3908738261
* Fix force color match default, loadedFilamentTypes bug, remove dead translations
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
Co-authored-by: MartinNYHC <mz@v8w.de>
All filament mapping dropdowns (single-printer, multi-printer, and
"Print to Any" model-based) showed only the base material type (e.g.
"PLA") without distinguishing subtypes like "PLA Basic" vs "PLA Matte",
making entries with different subtypes but same color look identical.
Backend: Add tray_sub_brands to available-filaments response and include
it in the dedup key so different subtypes of the same color appear as
separate entries.
Frontend: Show tray_sub_brands in FilamentMapping, FilamentOverride, and
PrinterSelector dropdowns, falling back to base type when unset. Add
traySubBrands field to LoadedFilament interface.
Multi-plate 3MF files can now be queued in one action via a "Queue All
Plates" toggle in the plate selector (add-to-queue mode only). Each
plate becomes a separate queue entry, individually editable.
Fix: "Clear Plate & Start Next" no longer appears when all pending
queue items are staged (manual_start). The prompt only shows when
there are auto-dispatchable items the scheduler will actually start.
Virtual printers in Queue mode now have an "Auto-dispatch" setting.
When enabled (default), prints start automatically — preserving current
behavior. When disabled, prints are added with manual_start so they
wait for manual dispatch from the queue UI.
Checkbox selection + "Delete Selected" button in Settings > Filament
for both Spool Catalog and Color Catalog. Adds POST bulk-delete
endpoints and translations for all 7 locales.
P2S uses hardened steel rods, not carbon fiber. Move P2S from
carbon rod classification to new steel_rod category with its own
"Lubricate Steel Rods" / "Clean Steel Rods" maintenance tasks.
visibility into AMS spool assignments on printer cards without exposing
the full Inventory page (#635). The list_assignments endpoint now
requires this new permission instead of inventory:read. All default
groups (Administrators, Operators, Viewers) include it for backward
compatibility.
Closes#634
The print dispatch progress toast stayed visible forever after the
second print in a session. lastDispatchSummaryRef was never reset
between batches — every single-printer dispatch produced the same
summary key ("first-complete:1:0"), so subsequent completions matched
the stale ref and skipped creating the done toast.
Reset the dedup guard when the dispatch toast is dismissed and when
a new batch starts.
The print dispatch notification disappeared instantly for small files or
closed immediately when the progress bar reached 100%, giving no
confirmation that the job was submitted. The dispatch toast now stays
visible for 3 seconds showing the completion message before auto-
dismissing. For very fast uploads where no progress toast was shown,
a fresh confirmation toast is created instead.
When printing from the file manager, the print modal showed all printers
including busy ones. Selecting a busy printer resulted in a failed send.
The printer selector now fetches live status for each printer and shows
state badges (Idle, Printing, Paused, etc.). In reprint mode, non-available
printers (anything other than IDLE, FINISH, FAILED) are grayed out and
not selectable. "Select all" skips them. Queue/edit modes still allow
selecting busy printers since the job will wait.
Resize PWA icons to match their declared dimensions (192x192, 512x512,
180x180), split discouraged "any maskable" icon purpose, and add mobile
and desktop screenshots to manifest.json for Chrome's richer install UI.
Replace all hardcoded English strings with t() translation calls across
9 components: SettingsPage, SmartPlugCard, AddSmartPlugModal,
SwitchbarPopover, NotificationProviderCard, AddNotificationModal,
NotificationTemplateEditor, NotificationLogViewer, GitHubBackupSettings,
and RestoreModal. Add ~600 new translation keys to all 7 locales
(en, de, ja, fr, it, pt-BR, zh-CN).
All filament mapping dropdowns (single-printer, multi-printer, and
"Print to Any" model-based) showed only the base material type (e.g.
"PLA") without distinguishing subtypes like "PLA Basic" vs "PLA Matte",
making entries with different subtypes but same color look identical.
Backend: Add tray_sub_brands to available-filaments response and include
it in the dedup key so different subtypes of the same color appear as
separate entries.
Frontend: Show tray_sub_brands in FilamentMapping, FilamentOverride, and
PrinterSelector dropdowns, falling back to base type when unset. Add
traySubBrands field to LoadedFilament interface.
The per-printer InlineMappingEditor showed filaments from both nozzles
on H2D printers. The single-printer FilamentMapping dropdown was fixed
in 29e9593 but the multi-printer code path was missed. Added nozzle_id
filtering to both auto-match logic and dropdown options via shared
autoMatchFilament() and filterFilamentsByNozzle() functions in
amsHelpers.ts, with 10 regression tests.
Move the toast container from bottom-4 to bottom-20 so toast
notifications and upload progress stack above the bug report bubble
instead of rendering on top of each other.
- Add 12 backend integration tests for AMS labels API (GET/PUT/DELETE,
serial resolution, synthetic key fallback, whitespace handling, validation)
- Add 10 frontend tests for FilamentSlotCircle component (rendering,
border styles, background colors, text contrast inversion)
- Fix ruff W293 trailing whitespace in inventory.py from contributor fix
- Add ams_label model import to test conftest.py
- Update CHANGELOG, README, website features page, and wiki AMS docs
Floating bug report button submits issues via bambuddy.cool relay (no GitHub
token needed locally). Collects 30s debug logs with printer push_all, sanitizes
all sensitive data, uploads logs as files to GitHub. Screenshot upload/paste/drag
with JPEG compression. Translated into all 7 languages. Includes 21 tests.
Parse home_flag bit 18 (0x00040000) from MQTT to detect ethernet
connections. When set, the printer card shows a green "Ethernet"
badge with a cable icon instead of WiFi signal strength in dBm.
The printer info modal also displays "Ethernet" instead of WiFi
signal details.
- Extract shared detectSystemDateFormat() helper to eliminate
duplicated system locale detection in date.ts
- Derive SUPPORTED_CURRENCIES from CURRENCY_SYMBOLS map instead
of maintaining a duplicate hardcoded list
- Consolidate redundant time-parsing regex paths into one
- Use applyTimeFormat() consistently in formatETA()
- Add exhaustive switch default for type safety
The isSlicedFile() check only matched .gcode or .gcode.3mf extensions,
so archives from .3mf prints (the standard Bambu slicer output) showed
a "SOURCE" badge instead of "GCODE". Since .3mf can be either sliced or
a raw CAD export, now checks the archive's total_layers and
print_time_seconds metadata to distinguish them. Also passes the
original filename when creating archives from file manager prints.