Commit Graph
1896 Commits
Author SHA1 Message Date
maziggy 918dec4c19 Skip NTAG write ACK check — PN5180 can't capture 4-bit response
IRQ logging revealed the tag IS responding (RX_SOF_DET set) but the
  PN5180 cannot capture the 4-bit ACK as a complete frame — RX_IRQ
  never fires and RX_STATUS stays zero. Skip per-page ACK checking
  and rely on the read-back verification in ntag_write_pages().
2026-03-25 13:27:31 +01:00
maziggy 31ca2e7ddf Fix NTAG write: reset PN5180 state machine before WRITE command
The PN5180 transceive state machine wasn't being reset between the
  SELECT (from reactivate_card) and the WRITE command — just re-setting
  the TRANSCEIVE bits was a no-op. Use IDLE→TRANSCEIVE transition like
  activate_type_a does. Also clear Crypto1 bit and add IRQ status
  logging.
2026-03-25 13:24:57 +01:00
maziggy bae394d277 Add debug logging to NTAG write/verify path
Temporary diagnostics to identify which step of the NTAG write
  fails: per-page ACK status, reactivation, read-back, or data
  mismatch. Enable DEBUG level for pn5180 module.
2026-03-25 13:21:27 +01:00
maziggy 72536c93a0 Fix NTAG write ACK detection for 4-bit response
The NTAG WRITE ACK is 4 bits (0x0A), not a full byte. The PN5180
  RX_STATUS register reports 0 complete bytes with 4 extra bits, but
  the check only looked at the byte count — returning False on every
  successful write. Check both byte and bit fields of RX_STATUS.
  Also bump post-write delay from 5ms to 10ms for margin.
2026-03-25 13:18:41 +01:00
maziggy f4d8e1ecd3 Fix SpoolBuddy NFC write failing on NTAG 213/215/216 tags
Three issues:

  1. SAK gate too strict — NTAG chips can report SAK 0x04 (MIFARE
     Ultralight family) instead of 0x00. Accept both in nfc_reader.py
     and main.py.

  2. TX CRC disabled for NTAG WRITE — the NTAG spec requires CRC on
     the WRITE command frame. Enable TX CRC in ntag_write_page().

  3. TX CRC disabled for NTAG READ — the post-write verification read
     also failed because ntag_read_pages() sent the READ command
     without CRC. Enable TX CRC there too.
2026-03-25 13:15:45 +01:00
maziggy 9d4f57d54d Fix SpoolBuddy NFC write failing on NTAG 213/215/216 tags
Two issues:

  1. SAK gate too strict — NTAG chips can report SAK 0x04 (MIFARE
     Ultralight family) instead of 0x00. Accept both in nfc_reader.py
     and main.py.

  2. TX CRC disabled during WRITE — the NTAG WRITE command (0xA2)
     requires a CRC on the frame. The PN5180 was sending without CRC,
     causing the tag to NAK every write. Enable TX CRC for writes
     (RX CRC stays off for the 4-bit ACK).
2026-03-25 13:12:57 +01:00
maziggy f71367bb4e Fix SpoolBuddy NFC write rejecting NTAG 215 tags with SAK=0x04
NTAG 213/215/216 chips can report SAK 0x04 (MIFARE Ultralight family)
  instead of 0x00 during anticollision. Accept both values for NTAG
  detection and write operations in nfc_reader.py and main.py.
2026-03-25 13:10:11 +01:00
maziggy 504a0f9970 Compact SpoolBuddy settings Device tab to fit without scrolling
Remove branding/about card, fold Device ID into Device Info card,
  place Backend/Auth config and diagnostic buttons side by side in a
  2-column grid, remove redundant online/offline status from Device
  Info, and tighten spacing throughout.
2026-03-25 12:57:24 +01:00
maziggy 73aeee7bdf Compact SpoolBuddy settings Device tab to avoid scrolling
Remove the branding/about card, fold Device ID into the Device Info
  card, make diagnostic buttons a horizontal 3-column row, and put the
  API token input and Save button on the same line. Tighten spacing
  throughout so the tab fits on the small touchscreen without scrolling.
