Browse Source

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.
maziggy 2 months ago
parent
commit
f71367bb4e
4 changed files with 5 additions and 4 deletions
  1. 1 0
      CHANGELOG.md
  2. 1 1
      spoolbuddy/README.md
  3. 1 1
      spoolbuddy/daemon/main.py
  4. 2 2
      spoolbuddy/daemon/nfc_reader.py

+ 1 - 0
CHANGELOG.md

@@ -17,6 +17,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **SpoolBuddy Install Script Now Upgrades System Packages** — The install script now runs `apt-get upgrade -y` after installing required packages and the WiFi safeguard. This ensures the Pi is fully up to date before SpoolBuddy is deployed, and the WiFi safeguard protects connectivity during the upgrade.
 
 ### Fixed
+- **SpoolBuddy NFC Write Rejects NTAG 215 Tags (SAK=0x04)** — Some NTAG 213/215/216 chips report SAK `0x04` (MIFARE Ultralight family) instead of `0x00` during anticollision. The write gate only accepted `0x00`, causing "Incompatible tag type" errors on valid NTAG tags. Both SAK values are now accepted for NTAG detection and write operations.
 - **Database Connection Pool Exhaustion on Large Printer Farms** — Users with 100+ printers connected simultaneously experienced `QueuePool limit of size 10 overflow 20 reached, connection timed out` errors. Increased the SQLAlchemy connection pool from 30 total (10 base + 20 overflow) to 220 (20 base + 200 overflow), and raised the SQLite busy_timeout from 5 to 15 seconds to reduce write contention under heavy concurrent MQTT updates.
 - **SpoolBuddy Update Check Always Shows "Up to Date"** — The SpoolBuddy daemon update check compared the device's firmware version against GitHub releases instead of the running Bambuddy backend version. This meant the check could incorrectly report "up to date" even when the daemon was behind. Fixed by comparing directly against `APP_VERSION` from the backend config.
 - **SpoolBuddy Updates Now Use SSH** — Replaced the fragile self-update mechanism (daemon pulls its own code via git, permission errors on `.git/`, hardcoded `main` branch) with SSH-based updates driven by the Bambuddy backend. Bambuddy now SSHes into the SpoolBuddy Pi and runs git fetch/checkout, pip install, systemctl restart, and kiosk browser restart remotely. Updates automatically use the same branch as Bambuddy. SSH key pairing is fully automatic — Bambuddy generates an ED25519 keypair and includes the public key in the device registration response; the daemon deploys it to `authorized_keys` on first connect. The install script creates the `spoolbuddy` user with a bash shell and sudoers entries for daemon and kiosk restart. A "Force Update" button allows re-deploying even when versions match. The SSH public key is also shown in SpoolBuddy Settings → Updates → SSH Setup for manual pairing if needed.

+ 1 - 1
spoolbuddy/README.md

@@ -123,7 +123,7 @@ Place a tag on the reader. Supported tag types:
 |---------------------|--------|------------------------------|
 | MIFARE Classic 1K   | `0x08` | Bambu Lab filament tags      |
 | MIFARE Classic 4K   | `0x18` | Bambu Lab filament tags      |
-| NTAG (213/215/216)  | `0x00` | SpoolEase / OpenPrintTag     |
+| NTAG (213/215/216)  | `0x00` / `0x04` | SpoolEase / OpenPrintTag     |
 
 ### Troubleshooting
 

+ 1 - 1
spoolbuddy/daemon/main.py

@@ -124,7 +124,7 @@ async def nfc_poll_loop(config: Config, api: APIClient, shared: dict):
             # Check for pending write command
             pending = shared.get("pending_write")
             if pending and nfc.state == NFCState.TAG_PRESENT:
-                if nfc.current_sak == 0x00:
+                if nfc.current_sak in (0x00, 0x04):
                     logger.info("Executing pending tag write for spool %d", pending["spool_id"])
                     success, msg = await asyncio.to_thread(nfc.write_ntag, pending["ndef_data"])
                     await api.write_tag_result(

+ 2 - 2
spoolbuddy/daemon/nfc_reader.py

@@ -98,7 +98,7 @@ class NFCReader:
         """
         if self._state != NFCState.TAG_PRESENT:
             return False, "No tag present"
-        if self._current_sak != 0x00:
+        if self._current_sak not in (0x00, 0x04):
             return False, f"Not an NTAG (SAK=0x{self._current_sak:02X})"
         if not self._nfc:
             return False, "NFC reader not available"
@@ -205,7 +205,7 @@ class NFCReader:
 
                 # Try reading Bambu tag data
                 tray_uuid = None
-                tag_type = "mifare_classic" if sak in (0x08, 0x18) else "ntag" if sak == 0x00 else "unknown"
+                tag_type = "mifare_classic" if sak in (0x08, 0x18) else "ntag" if sak in (0x00, 0x04) else "unknown"
 
                 if sak in (0x08, 0x18):
                     blocks = self._nfc.read_bambu_tag(uid_bytes)