mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-17 11:25:48 +02:00
v0.2.2b3
461
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b3a91d7314 |
Revert "v0.2.2b1 (#602)" (#603)
This reverts commit
|
||
|
|
3dd1ffb485 |
v0.2.2b1 (#602)
* feat(queue): show spool grams left in filament slot mapping
* Bumped version
* Add SpoolBuddy AMS slot config, external slots, and dashboard redesign
- AMS page: external spool slots (Ext/Ext-L/Ext-R), click-to-configure
modal on all slots, temperature/humidity threshold-colored indicators,
nozzle L/R badges for dual-nozzle printers, compact AMS-HT layout
- Dashboard: two-column layout with device status + printers list (left)
and current spool card (right), state-colored scale/NFC icons, dashed
border card styling
- Daemon: suppress redundant scale reports (±2g threshold + stability
state change detection) to prevent weight display bouncing
- TopBar: auto-select online printers only, SpoolBuddy logo
* Fix SpoolBuddy daemon crash when read_tag module is missing
NFCReader.__init__ imported read_tag and instantiated PN5180() outside
the try/except block, so a missing module crashed the entire daemon.
Moved the import inside the existing try/except so the daemon gracefully
skips NFC polling — matching the scale reader's existing behavior.
* Fix SpoolBuddy daemon failing to import hardware drivers
The daemon imports read_tag and scale_diag as bare modules, but they
live in spoolbuddy/scripts/ which isn't on sys.path when systemd runs
the daemon. Added scripts/ to sys.path at startup, resolved relative
to the module file. Also moved the read_tag import inside NFCReader's
try/except (was crashing the daemon instead of skipping gracefully)
and demoted hardware-not-available messages from ERROR to INFO.
* Increase scale moving average window to reduce weight bouncing
5 samples at 100ms (500ms window) wasn't enough to smooth NAU7802 ADC
noise — the averaged value still varied by >2g between 1s report
intervals, and the stability state kept flipping, triggering a report
every cycle. Increased to 20 samples (2s window) so noise is smoothed
before reaching the reporting layer.
* Remove stability flipping as scale report trigger
When ADC noise kept the spread hovering around the 2g stability
threshold, the stable flag toggled every cycle, forcing a report with
a slightly different weight each time. Now only actual weight changes
of >=2g trigger reports. The stable flag is still included in each
report for consumers that need it.
* Fix formatting of option elements in FilamentMapping
* Minor Spoolbuddy frontend improvements
* Updated Spoolbuddy install script to strip down Raspbian
* Updated Spoolbuddy install script
* Add API key auth support to /auth/me for SpoolBuddy kiosk
When Bambuddy auth is enabled, the SpoolBuddy kiosk gets redirected to
the login page because ProtectedRoute requires a user from GET /auth/me,
which only handled JWT tokens. The kiosk daemon already has an API key
but couldn't use it to satisfy the frontend auth check.
- Backend: /auth/me now accepts API keys (Bearer bb_xxx or X-API-Key)
and returns a synthetic admin UserResponse with all permissions
- Frontend: AuthContext reads ?token= from URL on first load, stores in
localStorage, and strips from URL (prevents history/referrer leakage)
- Install script: kiosk URL now includes ?token=${API_KEY}
- Tests: 3 new integration tests (Bearer API key, X-API-Key header,
invalid key rejection)
* SpoolBuddy touch-friendly UI overhaul for 1024x600 kiosk display
Enlarge all interactive elements across 9 SpoolBuddy components to meet
44px minimum tap targets on the RPi touchscreen. Increase nav icons
(20→24px), labels (10→12px), bar heights, section headers, printer
buttons, spool visualizations, fill bars, and status indicators.
Compact the dashboard stats bar and remove the printers card. Add
fullScreen prop to ConfigureAmsSlotModal with two-column layout
(filament list left, K-profile + color right) to eliminate scrolling.
* Updated CI
* Fix naive-vs-aware datetime crash from 0.2.1 timezone migration
The timezone fix (
|
||
|
|
9ee4bd51e4 | Sync | ||
|
|
f2f43b98a3 |
Fix sidebar navigation not respecting user permissions
Sidebar nav items (Archives, Queue, Stats, Profiles, Maintenance, Projects, Inventory, Files) were visible to all users regardless of role permissions — only Settings was gated. Now each item is hidden when the user lacks the corresponding read permission. Printers remains always visible as the home page. Also adds missing inventory:read|create|update|delete to the frontend Permission type (existed in backend but was absent from the frontend type definition). |
||
|
|
90b9523998 |
Updated commit message (now includes the test fix):
Fix camera button permissions & ffmpeg process leak (#550) Camera button on printer card was clickable without camera:view permission. ffmpeg processes (~240MB each) accumulated after closing camera streams because: (1) stop endpoint called terminate() without wait()/kill(), (2) HTTP disconnect detection only ran between frames so was blocked when the generator was stuck on stdout read, and (3) no mechanism caught processes orphaned by generator abandonment or app restarts. - Add camera:view permission check + tooltip to camera button - Fix stop endpoint: terminate() → wait(2s) → kill() → wait() - Add background disconnect monitor (polls every 2s, kills ffmpeg directly on disconnect) - Add periodic /proc scan (every 60s) that SIGKILLs any ffmpeg with rtsps://bblp: not in an active stream - Add noCamera i18n key to all 6 locales - Fix camera API test mocks for async wait() and pid attribute |
||
|
|
240eeb4f5d |
Add H2C dual nozzle variant O1C2 model support (#489)
The H2C dual nozzle variant reports model code O1C2 via MQTT, but only O1C was recognized. This caused the camera to use the wrong protocol (chamber image on port 6000 instead of RTSP on port 322), producing a reconnect loop. Added O1C2 to all model ID maps across 8 files. |
||
|
|
d3bae07edf |
Fix queue badge showing on printers without matching filament (#486)
The purple queue counter badge in the printer card header used the raw unfiltered queue item count, so it appeared on ALL printers of the same model when a job was scheduled for "any [model]" — even printers without the matching filament color. The PrinterQueueWidget below it (which shows "Clear Plate & Start") already filtered by filament type + color. Apply the same filament compatibility filter (type check + color override check) to the badge count so it only shows on printers that can actually run the queued jobs. |
||
|
|
94d0f55e1c |
Fix AMS history chart showing wrong time range (#535)
The chart X axis used dataMin/dataMax domain, compressing the view to only the data present. A 6h view with 1.5h of data looked like 1.5h. Pin the X axis to the full selected time range, pad data edges so the line extends to both ends, and connect through nulls for a continuous line. |
||
|
|
ad6108c8a7 |
Fix "Clear Plate" button shown on printers without matching filament color (#486)
When a print was queued to "any printer" with a filament color override (e.g., white PETG), the "Clear Plate & Start Next" button appeared on printers that had the right type but wrong color. The backend scheduler already rejected color mismatches, but the frontend only checked filament types. Now passes loaded type+color pairs from AMS status to the widget and filters against filament_overrides, mirroring the backend's _count_override_color_matches() logic. |
||
|
|
4f5a9f4b95 |
Fix spool form profile dropdown truncating long preset names (#534)
Long filament profile names were cut off because inline filament ID codes consumed horizontal space in the dropdown. Remove the codes from dropdown items (selected code still shown below the input) and widen the modal from max-w-lg to max-w-xl. |
||
|
|
f4f09ccc2d |
Hide unnecessary target model selector on "Any" tab (#528)
When scheduling a print to "Any {model}", a redundant "Target Model"
dropdown appeared even though the G-code is already sliced for a
specific printer model. Changing it would lead to print failures.
Hide the dropdown when slicedForModel is known — the tab label already
communicates the target. The dropdown still appears as a fallback for
legacy files without model metadata.
|
||
|
|
20c291d678 |
Fix "Clear Plate & Next" shown on printers without correct filament (#527)
The "Clear Plate & Start Next" button appeared on ALL printers of a model when a job was queued via "Queue to Any X", even printers without the required filament loaded. Clicking it started a print that fails. PrinterQueueWidget now filters queue items by filament compatibility — each item's required_filament_types must all be present in the printer's loaded filaments (AMS + external spools). If no compatible items exist, the widget is hidden entirely. Matching is type-only (not color) and case-insensitive, consistent with the backend scheduler. When filament data is unavailable, no filtering is applied (graceful degradation). |
||
|
|
1973a5bead |
Fix virtual printer queue mode not assigning printer (#518), settings text fields resetting mid-typing
Virtual printer "print_queue" mode created queue items with no printer assignment. Now sets target_model from the VP's SSDP model code (e.g. P1S, X1C) for "Any Printer" scheduling, or uses target_printer_id if configured. Settings page auto-save onSuccess overwrote localSettings with the server response, discarding characters typed during the save request. Removed the stale state overwrite so in-progress input is preserved. |
||
|
|
d92803b557 |
Fix "Open in Slicer" failing for filenames with special characters
Filenames containing / \ ? or # (e.g. "Abzweigdose/Verteilerdose 70mm") broke the slicer protocol handler. BambuStudio/OrcaSlicer url_decode() the entire protocol URL before downloading, which decoded %2F back to /, creating extra path segments that returned 404. Sanitize these characters to _ in slicer download URLs — the filename is cosmetic (backend resolves files by archive ID). |
||
|
|
ed36eafbec |
Fix timestamps off by timezone offset in non-UTC containers (#504)
All backend timestamps used datetime.now() (server local time) or the deprecated datetime.utcnow(). The frontend's parseUTCDate() assumes timestamps without timezone indicators are UTC and appends 'Z', so stored timestamps were off by the timezone offset when the container's timezone wasn't UTC. Backend: replaced datetime.now() and datetime.utcnow() with datetime.now(timezone.utc) across 16 files (~80 call sites) for all database fields and DB comparisons. Cosmetic timestamps (filenames, user-facing local time formatting) intentionally left as local time. Frontend: replaced 13 new Date(backendTimestamp) calls with parseUTCDate() across 8 files to correctly interpret UTC timestamps. |
||
|
|
974988c4f1 |
Fix created admin users not seeing settings button in sidebar (#503)
The sidebar hid Settings based on hardcoded role === 'user' instead of the settings:read permission, and login set user state directly from the response instead of re-fetching full auth status with permissions. |
||
|
|
04ac6bd36e |
Fix power-off option not gated by printers:control permission (#500)
The "Power off printer when done" checkbox in the print modal and the auto power off tri-state toggle in the bulk edit modal were accessible to all users regardless of permissions. Users without printers:control can now no longer enable auto power off — controls are disabled and visually dimmed. |
||
|
|
24c4363620 |
Fix filament fill level display bugs on printer card (#496)
Three related fixes in PrintersPage.tsx:
1. External spool (vt_tray) fill level was missing the AMS remain
fallback — only checked Spoolman/inventory, ignoring valid AMS data.
Now uses the same fallback chain as regular and AMS-HT slots.
2. When fill was unknown (null), slot visual showed a full-width gray
bar ("full") while the hover card showed "—" ("empty"). Removed the
misleading gray fallback bar from all three slot types so both views
consistently show "unknown".
3. Fill source priority always preferred AMS remain over Spoolman and
inventory, even when those sources were more accurate (e.g. spools
with usage tracking or migrated from Spoolman). Reversed priority to
Spoolman → Inventory → AMS remain. Fixed fillSource label to reflect
the actual data source (was always 'ams' even when using fallback).
|
||
|
|
5cb1ca3ae2 | Spoolbuddy frontend work | ||
|
|
8e6a959eef | Redact IP addresses from support bundle debug logs | ||
|
|
5164152088 |
Fix external spool mapping inverted on H2C (#492)
On H2C/H2D dual-nozzle printers, tray_now=254 is sent generically for both external spools. The direct ID comparison always matched Ext-L (id=254), never Ext-R (id=255). Now uses active_extruder to disambiguate: extruder 1 (left) → Ext-L, extruder 0 (right) → Ext-R. |
||
|
|
6da12a8ad2 |
Fix wrong documentation link for "Lubricate Carbon Rods" on P2S (#490)
The maintenance page linked P2S "Lubricate Carbon Rods" to the belt-tension wiki page instead of the XYZ axis lubrication page. |
||
|
|
3c72f7cb22 |
Show inventory sidebar item for both Spoolman and internal inventory
Previously the Inventory sidebar item was hidden when Spoolman was enabled. Now it always shows — when Spoolman is active, /inventory embeds the Spoolman web UI in the content area via iframe; when disabled, it renders the internal inventory page as before. |
||
|
|
77677cb07f |
Add clear-plate dot indicator on sidebar Printers icon
When a printer has pending queue items and is in FINISH/FAILED state awaiting plate clearing, a yellow dot now appears on the Printers sidebar icon. Uses useQueries to check statuses of printers with pending queue items from the existing WebSocket-warmed React Query cache — no new backend endpoints or additional polling needed. |
||
|
|
d5c9f2b9ea | Moved Spoolbuddy frontend to Bambuddy | ||
|
|
9381edf0cb | Removed new Spoolbuddy frontend | ||
|
|
38af5df050 |
Add filament override for model-based queue assignment (#486)
When scheduling a print to "any printer" (model-based assignment), users can now override the 3MF's original filament choices per slot. The override dropdown shows compatible filaments loaded across all printers of the selected model, filtered by type and nozzle (H2D). The scheduler matches against overridden type/color instead of the original 3MF values, preferring printers with exact color matches. Backend: - New GET /printers/available-filaments endpoint (aggregates loaded filaments across printers of a model, includes extruder_id for dual-nozzle nozzle-aware filtering) - New filament_overrides JSON column on print_queue table - Scheduler applies overrides before AMS mapping, clears tray_info_idx on overridden slots so color matching takes priority - Printer selection prefers printers with most override color matches Frontend: - New FilamentOverride component with per-slot override dropdowns - Type-filtered options (PLA slots only show PLA) - Nozzle-aware filtering (H2D: only shows filaments on correct extruder) - Integrated into PrintModal for model-based queue mode Tests: - 11 backend unit tests (color match counting, override application) - 12 frontend tests (rendering, type/nozzle filtering, interactions) i18n: All 6 locales (en, de, fr, it, ja, pt-BR) |
||
|
|
aeca15b585 |
Add SpoolBuddy integration as optional filament management add-on
SpoolBuddy turns a Raspberry Pi 4B with a PN5180 NFC reader and NAU7802 scale into a filament management station that integrates with Bambuddy via REST API and WebSocket. Backend: SpoolBuddyDevice model, 10 REST endpoints (/spoolbuddy/*), 6 WebSocket broadcast types, background offline-detection watchdog. RPi daemon: asyncio service with concurrent NFC polling (300ms, MIFARE Classic + Bambu HKDF key derivation), scale reading (10 SPS, 5-sample moving average, stability detection), and 10s heartbeat with exponential backoff reconnect. Frontend: kiosk-optimized 1024x600 UI at /spoolbuddy with Dashboard (live weight + NFC spool detection), AMS Overview, Inventory, Printers, and Settings pages. useSpoolBuddyState reducer hook driven by WebSocket CustomEvents. i18n: all 6 locales (en, de, fr, it, ja, pt-BR). |
||
|
|
e450c3b728 |
Add visual spool grouping and optional brand/subtype in quick-add (#480)
Group toggle in inventory toolbar collapses identical unused/unassigned spools into expandable rows/cards with count badges. Grouping key uses material, subtype, brand, color, and label weight. Brand and subtype fields now appear in quick-add mode as optional (no asterisk, no validation). Quantity field restricted to quick-add mode only. |
||
|
|
0e87c377e6 |
Add developer LAN mode detection and warning banner
Parse the MQTT "fun" field bit 0x20000000 to detect whether connected printers have Developer LAN Mode enabled. Show a persistent orange warning banner when any printer lacks it, since newer firmware silently rejects MQTT write commands without developer mode. - Parse fun field into developer_mode on PrinterState - Add /printers/developer-mode-warnings lightweight polling endpoint - Include developer_mode in printer status API and support bundle - Orange banner with affected printer names and wiki link - Translations for all 6 locales (en, de, fr, it, ja, pt-BR) - 7 backend + 4 frontend tests |
||
|
|
16fa84bc16 |
Add bulk spool addition and stock spools
Add Quick Add mode to the spool form for simplified entry (material + color + weight only), and a quantity field (1-100) for creating multiple identical spools at once. Stock spools (no slicer profile) are computed rather than stored — any spool without slicer_filament shows an amber "Stock" badge. New filter chips (All/Stock/Configured) on the inventory page. Backend bulk endpoint creates N spools in one transaction. Backend: - SpoolBulkCreate schema with quantity validation (1-100) - POST /inventory/spools/bulk endpoint Frontend: - Quick Add toggle in SpoolFormModal (create mode only) - Quantity field in FilamentSection (both modes) - bulkCreateSpools API method and bulkCreateMutation - Stock column (hidden by default) and stock filter chips - Inline error rendering moved into FilamentSection - CellCtx extended with t() for translatable cell content Tests: - 13 backend tests (schema validation + endpoint logic) - 10 frontend tests (validateForm quickAdd + UI behavior) i18n: 6 locales (en, de, fr, it, ja, pt-BR) Docs: CHANGELOG, README, website features, wiki inventory |
||
|
|
7d46b44561 | Fix PCTG filament misidentified as PC (#478) | ||
|
|
839be41133 |
Fix support bundle leaking personal data (#473)
The log sanitizer only used regex patterns, missing arbitrary user-chosen strings (printer names, usernames). Tasmota smart plug credentials were logged verbatim in URLs by httpx. - Make _sanitize_log_content() database-aware: query Printer names/serials, User usernames, and Bambu Cloud email for exact-string replacement (longest-first, skip <3 chars to prevent over-redaction) - Fix serial regex leaking first 3 chars (remove capture group partial redaction), add case-insensitive flag - Move Tasmota credentials from URL-embedded (http://user:pass@host) to httpx auth= parameter so they never appear in logs - Add URL credentials regex as defense-in-depth for user:pass@ in logs - Add 'username' and 'path' to settings sensitive_keys filter (catches smtp_username, slicer_binary_path in support-info.json) |
||
|
|
63efc2281d | Sync | ||
|
|
1404242e0c | Fix cost tracking issues | ||
|
|
40403ae584 |
Fix inventory date format and AMS-HT slot labels (#463)
Two bugs in the inventory page: 1. Dates always displayed as DD/MM/YY regardless of the user's date format setting. The page had a local formatDate() hardcoding en-GB locale. Replaced with the shared formatDateOnly() from utils/date.ts. 2. AMS-HT slot locations showed accented characters (e.g., "Á1") instead of proper labels (e.g., "HT-A"). The code used String.fromCharCode(65 + ams_id), which produces garbled chars for AMS-HT IDs (128+). Now uses the shared formatSlotLabel() from utils/amsHelpers.ts. |
||
|
|
e4e6e9f8c4 |
Decouples file uploads and print start commands so that they run in the background asynchronously. When a print is started, the print modal no longer waits for the print to upload and start. Instead, a new toast-based UI appears with the status of prints being dispatched. Prints being dispatched can be cancelled during upload. If cancelled, the partially-uploaded gcode is deleted from the printer automatically before the FTP connection is closed.
This allows users sending particularly large prints to slow printers such as the P1-series to start a print and then move onto another task in Bambuddy immediately (such as starting more prints on more printers). It also gives the user visibility into what's happening instead of a loading indicator appearing for an indefinite period of time. The new toast-based UI uses websockets to update in real time. It will also appear for other users / instances of Bambuddy, not just the user who started the prints, allowing more transparency and handling cases where the user closes the page and then comes back wanting to know the status of the dispatching. fix: review fixes for background dispatch PR #408 - Restore missing imports in main.py (inventory, print_log, virtual_printers, mqtt_smart_plug_service) - Guard voidresp() for A1 printers to prevent hang after upload - Don't fail upload on voidresp() error since data transfer already completed - Add ams_mapping to register_expected_print calls for Spoolman usage tracking - Fix cancel_job TOCTOU race by using single lock acquisition - Fix batch counter reset TOCTOU by re-checking condition inside second lock - Add backgroundDispatch translations to fr.ts and pt-BR.ts - Remove dead upload_progress_callback definitions - Skip redundant "Print queued" toast in reprint mode (dispatch toast handles it) - 5 backend tests: cancel_job single-lock TOCTOU, batch reset re-check, job lifecycle - 2 FTP regression tests: voidresp error handling (upload-loop fix), A1 model voidresp skip - 1 frontend test: reprint toast suppression - CHANGELOG: background dispatch feature + test coverage entries - README: add background dispatch to Scheduling & Automation - Website: add feature item to Automation section - Wiki: add Background Print Dispatch section to print-queue.md |
||
|
|
31f4193ce0 | Update frontend build | ||
|
|
060b253669 | Update frontend build | ||
|
|
d71e56c3e6 | Minor layout improvements | ||
|
|
2f51bec40d |
feat: add "Include beta updates" setting to filter prerelease notifications
Users on the Docker `latest` tag were seeing update notifications for beta releases (e.g. v0.2.1b) they couldn't install. The update checker now fetches /releases instead of /releases/latest and filters by parse_version() prerelease detection. A new toggle in Settings (default: off) lets users opt in to beta notifications. |
||
|
|
5e6c04f303 |
fix: queue stuck on "Busy" for "Any Model" jobs (#435)
When a print was queued with "Any [Model]", the queue widget only queried items with printer_id=X after dispatch, missing the next pending model-based item (printer_id IS NULL, target_model="P1S"). The "Clear Plate & Start Next" button never appeared, leaving the scheduler stuck reporting "Busy". Add optional target_model query parameter to GET /queue/. When combined with printer_id, uses OR logic to also return unassigned items whose target_model matches. The frontend now passes the printer's model through PrinterQueueWidget to this query. |
||
|
|
7b39026429 |
fix: resolve PFUS preset IDs causing slicer slot resets + fill level for new spools
BambuStudio actively resets AMS slots configured with unrecognized PFUS* (user-local) preset IDs. Replace PFUS* with generic Bambu filament IDs (e.g. GFL99 for PLA) in both the slot configure and inventory assignment endpoints. When the slot already has a recognized cloud-synced preset for the same material, reuse it to preserve K-profile calibration. Also fix fill level bar not showing for brand new spools (weight_used=0) by changing the condition from weight_used > 0 to weight_used != null. |
||
|
|
d24e7cdf84 |
feat: multiple virtual printers with dedicated bind IPs + dual bind/detect ports (#445)
Multiple Virtual Printers: - Each VP gets a dedicated bind IP with independent FTP, MQTT, SSDP, and Bind services - New VirtualPrinter DB model, CRUD API (/api/virtual-printers), React UI - VirtualPrinterList, VirtualPrinterCard, VirtualPrinterAddDialog components - Per-instance TLS certificates (shared CA), 11 printer models, all 4 modes - Auto-incremented serial suffixes, network interface override per VP Dual Bind/Detect Ports (#445): - Listen on both ports 3000 and 3002 for slicer bind/detect handshake - Different BambuStudio/OrcaSlicer versions use different ports - Applies to BindServer (server mode) and SlicerProxyManager (proxy mode) - Updated Dockerfile, docker-compose.yml, firewall rules in wiki Also: - Rewrote VP test suite for new multi-instance architecture (75 tests) - Rewritten "How it works" section with 3-step workflow explanation - Updated all 5 locales (en, de, ja, fr, it) - Updated wiki and website for multi-VP + dual ports - New multi-VP screenshot |
||
|
|
cb3363733e |
fix: remove dead PAUSED printer state checks (#447)
The printer only sends PAUSE via MQTT gcode_state, never PAUSED. Removed all unreachable PAUSED comparisons from frontend (4 files) and backend (2 files). |
||
|
|
df83250ff8 |
feat: add dedicated clear_plate permission + full-page group editor (#446)
Add a new `printers:clear_plate` permission so admins can grant plate-clearing ability without full `printers:control` access. Existing groups with `printers:control` automatically receive the new permission on startup via migration. Replace the cramped permission modal in Settings with a dedicated full-page group editor (`/groups/new`, `/groups/:id/edit`) featuring search filtering, select all/clear all, category-level toggles, and a responsive 2-column permission grid. Remove dead GroupsPage code that was never routed. - Backend: new Permission enum, category, defaults, endpoint guard, migration - Frontend: GroupEditPage, updated routes, removed modal from SettingsPage - Tests: 10 backend + 10 frontend tests for new permission and editor - Docs: updated wiki (auth, printer-control, API), website, changelog - i18n: added group editor keys to all 6 locale files (en/de/ja/fr/pt-BR/it) |
||
|
|
9e317bd775 |
Fix npm audit high-severity minimatch ReDoS (GHSA-3ppc-4f35-3m26)
by adding an npm override for minimatch@^10.2.1 in package.json. |
||
|
|
ec751424b6 |
Fix AMS slot mapping for A1 Mini (#364)
Add color-matching fallback for slot-to-tray mapping on printers that don't provide the MQTT mapping field (snow encoding) or reject request topic subscription. Matches 3MF filament slot colors against AMS tray colors to resolve the correct physical tray. Returns no match when colors are ambiguous (duplicate tray colors) to safely fall through to existing fallbacks. Mapping priority chain: print_cmd → MQTT snow → queue → color match → tray_now → slot_id-1. |
||
|
|
d119219e4d | Merge branch '0.2.1b' into add-H2D-Pro-png | ||
|
|
2bfb9d22c5 | Updated CI |