2026-03-25 12:52:43 +01:00
maziggy 3c1fdd13b9 Added back debug logs to Spoolbuddy test scripts 2026-03-25 12:16:49 +01:00
maziggy d5c520dd71 Added back debug logs to Spoolbuddy test scripts 2026-03-25 12:15:29 +01:00
maziggy 74387b7c38 Added back debug logs to Spoolbuddy test scripts 2026-03-25 12:15:22 +01:00
maziggy f96d211612 Added back debug logs to Spoolbuddy test scripts 2026-03-25 12:13:31 +01:00
maziggy 2b1fe03159 Fix SpoolBuddy scale first reading and extract hardware drivers
The NAU7802 ADC returns a stale max-scale value (0x7FFFFF) on its
  first conversion after power-up, polluting the moving average and
  making the initial weight report wildly inaccurate. Flush the first
  reading during init().

  Also extract both hardware drivers out of diagnostic scripts into
  proper daemon modules:
  - NAU7802 scale driver: scripts/scale_diag.py -> daemon/nau7802.py
  - PN5180 NFC driver: scripts/read_tag.py -> daemon/pn5180.py

  The production daemon was importing driver classes from test scripts
  since the original SpoolBuddy commit. Diagnostic scripts now import
  from the driver modules. Removed the sys.path hack from main.py.
