Commit Graph
731 Commits
Author SHA1 Message Date
maziggy 7eb82f58fa Updated CHANGELOG 2026-03-11 10:13:35 +01:00
maziggy c873b74fe6 Merge branch '0.2.2b3' into 0.2.3b1 2026-03-11 10:05:02 +01:00
maziggy d374e5f70b Fix debug logging endpoint 500 error after version upgrade
The GET /api/v1/support/debug-logging endpoint returned 500 when the
  database contained a timezone-aware enabled_at timestamp written by
  0.2.2b3. The duration calculation mixed offset-aware and offset-naive
  datetimes, raising TypeError. Strip tzinfo when reading the stored value.
2026-03-11 09:58:51 +01:00
maziggy 3788dd723c Added debug logging for ffmpeg process 2026-03-11 09:57:55 +01:00
maziggy f69b0413f0 Fix bed cooled notification never firing (#497)
Two bugs prevented bed cooldown notifications from working:

  1. Stale temperature data: After print completion, the printer sends
     partial MQTT updates without bed_temper, leaving the cached value
     frozen at the end-of-print temperature. The monitor polled for 30
     minutes seeing the stale value above threshold, then timed out.
     Fix: send periodic pushall commands to force fresh temperature data.

  2. Missing fields in provider create endpoint: on_bed_cooled and all 7
     queue event toggles were omitted from the NotificationProvider
     constructor, silently discarding user selections on create (update
     worked fine via dynamic setattr).

  Also added debug logging to the bed cooldown polling loop.
2026-03-11 09:57:55 +01:00
maziggy a0fee9a1b6 Fix debug logging banner showing negative timer duration
The debug logging banner displayed a negative elapsed time (e.g. "-60m -59s")
  equal to the server's UTC offset. datetime.now() stored local time without a
  timezone indicator, but the frontend's parseUTCDate() interpreted it as UTC.

  Use datetime.now(tz=timezone.utc) consistently for storing, parsing, and
  comparing the enabled_at timestamp.
2026-03-11 09:57:34 +01:00
Dakota G be2ddbee5d [Fix]: Update location when linking/unlinking to/from Spoolman (#669)
* Enhance link spool functionality with additional printer and AMS details

* Refactor linkSpool function to accept detailed context object for improved spooling integration

* Enhance LinkSpoolModal to include amsName in props and linkSpool mutation for improved functionality

* Add amsName prop to PrinterCard for enhanced spool linking functionality

* Updates LinkSpoolModal test to work with recent spool location update changes

* Adds clear_location to unlink testing

* Refactor LinkSpoolRequest to remove ams_name and update location generation logic for improved clarity

* Remove amsName from LinkSpoolModal and PrinterCard for cleaner API integration

* Remove amsName from LinkSpoolModal test props and update linkSpool mock response for improved clarity
2026-03-11 09:38:14 +01:00
maziggy 53b8cbc169 Added debug logging for ffmpeg process 2026-03-11 09:29:03 +01:00
maziggy 283eaed2de Fix bed cooled notification never firing (#497)
Two bugs prevented bed cooldown notifications from working:

  1. Stale temperature data: After print completion, the printer sends
     partial MQTT updates without bed_temper, leaving the cached value
     frozen at the end-of-print temperature. The monitor polled for 30
     minutes seeing the stale value above threshold, then timed out.
     Fix: send periodic pushall commands to force fresh temperature data.

  2. Missing fields in provider create endpoint: on_bed_cooled and all 7
     queue event toggles were omitted from the NotificationProvider
     constructor, silently discarding user selections on create (update
     worked fine via dynamic setattr).

  Also added debug logging to the bed cooldown polling loop.
2026-03-11 08:55:03 +01:00
maziggy 253828c2b5 Fix debug logging endpoint 500 error after version upgrade
The GET /api/v1/support/debug-logging endpoint returned 500 when the
  database contained a timezone-aware enabled_at timestamp written by
  0.2.2b3. The duration calculation mixed offset-aware and offset-naive
  datetimes, raising TypeError. Strip tzinfo when reading the stored value.
2026-03-10 14:13:32 +01:00
Dakota GandMartinNYHC 971984f91d [Fix]: Non-Bambu Lab Spools can now be fully linked/unlinked to Spoolman (#653)
* Expanded link logic to accept a generic spool tag (spool_tag, tray_uuid, or tag_uid) and validate 16/32-char hex values, including rejection of all-zero tags. Added a new unlink endpoint that clears Spoolman extra.tag for a given spool ID.

* Updated the link validation expectation to match the new 16-or-32-hex rule. Added an integration test for the new unlink endpoint to verify extra.tag is cleared and success is returned.

* Updated the link API call to send spool_tag instead of tray_uuid. Added a new unlinkSpool API helper that calls the new backend unlink route.

* Switched modal data source from inventory spools to Spoolman unlinked spools so the list matches the backend response you shared. Updated the link action to call Spoolman link directly and use trayUuid or tagUid as the slot tag.

* Refactored Spoolman card behavior so actions render correctly across linked/unlinked cases, and added support for an Unlink from Spoolman button under Open in Spoolman. Final UI rule now hides Unlink for Bambu Lab filament and shows it only for non-Bambu linked spools.

* Added fallback slot-tag generation so untagged slots can still be linked/unlinked reliably and linked spool lookups work consistently across AMS, AMS-HT, and external trays. Wired a new unlink mutation and passed per-slot unlink callbacks into the hover card, with query invalidation for linked/unlinked spool caches after unlink.

* Added/updated the noTrayUuid message to reflect that either tray UUID or tag UID is required when no slot tag is available. This keeps error text aligned with the new tag fallback and modal behavior.

* Added noTrayUuid message in the other languages. The translation was done using Google Translate.

* Updated LinkSpoolModal tests to use Spoolman API instead of inventory API, with new UnlinkedSpool data structure and Select Spool UI text.

* Adds hashSerialToHex32, uses new function in getFallbackSpoolTag and updates all uses. This ensures we're generating a fallback spool tag using the printers serial number rather than the database ID for consistency.

* Removes 'import json' from unlink_spool and moves to the top of the file.

* Removes hasUnlinkedSpools and related references since it's no longer used

* Removes noTrayUuid from translations and references in components.

* Adds confirmation dialog before fully unlinking spool from Spoolman

* Adds unlinkConfrimTitle and unlinkConfirmMessage. All languages other than English were done using Google Translate

* Fixes unlink toast to use dedicated unlinkSuccess and unlinkFailed keys.

* Changes tag priority on spoolTag, fixes type error by adding non-null assertion to spoolTag

* Switches around tag_uid and tray_uuid on const trayTag

---------

Co-authored-by: MartinNYHC <mz@v8w.de>
2026-03-10 14:06:09 +01:00
maziggy 63208cf6f1 Fix debug logging banner showing negative timer duration
The debug logging banner displayed a negative elapsed time (e.g. "-60m -59s")
  equal to the server's UTC offset. datetime.now() stored local time without a
  timezone indicator, but the frontend's parseUTCDate() interpreted it as UTC.

  Use datetime.now(tz=timezone.utc) consistently for storing, parsing, and
  comparing the enabled_at timestamp.
2026-03-10 10:51:23 +01:00
maziggy f28421d1ae Add Home Assistant as notification provider (#656)
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.
2026-03-10 10:10:14 +01:00
maziggy 688804ac07 Housekeeping 2026-03-10 08:38:29 +01:00
maziggy fa4bb92f7d Add higher FTP timeout options for large 3MF files (#660)
Large Hueforge 3MF files (~28 MB) can't be downloaded from the
  printer's FTP server within the previous 120s max timeout, especially
  during active printing. Added 180s and 300s timeout options to the
  FTP settings dropdown.
2026-03-10 08:31:44 +01:00
maziggy 68d2230cab Fix H2D AMS units displayed on wrong nozzle (#659)
Three interrelated bugs in AMS info field parsing caused AMS units
  to appear on the wrong nozzle on H2D dual-nozzle printers:

  1. Info field parsed as decimal instead of hex (BambuStudio uses
     std::stoull with base 16)
  2. Extruder ID extracted as 1-bit instead of 4-bit field (bits 8-11)
  3. Partial MQTT updates replaced the full extruder map instead of
     merging into it
2026-03-10 08:18:23 +01:00
maziggy 121b3d53df fix: remove incorrect ethernet badge on printer cards
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.
2026-03-09 12:16:22 +01:00
d7401a80df Feature: Force Color Match (#625)
* 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>
2026-03-09 11:54:02 +01:00
Neale Swinnerton ae80eaade0 feat(metrics): add bambuddy_build_info metric
Publish a gauge with version, python_version, platform, and
architecture labels at the top of the Prometheus metrics endpoint.
2026-03-07 15:40:48 +00:00
maziggy b3c37072b2 Add auto-dispatch toggle for virtual printer queue mode (#587)
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.
2026-03-07 11:41:01 +01:00
maziggy f1d5ee422c Bumped version 2026-03-07 11:11:16 +01:00
maziggy 0efb4690b9 Fix SD card error after FTP upload by waiting for 226 response (#645)
The FTP upload skipped reading the server's "Transfer complete"
  confirmation, sending the print command before the file was flushed
  to the SD card. Now waits for the 226 response with a 60s timeout.
2026-03-07 11:01:34 +01:00
maziggy a7ddc483b3 Add bulk delete for spool and color catalog entries (#646)
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.
2026-03-07 10:13:40 +01:00
maziggy d55585a73f Fix P2S showing carbon rod maintenance tasks (#640)
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.
2026-03-07 09:45:14 +01:00
maziggy 09c3c24111 Add ETA variable to print notification templates (#638)
Add {eta} template variable showing wall-clock completion time
  (e.g. "15:53" or "3:53 PM") to print_start, print_progress, and
  queue_job_started notifications. Respects the user's time_format
  setting (12h/24h). The existing {estimated_time} variable continues
  to show duration ("1h 23m").
2026-03-07 09:34:01 +01:00
maziggy f66bd26f6e Add inventory:view_assignments permission so admins can grant users
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
2026-03-07 09:17:26 +01:00
maziggy 538fe4b13b Bumped version 2026-03-06 15:51:49 +01:00
maziggy 46097a9ed4 Fix archived files counted as printed in project statistics (#630)
Files added to a project from the archive (status="archived") were
  incorrectly counted in completed_prints and parts_progress stats.
  Only status="completed" (actually printed) now counts toward completion.
2026-03-06 13:32:19 +01:00
maziggy 940810cba3 Show filament subtypes in all mapping dropdowns (#624)
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.
2026-03-06 08:35:06 +01:00
maziggy becc4669b1 Fix greenlet_spawn error in spool auto-assign
Two lazy-load bugs caused greenlet_spawn errors in the RFID auto-assign
  flow:

  1. create_spool_from_tray set spool.k_profiles=[] AFTER db.flush(),
     but assigning to a relationship on a persistent object triggers a
     lazy load (SQLAlchemy loads the current collection before replacing).
     Moved initialization to BEFORE db.add().

  2. spool.assignments was never initialized or eagerly loaded, so
     db.add(SpoolAssignment) triggered a back_populates lazy load
     outside the async greenlet. Added assignments=[] in create and
     selectinload(Spool.assignments) in get_spool_by_tag.

  Also added exc_info=True to error handlers for full tracebacks, and
  19 new tests including greenlet regression tests that reproduce the
  exact failure.
2026-03-05 12:40:53 +01:00
maziggy 0faf03ecb3 Fix Python 3.10 compatibility (StrEnum requires 3.11)
enum.StrEnum was added in Python 3.11, but the documented minimum is
  3.10. Add a compatibility shim in backend/app/core/compat.py that falls
  back to (str, Enum) on older versions. Updated all 5 import sites and
  lowered pyproject.toml target-version to py310.
2026-03-05 10:44:24 +01:00
maziggy aa39f6c866 Fix Bind-TLS proxy handshake failure on OpenSSL 3.x
Bambu printers only support plain RSA key exchange ciphers
  (AES256-GCM-SHA384, AES128-GCM-SHA256), but Python's OpenSSL 3.x
  defaults exclude them in favor of forward-secrecy (ECDHE/DHE) only.
  Add the RSA ciphers to the client SSL context so the TLS proxy can
  connect to the printer's bind port (3002).
2026-03-05 10:08:31 +01:00
maziggy 0bff20662c Add scheduler diagnostic logging for queue stall debugging (#616)
When the print queue scheduler finds pending items but doesn't start
  any, there was no logging to explain why. Added INFO-level summary
  after each queue check showing skip reasons (manual_start,
  scheduled_future) and busy printer details (state, connected,
  plate_cleared). Also added DEBUG-level logging in _is_printer_idle()
  for the specific condition that failed.
2026-03-05 09:18:38 +01:00
maziggy ed462c5cca Add tests, docs, and lint fix for AMS Info Card feature (#570)
- 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
2026-03-05 08:46:39 +01:00
Thomas RambachandMartinNYHC 7ba67012f6 Feature AMS Info Card (#570)
* AMS Labels addition to PrintersPage

* Added database reinitialization for schema migrations on database restore

* Bug fixes and AMS Label persistence updates

* Update database.py to resolve PR conflicts

* PR Comment Resolution

* Resolve conflicts in database.py for PR#570

* Updates to address PR#570 additional comments

* Optimize visibility handling for popup component

* Improve serial key handling in printers.py

Refactor serial key assignment to handle empty AMS serial gracefully.

* Implement error handling in serial number mapping

Add error handling for serial number mapping.

* Add migration to drop old ams_labels table

---------

Co-authored-by: MartinNYHC <mz@v8w.de>
2026-03-05 08:36:39 +01:00
maziggy 5ee2ef8dbf Fix Windows server shutdown after 60s from ffmpeg cleanup (#605)
On Windows, process.terminate() on ffmpeg broadcasts CTRL_C_EVENT to
  the entire process group, causing uvicorn to shut down. Spawn ffmpeg
  with CREATE_NEW_PROCESS_GROUP so cleanup doesn't affect the server.
2026-03-04 15:25:55 +01:00
maziggy dba43530cb Bumped version 2026-03-04 15:12:22 +01:00
maziggy 058f74a7da Add in-app bug reporting with relay, debug log collection, and privacy controls
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.
2026-03-04 13:33:19 +01:00
maziggy 6388b0df9b Show ethernet indicator instead of WiFi signal for wired printers (#585)
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.
2026-03-04 09:44:08 +01:00
maziggy 76fd8c5c48 Add SSDP model codes to firmware check mapping (#584)
The firmware check only mapped display names (e.g., "H2D Pro") to
  API keys but not raw SSDP device codes (e.g., "O1E", "O2D"). If a
  printer's model was stored as the raw SSDP code, the firmware check
  either failed or matched the wrong model — H2D Pro matched against
  H2D firmware, showing a false update-available badge.

  Add all known SSDP device codes to MODEL_TO_API_KEY so firmware
  versions resolve correctly regardless of how the model was stored.
2026-03-04 09:34:33 +01:00
maziggy acae51b938 Fix spurious 0300_0002 error notification via HMS array path (#583)
The previous fix only filtered status codes (< 0x4000) from the
  print_error field. Firmware can also send the same false positive
  through the hms array in MQTT, which had no such filter. Apply the
  same < 0x4000 check to the HMS parser so status/phase indicators
  are skipped regardless of which MQTT field carries them.
2026-03-04 09:26:51 +01:00
maziggy 19a1a7584b Fix archive card showing "Source" badge for sliced .3mf files
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.
2026-03-03 14:26:03 +01:00
maziggy 6b92a99dd8 Improve FTP upload progress and widen print modal
FTP upload: reduce chunk size from 1MB to 64KB for smooth progress bar
  updates (~1s intervals instead of 20+ second gaps). Skip voidresp() for
  all printer models — H2D delays the 226 response by 30+ seconds after
  data transfer, causing a hang at 100%. Add transfer speed and TLS
  handshake timing to logs for diagnosing slow connections.

  Print/Schedule modal: widen from max-w-lg (512px) to max-w-2xl (672px)
  to accommodate long filament profile names like "PLA Support for PETG
  PETG Basic @Bambu Lab H2D 0.4 nozzle".
2026-03-03 14:14:26 +01:00
maziggy 330d77198a Fix AMS slot showing wrong material for "Support for" profiles
Profiles like "PLA Support for PETG PETG Basic @Bambu Lab H2D" have
  filament_type PETG, but both the frontend and backend name parsers
  found "PLA" first (iterating material types in order). The MQTT command
  sent tray_type=PLA and tray_info_idx=GFL99 (PLA generic), so the
  slicer displayed PLA instead of PETG.

  - Frontend parsePresetName(): detect "X Support for Y" pattern, extract
    material after "Support for"
  - Frontend ConfigureAmsSlotModal: prefer corrected parsed material over
    stored localPreset.filament_type for tray_type, tray_info_idx, and
    temperature fallback
  - Backend _parse_material_from_name(): same "Support for" handling for
    future profile imports
  - Backend assign_spool: prioritize spool.material over lp.filament_type
    for generic filament ID lookup
2026-03-03 13:34:03 +01:00
maziggy e3ebe86b00 Remove obsolete slicer_binary_path setting from database
The slicer_binary_path key was left in the settings table from earlier
  slicer integration research but is no longer referenced anywhere in the
  codebase. Add a startup migration step that deletes orphaned settings
  keys so they don't persist in backups.
2026-03-03 11:39:43 +01:00
97f6250a0b Add customizable low stock threshold, add low stock filter (#531)
* 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

* Make low stock threshold editable

* Add new filter for low spools

* Update bug report template to require additional fields

* Added toast for invalid imputs with locales, updated inputb field restrictions

* Minor Spoolbuddy frontend improvements

* Updated test_backend.sh

* 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.

* Minor changes, CSS fixes

* Refactor usageFilter state to remove 'lowstock' option for clarity

* Move var saving to API, add test coverage

* fix: threshold validation and cleanup

* Change test input from '150' to '0'

---------

Co-authored-by: tridev <c.tripod@gmx.ch>
Co-authored-by: MartinNYHC <mz@v8w.de>
2026-03-03 10:04:13 +01:00
maziggy e2ba768c2e Fix spurious error notifications from print_error status codes
Some firmware sends non-zero print_error values (e.g. 0x03000002 →
  0300_0002) during normal printing as status/phase indicators. The
  parser treated any non-zero value as a real error, triggering
  notifications. All known real errors have codes >= 0x4000 (fatal,
  warning, prompt ranges). Now skips print_error values where the
  low 16 bits are below 0x4000.

  Also fix K-profile greenlet error on auto-created RFID spools by
  eagerly setting k_profiles=[] after flush in create_spool_from_tray().
2026-03-02 14:06:06 +01:00
maziggy 219214f0af Fix K-profile greenlet error on auto-created RFID spools
create_spool_from_tray() didn't eagerly load the k_profiles
  relationship, so auto_assign_spool() triggered a lazy load in async
  context when iterating spool.k_profiles. Set k_profiles=[] on new
  spools since they can never have K-profiles yet.
2026-03-02 14:00:52 +01:00
maziggy f943420ea2 Add SpoolBuddy NFC tag writing with OpenTag3D format
Write NTAG213/215/216 tags for third-party spools via the SpoolBuddy
  kiosk UI. New "Write" page with three workflows: existing spool, new
  spool creation, and tag replacement. Backend encodes 133-byte OpenTag3D
  NDEF payloads (material, color, brand, weight, temp). Daemon writes
  page-by-page via PN5180 NTAG WRITE command with read-back verification.
  Write commands flow through heartbeat polling with WebSocket status
  updates. Includes 39 new tests and translations for all 6 languages.
2026-03-02 13:56:15 +01:00
maziggy 628a814271 Redesign SpoolBuddy settings page, add language/time format support
- Redesign settings page with tabbed layout (Device, Display, Scale, Updates)
  - Add screen blank timeout: blanks after touch inactivity, tap to wake
  - Add CSS brightness filter for HDMI displays (no sysfs on HDMI)
  - Add backend `language` field to app settings for server-side persistence
  - Sync UI language from backend on kiosk load (separate Chromium instance)
  - Top bar clock respects user's time format setting (system/12h/24h)
  - Add SpoolBuddy settings translations for all 6 languages (en/de/fr/ja/it/pt-BR)
  - Disable Chromium swipe-to-navigate in kiosk install script
  - Add `video` group for DSI backlight access
2026-03-02 12:44:45 +01:00