Commit Graph
1281 Commits
Author SHA1 Message Date
MartinNYHC 8a0fbbd7b4 Merge branch '0.2.1b' into feature/brazilianPortugueseTranslation 2026-02-18 12:13:33 +01:00
maziggy 2fd90e9dce refactor(api): rename /filaments/ to /filament-catalog/ for clarity (#427)
The /filaments/ endpoint manages material type definitions (cost, temps,
density) but shares its name with the UI's "Filament" page which shows
the spool inventory (/inventory/spools/). This caused users to expect
the API to return their spool inventory.

Rename to /filament-catalog/ to make the distinction clear. No frontend
behavior change — these API methods are defined but unused in the UI.
2026-02-18 11:58:17 +01:00
MartinNYHC e60832d9f4 Merge branch '0.2.1b' into feature/brazilianPortugueseTranslation 2026-02-18 11:34:33 +01:00
maziggy 713a3e931a fix(usage-tracker): decode MQTT mapping field for correct spool tracking on multi-AMS printers (#364)
On dual-nozzle printers (H2C, H2D Pro) with multiple AMS units, usage
tracking attributed filament consumption to the wrong spools. The MQTT
mapping field — a snow-encoded array mapping slicer slots to physical
AMS trays — was preserved in state but never parsed.

Add _decode_mqtt_mapping() to convert snow encoding (ams_hw_id * 256 +
slot) to bambuddy global tray IDs. Insert as priority 2 in the mapping
resolution chain, after print_cmd ams_mapping but before queue/tray_now
fallbacks. Works for all printer models and print sources.
2026-02-18 11:24:22 +01:00
maziggy 60b5ff2363 Closes #426 2026-02-18 11:05:16 +01:00
maziggy c19de47ce5 test(mqtt): add tray_now disambiguation regression tests (28 tests)
Replay realistic MQTT message sequences through _process_message() to
cover all tray_now disambiguation paths: single-nozzle passthrough
(X1E/P2S), H2D dual-nozzle snow field, pending target, ams_extruder_map
fallback, active extruder switching, and full multi-color lifecycles.
2026-02-18 10:54:04 +01:00
maziggy 1eaf9c62e3 Updated CHANGELOG 2026-02-18 10:22:55 +01:00
maziggy 4f8cad0cf7 fix(mqtt): correct AMS-HT snow slot computation for H2D disambiguation
AMS-HT trays (IDs 128-135) are single-slot units, but the snow_slot
computation used `snow_tray % 4 if snow_tray < 128 else -1`, yielding
-1 for AMS HT. This caused a misleading "slot mismatch" debug log on
every MQTT update despite producing the correct tray_now value. Now
returns slot 0 for AMS-HT IDs (128-135), matching the firmware's
tray_now=0 for these single-slot units.
2026-02-18 10:22:02 +01:00
maziggy d46f8e8938 fix(mqtt): skip H2D tray_now disambiguation on single-nozzle printers
P2S (and X1C) with multiple AMS units incorrectly entered the H2D
dual-nozzle tray_now disambiguation code path, causing warning log
spam. The check `tray_now <= 3` matched any printer loading from
AMS 0. Now uses a persistent `_is_dual_nozzle` flag detected from
device.extruder.info (>= 2 entries), which only dual-nozzle printers
(H2D, H2D Pro) report. Flag is set early in message processing so
it's available before AMS data is parsed.
2026-02-18 09:51:39 +01:00
maziggy bedcd0a73e 1. ajv is only used by eslint to validate config schemas during linting
2. It's a dev dependency, never reaches production
  3. The ReDoS requires crafted $data schema input — not an attack vector in a linting config
2026-02-18 09:30:29 +01:00
maziggy 29e9593f6c AMS mapping fixes (7 bugs):
- backend/app/services/print_scheduler.py — hard nozzle filter + external spool extruder
- backend/app/api/routes/printers.py — ams_extruder_map race condition
- backend/app/utils/threemf_tools.py — group_id priority + dual-nozzle detection
- frontend/src/hooks/useFilamentMapping.ts — external spool extruder
- frontend/src/pages/PrintersPage.tsx — AMS-HT globalTrayId
- frontend/src/components/PrintModal/FilamentMapping.tsx — dropdown nozzle filter

Usage tracking fix:
- backend/app/services/bambu_mqtt.py — capture last valid progress/layer
- backend/app/services/usage_tracker.py — use captured values on cancel

UI fix:
- frontend/src/components/spool-form/ColorSection.tsx — color tooltip z-index

Tests:
- backend/tests/unit/test_scheduler_ams_mapping.py — 63 tests
- frontend/src/__tests__/hooks/useFilamentMapping.test.ts — 43 tests

Static assets:
- static/ — rebuilt frontend bundles
2026-02-18 09:17:50 +01:00
Wesley Silva 7ce2048e09 Fixing typo on CONTRIBUTING.md 2026-02-17 20:09:47 +00:00
Wesley Reuel Marques Silva f289ca6979 Merge branch '0.2.1b' into feature/brazilianPortugueseTranslation 2026-02-17 19:52:43 +00:00
Wesley Silva 3291e8c6f9 Added translation to Brazilian Portuguese on existing strings. 2026-02-17 19:49:57 +00:00
maziggy 157dca27b7 Bumped version 2026-02-17 12:38:40 +01:00
maziggy ac2aaaac20 Bumped version v0.2.0 2026-02-17 12:36:53 +01:00
MartinNYHC 5987283f6f Merge pull request #411 from maziggy/0.2.0b
v0.2.0
2026-02-17 12:32:20 +01:00
MartinNYHC 2710fee82e Merge branch 'main' into 0.2.0b 2026-02-17 12:27:21 +01:00
maziggy a0abeba394 fix(queue): persist clear plate state across page refresh (#410)
After clicking "Clear Plate & Start Next", refreshing the page showed
the button again because the frontend determined the state purely from
the printer's FINISH/FAILED status. The backend already tracked a
plate_cleared flag in memory but never exposed it to the frontend.

- Add plate_cleared field to PrinterStatus schema and API response
- Pass plateCleared prop to PrinterQueueWidget
- Skip clear plate UI when plate is already acknowledged
- Add 2 tests for plateCleared=true behavior
2026-02-17 12:14:47 +01:00
maziggy 20e06bcf0c feat(virtual-printer): add port 3000 bind/detect server for slicer connectivity
Recent BambuStudio/OrcaSlicer updates require a bind/detect handshake on
port 3000 before connecting via MQTT/FTP. Without this, slicers cannot
discover or connect to the virtual printer in any mode.

- Add BindServer for server modes (immediate/review/print_queue)
- Add TCPProxy for raw TCP forwarding (proxy mode)
- Update Dockerfile (EXPOSE 3000) and docker-compose.yml (bridge port)
- Add 10 new tests for BindServer protocol and integration
2026-02-17 11:57:50 +01:00
maziggy a4fad2d2f5 fix(mqtt): fail-safe request topic subscription for ams_mapping capture (#405)
Some printer MQTT brokers (e.g. P1S) reject subscriptions to the request
topic by killing the TCP connection, causing a disconnect loop. The request
topic subscription for ams_mapping capture is now fail-safe with two
detection paths:

- SUBACK rejection: on_subscribe callback detects failure code 0x80
- Broker kills connection: on_disconnect detects disconnect within 10s of
  unconfirmed subscription attempt

After detection, the request topic is disabled for that printer and
reconnection succeeds with only the report topic. Printers that support
the request topic (e.g. X1E, H2D) get ams_mapping capture; printers that
don't (e.g. P1S) gracefully degrade to tray_now-based tracking.
2026-02-17 09:33:32 +01:00
maziggy bd84f8d87a Housekeeping 2026-02-17 08:57:27 +01:00
maziggy 83ed4b2581 Housekeeping 2026-02-17 08:57:09 +01:00
maziggy bc78f3f456 feat(timelapse): add upload and remove timelapse management (#406)
When the auto-scan attached the wrong timelapse (e.g. from a different
print), there was no way to fix it — the file couldn't be removed and
re-scanning was disabled once a timelapse was attached.
2026-02-17 08:49:32 +01:00
maziggy c82521efc9 fix(timelapse): support AVI format from P1-series printers (#405)
P1S/P1P save timelapses as AVI (MJPEG), but the scanner only looked
for MP4 files — so P1-series timelapses were never found or attached.
2026-02-17 08:29:47 +01:00
maziggy 4cd36abfef fix(queue): update queue item status before archive lookup early return
The queue item status update (printing → completed/failed) was placed
after `if not archive_id: return` in on_print_complete. When archive
lookup failed (app restart mid-print, manual deletion), the function
returned early and the queue item stayed stuck in "printing" forever.

Over multiple print cycles, stale items accumulated — showing double
the actual printer count in the "Printing" stat and completed prints
remaining in the "Currently Printing" section.

Move the entire queue item status update block (status transition,
MQTT relay, queue-completed notification, auto-power-off) to before
the archive_id early return, matching the pattern used for SD card
cleanup.
2026-02-17 07:41:12 +01:00
maziggy 27e4fe49bd fix(ghost-print): run SD card cleanup before archive lookup and add retry logic (#374)
The SD card file cleanup (which prevents phantom prints on power cycle)
was placed after the archive_id early-return in on_print_complete. Users
with auto-archiving disabled never reached the cleanup code, so ghost
prints persisted on every reboot.

- Move cleanup before the archive_id check so it always runs
- Add retry loop (3 attempts, 2s delay) for printers that briefly lock
  the filesystem after a print ends
- Try both .3mf and .gcode extensions

Reported by @DIYofThings in #374.
2026-02-17 07:26:28 +01:00
maziggy 12399abfea fix(usage-tracker): capture ams_mapping from MQTT request topic for slicer-initiated prints
Subscribe to the MQTT request topic (device/{serial}/request) to intercept
print commands from any source (BambuStudio, OrcaSlicer, Bambu Handy, or
Bambuddy itself). Captures ams_mapping from project_file commands and passes
it through print start/complete callbacks. Fixes wrong tray attribution on
H2D Pro when prints are started from external slicers.
2026-02-17 07:07:39 +01:00
maziggy ca9ffbba5d feat(usage-tracker): add diagnostic logging for slot-to-tray mapping investigation
Usage tracking works on X1E but fails on H2D Pro — the wrong tray
is identified, attributing usage to the wrong spool. The root cause
is unknown because we don't know what MQTT mapping data each printer
model reports.

Adds INFO-level logging at print start and completion:
- state.raw_data["mapping"] (unknown format, preserved but never parsed)
- tray_now, last_loaded_tray values
- All raw_data keys containing "map" (discovery)
- Per-AMS-tray summary: tray_type, tray_color, tray_now, tray_tar

This enables comparing MQTT behavior across printer models without
requiring DEBUG mode, so testers can send normal logs.
2026-02-16 17:04:47 +01:00
maziggy cf7c459099 fix(inventory): fix usage tracking for remapped AMS slots and slicer prints
Three fixes for inventory spool usage not updating after prints:

1. Store ams_mapping from print command (reprint, library print, queue)
   so the usage tracker maps 3MF slots to the actual physical trays
   the user selected, not the default slicer mapping.

2. Track last_loaded_tray on printer state — the last valid tray_now
   (0-253) seen during printing. On H2D printers, tray_now is always
   255 in AMS data; the real tray resolves via snow field ~44s after
   print start but reverts to "unloaded" at completion. The fallback
   chain is: tray_now_at_start > current tray_now > last_loaded_tray.

3. Use color similarity (Euclidean RGB distance, threshold 50) instead
   of exact hex match for auto-unlink fingerprint checks. RFID sensors
   report slightly different shades across reads (e.g. distance ~43.6
   for the same spool), causing false assignment unlinks after prints.
2026-02-16 15:46:32 +01:00
MartinNYHC ec82e4d428 Merge pull request #401 from aneopsy/queue-plate-name
feat(queue): display plate name alongside file name for multi-plate files
2026-02-16 13:50:43 +01:00
MartinNYHC f8768b9ee9 Merge branch '0.2.0b' into queue-plate-name 2026-02-16 13:48:14 +01:00
maziggy 6ba5d43a18 fix(queue): show library file name in printer queue widget (#364)
The "Next in queue" widget on the printer card only checked
archive_name/archive_id, so file-manager-sourced queue items
displayed "Archive #null". Now falls back to library_file_name
and library_file_id, matching the Queue page display logic.
2026-02-16 13:46:22 +01:00
AneoPsy 191600b006 fix: use same query keys as PrintModal and ArchivesPage 2026-02-16 02:42:18 -10:00
MartinNYHC bf9679f232 Merge branch '0.2.0b' into queue-plate-name 2026-02-16 13:07:32 +01:00
maziggy e13a72ef19 fix(queue): create archive for library-file prints so 3MF usage tracking works (#364)
When a print was queued from the file manager (library_file_id path),
the scheduler never created an archive or called register_expected_print().
This forced on_print_start to re-download the 3MF via FTP, and if that
failed, a fallback archive with no file was created — breaking 3MF-based
filament usage tracking entirely. The queue item's archive_id also stayed
NULL, so the usage tracker couldn't find the AMS slot mapping.

Now the scheduler creates an archive from the library file before uploading,
sets item.archive_id, and the existing register_expected_print() call fires
since archive is no longer None.
2026-02-16 13:04:10 +01:00
AneoPsy f1f27cefe1 feat(queue): display plate info alongside file name for multi-plate files
- Show plate name or plate ID next to the file name in queue items
- Add translation queue.plateNumber
2026-02-16 01:51:05 -10:00
maziggy 2f61973af2 Housekeeping 2026-02-16 10:57:39 +01:00
MartinNYHC 2cb1a7d8d6 Merge pull request #387 from Keybored02/feature/ui_improvements
Fixed Archive object card clipping, added reprint icon to list view
2026-02-16 10:34:39 +01:00
MartinNYHC bb4687a832 Merge branch '0.2.0b' into feature/ui_improvements 2026-02-16 10:30:08 +01:00
maziggy bc15d49a7e feat: add clear HMS errors button to dismiss stale print errors
Add a "Clear Errors" button to the HMS error modal that sends
clean_print_error via MQTT and locally clears hms_errors for
immediate UI feedback. Useful for dismissing stale print_error
values that persist after print cancellation or transient events.
2026-02-16 10:29:07 +01:00
Matteo Parenti b0d1358b2e Change gcode/3MF preview icon 2026-02-16 10:15:44 +01:00
MartinNYHC 82964da459 Merge pull request #395 from aneopsy/queue-currently-printing-card
feat(Queue) Add more information in Currently Printing job
2026-02-16 10:09:15 +01:00
MartinNYHC 957e57f689 Merge branch '0.2.0b' into feature/ui_improvements 2026-02-16 09:59:00 +01:00
MartinNYHC 78fdb27fa5 Fix indentation in QueuePage.tsx 2026-02-16 09:55:30 +01:00
MartinNYHC ddce4d5c98 Merge branch '0.2.0b' into queue-currently-printing-card 2026-02-16 09:52:20 +01:00
maziggy 2a06ebd9f6 feat: add click-to-enlarge lightbox to skip objects modal (#396)
The small 208px image panel in the skip objects modal made it hard to
distinguish object markers when parts are close together. Clicking the
image now opens a fullscreen lightbox overlay (up to 600px) with the
same markers at a proportionally smaller size, solving the overlap
problem. Close via X button, Escape key, or backdrop click. Escape
cascades correctly — closes lightbox first, then the modal.
2026-02-16 09:50:59 +01:00
AneoPsy 7134007e6a fix(queue): optimize printer status polling and minor cleanup
- Only poll printer status for actively printing items
- Fix indentation in useQuery block
- Add trailing newline to utils/date.ts
2026-02-15 22:47:06 -10:00
AneoPsy 687a48e655 feat(queue): enhance currently printing item display
- Add progress bar, time remaining, ETA, and layer count to currently printing item
- Remove duplicate formatDuration & formatETA functions, now imported from utils/dates
- Remove formatTime (duplicate of formatDuration)
- Update formatETA to support optional i18n translation
- Update translation: common.tomorrow
2026-02-15 22:25:52 -10:00
maziggy cf0287d5c8 fix: auto-select first plate for multi-plate files in print modal (#394)
When scheduling a multi-plate file from the file manager, the modal
allowed submission without selecting a plate. Now auto-selects the
first plate by default and enforces plate selection for both archive
and library files.
2026-02-16 09:11:08 +01:00