2026-03-25 11:57:28 +01:00
maziggy 5926e722f8 Fix H2D external spool print failing with 0700_8012 (#797)
BambuStudio converts virtual tray IDs (254/255) to -1 in the flat
  ams_mapping and relies on ams_mapping2 for external spool routing.
  Bambuddy was passing raw 254/255 in the flat array, which H2D firmware
  rejects with "Failed to get AMS mapping table".

  - Convert external tray IDs to -1 in flat ams_mapping (match BambuStudio)
  - Fix ams_mapping2 for external trays: each virtual tray is its own AMS
    unit with slot_id 0, not a shared unit differentiated by slot
  - Fix main/deputy nozzle ID comment (255=main, 254=deputy per BambuStudio)
  - Add 8 unit tests for start_print() mapping construction
2026-03-25 11:38:27 +01:00
maziggy a5ea3f599a Minor Spoolbuddy install.sh fixes 2026-03-25 10:24:47 +01:00
maziggy f96b9ded56 Add WiFi safeguard and apt upgrade to SpoolBuddy install script
Install script now runs apt-get upgrade -y after installing system
  packages. A WiFi safeguard (APT hook + helper script) is installed
  first, backing up NetworkManager connections before dpkg and restoring
  them if wiped — prevents headless Pis from losing WiFi during upgrades.
2026-03-25 10:22:22 +01:00
maziggy cb31a6cd33 Add apt upgrade to SpoolBuddy install script
Runs apt-get upgrade -y after installing system packages and the WiFi
  safeguard hook. Ensures the Pi is fully up to date before deploying
  SpoolBuddy, and the WiFi safeguard protects NM connections during
  the upgrade.
2026-03-25 10:14:16 +01:00
maziggy 53da037048 Add WiFi safeguard to SpoolBuddy install script
APT hook backs up NetworkManager WiFi connections before dpkg runs
  and restores them if they get wiped. Prevents headless SpoolBuddy
  Pis from losing WiFi after apt upgrade (observed with Bookworm
  kernel/raspi-config updates clearing system-connections/).
2026-03-25 09:53:14 +01:00
maziggy 88c0503009 Show spool notes as hover tooltip in Assign Spool modal (#793) 2026-03-25 08:55:06 +01:00
maziggy b8fa2df36d Increase database connection pool limits for large printer farms
QueuePool exhaustion at 100+ printers. Bumped pool_size 10→20,
  max_overflow 20→200, and SQLite busy_timeout 5s→15s.
2026-03-25 08:20:22 +01:00
maziggy 95c703282d Fix missing image thumbnails in external folder scan (#124)
External folder scan generated thumbnails for 3mf/stl/gcode files but
  skipped image files. Added IMAGE_EXTENSIONS check with
  create_image_thumbnail() to the scan loop.
2026-03-24 16:32:45 +01:00
maziggy c9efa4b8bb Fix stale AMS slot data and empty slot button visibility (#784)
Some printers (e.g. H2D) only send {id, state} in incremental MQTT
  tray updates — no tray_type, tray_color, or other fields. When
  filament is unloaded (state changes from 11 to 10), the old tray
  data persisted indefinitely because the merge logic only updates
  fields present in the incoming message.

  Backend:
  - Detect tray state != 11 without tray_type in incremental updates
    and clear stale tray data (bambu_mqtt.py)
  - Expose tray `state` field via REST API and WebSocket broadcasts
    (printer.py schema, printers.py route, printer_manager.py)
  - Include AMS tray content in WebSocket dedup key so load/unload
    transitions trigger broadcasts (main.py)

  Frontend:
  - Add `state` to AMSTray interface (client.ts)
  - Show configure/assign buttons for state=10 (spool present, not
    loaded) but hide for state=9 (truly empty) on AMS/HT slots
  - Hide fill level bar on empty slots

  Tests:
  - 5 new tests covering state-based clearing, preservation, reload,
    and idempotency
2026-03-24 16:03:34 +01:00
Keybored 6e648804fc [Feature] Spoolbuddy Fixes and Improvements (#787)
[Feature] Spoolbuddy Fixes and Improvements (#787)
2026-03-24 11:56:33 +01:00
maziggy 9f2722be36 Post work PR #763 2026-03-24 11:41:05 +01:00
Keybored 3f7d0e2d55 Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
2026-03-24 11:31:32 +01:00
maziggy dd75c8f0c9 feat: auto-link untagged inventory spools on AMS insert (#538)
When a Bambu Lab spool is detected in the AMS but no tag match exists,
  check for an untagged inventory spool with matching material/subtype/color
  before creating a new entry. Links the RFID tag to the existing spool
  (data_origin="rfid_linked") to prevent duplicate inventory entries.
2026-03-24 09:23:25 +01:00
maziggy 82278e8d93 Add external folder mounting for File Manager (#124)
Host directories (NAS, USB, network shares) can now be mounted
  into the File Manager without copying files. Files are indexed
  into the database on scan but read directly from their original
  location. Supports read-only mode, hidden file filtering, and
  automatic thumbnail extraction for 3MF/STL/gcode.

  - POST /library/folders/external — create with path validation
  - POST /library/folders/{id}/scan — discover/sync files
  - Block uploads, moves, and deletes for read-only external folders
  - Never delete actual files from external paths (DB-only removal)
  - Purple folder icon + info bar with rescan button in UI
  - i18n for all 7 languages
  - 19 backend + 11 frontend tests
2026-03-24 08:43:23 +01:00
maziggy 293ebd9b3f Fix ffmpeg process leak causing multi-GB memory growth (#776)
When a user closed the camera viewer, the stop endpoint killed the
  ffmpeg process but never signaled the stream generator's disconnect
  event. The generator saw "process died" as a dropped RTSP session
  and respawned ffmpeg — up to 30 times per stream. The orphan cleanup
  couldn't catch these because they were still tracked as active.

  - Add per-stream disconnect events dict so stop endpoint can signal
    generators to stop reconnecting before killing the process
  - Check if stream_id was removed from _active_streams before
    reconnecting (belt-and-suspenders with the event)
  - Track frame timestamps per stream_id instead of per printer_id
    so stale detection isn't fooled by newer streams for the same
    printer
  - Reduce stale thresholds from 120s+60s to 60s+30s
  - Signal disconnect events from cleanup when killing stale streams
2026-03-24 07:49:54 +01:00
maziggy d833cb88ff Updated CHANGELOG 2026-03-23 16:24:08 +01:00
maziggy 7b91cde6db Fixed typo in version 2026-03-23 16:14:44 +01:00
maziggy 745ff232eb Fix log flood: "State is FINISH but completion NOT triggered" (#790)
Diagnostic log added in 0.2.2.1 fired on every MQTT update while a
  printer was in FINISH/FAILED state, not just on the state transition.
  For farms with multiple idle printers, this produced thousands of log
  lines per minute. Guard the log to only fire once when the state first
  changes to FINISH/FAILED.
2026-03-23 16:07:44 +01:00
maziggy b8a3aa842b Add tests for SpoolBuddy SSH update service and settings UI
15 backend unit tests covering keypair management, branch detection,
  SSH command execution (success/failure/timeout), and full update flow
  with error handling. 4 new frontend tests for the Updates tab (version
  display, buttons, SSH setup, update available state).
2026-03-23 15:55:44 +01:00
maziggy c42d834219 Revert "version test"
This reverts commit cf8f43169b.
2026-03-23 15:46:10 +01:00
maziggy cf8f43169b version test 2026-03-23 15:45:08 +01:00
maziggy 364b02b8ac Housekeeping 2026-03-23 15:44:49 +01:00
maziggy 382daef6e2 Revert "version test"
This reverts commit 36494a6f6b.
2026-03-23 15:34:15 +01:00
maziggy 36494a6f6b version test 2026-03-23 15:33:10 +01:00
maziggy 8d60c31aa7 Force-clear service worker and caches on SpoolBuddy kiosk load
Just unregistering the SW wasn't enough — the old SW still controlled
  the page for that load. Now detects if any SW exists, nukes all SWs
  and caches, then reloads once to get a clean fetch from the server.
  Subsequent loads skip this since no SW is registered.
2026-03-23 15:32:06 +01:00
maziggy bc37c12f90 Disable service worker on SpoolBuddy kiosk to prevent stale frontend
The kiosk touchscreen has no way to hard-refresh, and the service worker
  served stale cached JS after updates. SpoolBuddy pages now unregister
  any existing SW and skip registration entirely. Regular desktop/mobile
  users still get the SW. Restored kiosk restart in SSH update flow since
  SW is no longer an obstacle.
2026-03-23 15:28:24 +01:00
maziggy c63c4fc39b version test 2026-03-23 15:21:39 +01:00
maziggy 7f1ced60fd Fix stale frontend after deploy due to service worker caching
The SW used stale-while-revalidate for JS/CSS, serving old cached
  bundles even after a new build. Changed to network-first (Vite already
  content-hashes filenames), bumped cache version v24→v25, and added
  Cache-Control: no-cache to the sw.js endpoint so browsers always fetch
  the latest service worker.
2026-03-23 15:12:18 +01:00
maziggy 8be4bed384 Fix SpoolBuddy update UI responsiveness and stale data
Rewrote update button states: single `busy` flag stays set from click
  through to device pickup — no more gap with no feedback. Buttons hide
  while any operation is in progress. Listens for spoolbuddy-online
  WebSocket event to reload the page after daemon re-registers, ensuring
  fresh version and status. Set staleTime to 0 on update check queries.
2026-03-23 15:04:56 +01:00
maziggy 559d41cc5e Fix SpoolBuddy update UI: loading states, page reload, stale data
Check button had no visual feedback because isFetching doesn't trigger
  reliably with cached data — replaced with manual loading state. Removed
  kiosk restart via getty; the frontend now detects daemon re-registration
  via WebSocket and calls window.location.reload(), keeping the user on
  the same page and fetching all fresh data.
2026-03-23 14:59:12 +01:00
maziggy 1f24bd264a Fix SpoolBuddy update UI feedback and stale query cache
- Check button now shows spinner on refetch (isFetching vs isLoading)
  - Force Update button shows spinner while triggering
  - Reduced staleTime from 4 minutes to 30 seconds so the UI picks up
    version changes after an update without a long delay
2026-03-23 14:48:10 +01:00
maziggy 0e44e149bd ● Compact SpoolBuddy updates tab layout to fit without scrolling
Merged version, status, and update check into a single card. Buttons
  are side by side when up to date. Reduced padding and font sizes.
  Removed separate "complete" banner since status is now cleared on
  re-registration. SSH Setup section is smaller and more compact.
2026-03-23 14:36:58 +01:00
maziggy b83a99ebab ● Fix SpoolBuddy update status stuck after restart
The SSH update set status to "complete" after the daemon had already
  restarted and re-registered, overwriting the cleared state so it stuck
  forever. Removed the post-restart "complete" write — daemon
  re-registration is now the completion signal, clearing any update status.
2026-03-23 14:26:50 +01:00
maziggy a922c18a41 ● Disable Chromium disk cache in SpoolBuddy kiosk
After updates, the kiosk browser showed stale frontend assets from
  Chromium's disk cache even after restarting. Added --disk-cache-size=0
  to the launch flags — the kiosk loads a single page from the local
  network so caching provides no benefit.
2026-03-23 14:11:21 +01:00
maziggy db43218785 Fix SpoolBuddy kiosk launching before network is ready
The getty@tty1 autologin had no network dependency, so the labwc/Chromium
  kiosk chain started before connectivity was up — showing a connection
  error for 10-15 seconds. Added After=network-online.target to the
  autologin override so the browser has network when it launches.
2026-03-23 14:04:55 +01:00
maziggy 811813165b Fix stale SpoolBuddy update status after daemon restart
After an SSH update completed, the UI kept showing "Update complete,
  daemon restarting..." and the old "update available" banner because
  nothing cleared the stale state. Registration now resets update_status
  when the daemon comes back, and WebSocket handlers for spoolbuddy_update
  and spoolbuddy_online invalidate the frontend queries immediately.
2026-03-23 13:55:12 +01:00