concept(applications): SpoolEase integration — NFC hardware ↔ Spoolman sync#11
Draft
akira69 wants to merge 1 commit intobase/upstream-masterfrom
Draft
concept(applications): SpoolEase integration — NFC hardware ↔ Spoolman sync#11akira69 wants to merge 1 commit intobase/upstream-masterfrom
akira69 wants to merge 1 commit intobase/upstream-masterfrom
Conversation
This branch holds the concept PR for integrating SpoolEase (NFC hardware Console + Scale) with Spoolman's Application framework. See PR description for full design spec including: - SpoolEase API surface analysis - Data ownership boundary design (4-point spec) - Sync strategy options and open questions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is a concept PR — no implementation code yet. It documents the full problem space, landscape of existing solutions, justification for building within Spoolman, and a concrete implementation plan for a Hardware Scale + NFC Sync Application within the Applications Framework (PR #9).
The primary integration target is SpoolEase, but the design is hardware-agnostic — the same Application framework can host adapters for SpoolEase, FilaMan (original ESP32), and future scale/NFC devices.
1. The Problem
Spoolman is excellent at tracking filament inventory but has no mechanism for automatically receiving weight updates from physical hardware. Every user with a scale today must manually weigh spools and type numbers into the UI. This is friction that directly determines whether a user bothers keeping their inventory accurate at all.
The ecosystem has produced several hardware projects that solve the physical measurement problem (scale + NFC tag) but each one deals with the Spoolman integration differently:
SPOOLMAN_DEBUG_MODE=TRUEto disable CORS (a workaround, not a solution)This PR proposes solving that from the Spoolman side: a Device Sync Application that gives hardware devices a well-designed, authenticated, first-party sync endpoint.
2. The Ecosystem — What's Already Out There
2.1 SpoolEase (yanshay/SpoolEase, 451 ⭐)
ESP32 Console + Scale. NFC read/write. Bambu AMS via MQTT. Local web server. Open source (Apache 2.0 + Commons Clause).
Integration status: SpoolEase Issue #43 ("Add integration with spoolman") was opened June 2025 and closed
wontfixOctober 2025. yanshay's objections were all valid from SpoolEase's perspective:None of those objections apply when Spoolman implements the integration — Spoolman owns the code, and SpoolEase doesn't need to change a line.
How this PR addresses yanshay's issue Donkie#43 concerns directly:
A future action: comment on SpoolEase issue Donkie#43 once P2 is working, referencing the implementation as a full resolution.
2.2 SpoolEase API — Encryption Analysis
SpoolEase's web API encrypts payloads using AES-256-GCM (main API) and AES-256-CTR with HMAC-SHA256 (captive portal API). This is NOT security through obscurity — it's real cryptography — but it is fully open-source and implementable in Python.
The
yanshay/esp-hal-appframework (MIT licensed) contains completeencrypt()/ctr_encrypt()/derive_key()implementations. Python equivalents using thecryptographylibrary are a straightforward port of ~50 lines.There is also a fixed key mechanism:
/api/fixed-key-configallows the user to set a persistent key on the device (stored across reboots)There is also precedent for plaintext access:
/insecure/screenshot?key=endpoint already ships in SpoolEase — yanshay already considered programmatic access via plain URL key auth/insecure/spools?key=feature request to yanshay a natural extension of existing design thinkingQ1 resolution: The encryption is not a deal-breaker. Implementation path:
cryptographylibrary + the fixed key as the API secretGET /insecure/spools?key=since the/insecure/pattern already exists in his codebase2.3 FilaMan Original (ManuelW77/Filaman, 169 ⭐, ARCHIVED)
DIY ESP32 firmware (HX711 load cell + PN532 NFC + OLED). Directly called Spoolman REST API from the device. No longer developed.
What FilaMan proved: The
sm_id-on-tag →PUT /api/v1/spool/{id}/withremaining_weightloop works at production quality. This is exactly the loop this integration Application formalizes.ManuelW77 commented in Spoolman PR #605 about CORS, and Stothed775 echoed it: "would be great to use filaman without debug mode." PR Donkie#605 (merged Jun 2025) added
SPOOLMAN_CORS_ORIGIN— FilaMan was the direct driver.2.4 FilaMan-System (Fire-Devils/filaman-system, 23 ⭐, Very actively developed)
A standalone inventory management system — FastAPI + Astro frontend + Docker. A Spoolman competitor, not a companion.
What FilaMan-System proves: the problem is real enough that ManuelW77 built an entire alternative inventory system around it. Their
spoolman-importendpoint shows users migrate from Spoolman — validating that Spoolman users are the natural audience.How this PR changes the FilaMan-System story: A Device Sync Application in Spoolman removes the primary reason users would migrate away, and makes the FilaMan-System-ESP32 hardware usable with Spoolman directly (same Device Token pattern).
3. Why Implement Within Spoolman (Not as External Tool)
SPOOLMAN_DEBUG_MODE=TRUE.4. Implementation Plan — Spoolman-Side Device Sync Application
4.1 Best Reference Codebases
Primary reference: Original FilaMan (
ManuelW77/Filaman, MIT)spool_idfrom NFC tag →remaining_weight = measured_weight - empty_spool_weight{"sm_id": "123", "color": "#...", "type": "PLA", "brand": "..."}Secondary reference: FilaMan-System Device API (
Fire-Devils/filaman-system, MIT)POST /api/v1/devices/scale/weightwithtag_uuid+measured_weight_g→remaining_weight_gAuthorization: Deviceheader pattern — embeddable, no session complexityTertiary reference: SpoolEase encryption framework (
yanshay/esp-hal-app, MIT)derive_key()/ctr_encrypt()/ctr_decrypt()— direct starting point for Python portScaleConfigDTO.key— static key pattern for the external scale, reusable as API secret model4.2 Tare Weight Source — Three-Level Fallback
remaining_weight = measured_weight − tare_weight. Spoolman's data model provides three levels of tare:Spool.spool_weightFilament.spool_weightVendor.empty_spool_weightResolution: Walk levels 1→3. If all three are
None, reject the weight update and return an error requiring the user to fill in a spool weight before linking the spool to a device. No silent failures or guessing.Q3 resolution: Tare weight is fully covered by existing Spoolman data model. The weight hardware (SpoolEase scale) provides only the raw measurement — Spoolman owns the tare calculation using its own vendor/filament/spool data. This is the correct data ownership boundary.
4.3 Device API — New Endpoints
Device Token scope: Tokens are Application-scoped — they may only call Device Sync endpoints. A compromised device token cannot read or modify spool data beyond what the weight endpoint expresses. Q2 resolved: per-Application tokens.
4.4 Weight History
Every successful weight update is logged:
Policy: last-write-wins on
remaining_weightfor the actual Spoolman spool record. The full measurement history is preserved inweight_sync_logfor auditing and future "usage graph" features.Q5 resolved: Timestamped log with device_id, retained indefinitely in the Application DB.
4.5 NFC Tag Link Storage
Option A — Extra Field (no schema changes, independent of PR Donkie#880):
nfc_tag_uidextra field key stored on the Spoolman spool recordextra = {"nfc_tag_uid": tag_id}to resolve tag → spoolOption B — Sibling Application sharing with PR Donkie#880:
tag_uid_to_spool()resolution serviceQ4 resolution: Use Option A for P2 (no dependency on PR Donkie#880 merge). PR Donkie#880 becomes a sibling NFC Application — the two Applications will share a common NFC lookup utility once PR Donkie#880 lands. The Common Fields Library (PR #10) will provide the
nfc_tag_uidextra field template.5. Data Ownership Boundary Design
(a) Linking — NFC Tag UID as Shared Key
Three workflows to establish the link:
nfc_tag_uidextra field saved to spool(b) Field Locking
Once linked, hardware-managed fields become read-only markers in the Spoolman UI:
remaining_weightcolor_hex,material,brandfirst_used,last_usedlocation,commentOverride: "Unlink / Take ownership" action unlocks all fields.
(c) Tare Weight Requirement Enforcement
Before a spool can be linked to a device for weight sync, Spoolman validates that a tare weight is available (checking the three-level fallback). The UI prompts the user to fill in
spool_weightorfilament.spool_weightif none is found. This is a one-time setup step, not ongoing friction.(d) Sync Methods
POST /weightafter each weighing — immediate, low overheadcryptographylibrary port of SpoolEase'sctr_encrypt/ctr_decryptGET /insecure/spools?key=(precedent:/insecure/screenshotalready exists)6. Target Hardware / Integration Roadmap
/insecure/precedent in codebase/weightwith Device Token7. How This Changes the Community Conversations
SpoolEase issue Donkie#43 (wontfix)
Once P2 delivers a working weight endpoint: comment on yanshay/SpoolEase#43 showing that Spoolman provides a Device Token endpoint SpoolEase can call with a single HTTPS POST, plus a Python implementation of the AES-256-CTR layer for the pull direction. No changes needed on SpoolEase's side.
Spoolman Discussion Donkie#629 (FilaMan companion device)
ManuelW77 introduced FilaMan here in Feb 2025. With FilaMan now archived and FilaMan-System having pivoted away, Discussion Donkie#629 has no resolution. This PR gives the Spoolman-native answer.
Spoolman PR Donkie#605 (CORS origin variable)
The Device Token auth pattern makes the CORS workaround unnecessary for registered devices. A registered device's calls are pre-authorized — no
SPOOLMAN_DEBUG_MODE=TRUEor manual CORS configuration.FilaMan-System
spoolman-importendpointFilaMan-System users can keep Spoolman as home inventory and use FilaMan-System-ESP32 hardware via the same Device Token pattern, reducing migration pressure.
Q6 resolved: All outreach deferred until P2 delivers a working implementation. Then comment on the three locations above in one coordinated update.
8. Implementation Phases
POST /weightendpoint, tare three-level fallback, Extra Field tag link,weight_sync_logNote for PR #9 — Navigation Hierarchy
Application configuration in PR #9 (Applications Framework) should include a per-Application toggle controlling where the Application surfaces in the sidebar navigation:
This toggle should be set by the Application author at registration time, with an optional instance-admin override. This allows Hardware Sync, once stable, to graduate to top-level visibility without a structural refactor.
9. Open Questions — Status
/insecure/endpoint precedent for cleaner future path.Spool.spool_weight→Filament.spool_weight→Vendor.empty_spool_weight. Reject (not silently fail) if all null.nfc_tag_uidExtra Field for P2; PR Donkie#880 becomes sibling Application sharing lookup utilityweight_sync_logtable (device_id + timestamp + measured + tare + remaining)10. Relationship to Other PRs
nfc_tag_uid,spoolease_id,spoolease_console_url,spoolease_fixed_keyextra field templatesReferences