Add support for writing RFID tags#156
Conversation
|
That is crazy :) I'm currently on holidays will review this in a few days, as there's a number of changes. How you also intend to guide user to write both sides of spool? |
I have been thinking about that. Currently I'm thinking to do the "simple" thing and have a prompt for the user to confirm/dismiss any time they write a tag saying they should update the other side as well. That will also likely necessitate adding a "clone" functionality of some sort. That being said, I'd prefer to add those in as a separate pr, and focus on getting these changes in (with your feedback on what is here now), as the pr already is pretty large. |
| FILAMENT_DT_CONFIG_FILE = "filament_detect.json" | ||
|
|
||
| +# Material density defaults (g/cm³) for tag writing | ||
| +MATERIAL_DENSITIES = { |
There was a problem hiding this comment.
what about mathicing Orca's material list here:
https://github.com/OrcaSlicer/OrcaSlicer/blob/b93112c67431d2cb962f2b6b7ad21fb13989119e/src/libslic3r/MaterialType.cpp#L92
But in all honesty, considering the variety of offerings on the market, locking the materials to a list might fall short pretty quickly
There was a problem hiding this comment.
These are defaults only, the user writing the tag will always be able to specify whatever they want, but pulling in a more extensive table isn't a bad idea either.
As a V1 of this feature which looks great btw .. Id imagine anyone, like me, would not find dealing with a prompt a hardship at all. Way easier than messing around with phone apps. wrt to clone would be nice to have a list of saved tags to select from, simple json file written to the fs when a new tag is created. Hope this makes it in, excited :D ... |
This is more about one's personal process than anything. For instance, I add spools to my spoolman instance as I buy them, when they come in, I already have the 2 tags ready and just stick them ont the spool, and I'm done with it. For me is an easier and smoother process than having to flip the spool on the printer just to tag it. |
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>RFID Tag Manager - Snapmaker U1</title> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css"> |
There was a problem hiding this comment.
I love the feature! I would recommend to put the two external css and js files locally on the printer to be able to use it in offline environments
Yeah, there are three things I wanted to accomplish with this. First was to get filament write support in general into the firmware, as it unlocks a lot more than just a web ui. Second was I wanted to get more rfid data into the firmware at an accessible place (like the uid) as that also unlocks more automation potential (such as spoolman integration for snapmaker native rfid tags). The web ui was more a of convenience feature for me than anything else, as it makes iteration quicker, since I don't need to be at the printer to update tags, and since I have an iphone, there isn't (yet) a dedicated way to write openspool tags. I've used generic tag writing apps on iphone, but so far I haven't found one that I like. The important thing to me is to make it easier to use rfid tags, and to make them more useful in general. Whatever changes are made, they shouldn't force somebody into a particular workflow, but should hopefully make that workflow easier at some point. |
|
Snapmaker filaments "integration" and tracking in spoolman is potentially done here: https://github.com/unlucio/SnapmakerU1-Extended-Firmware/blob/spoolman/docs/spoolman.md#properly-tagged-spools if/when this PR will land #163 I indeed plan to integrate it wiht your code to allow further automations for those that want them. PS: since there are quite a few people working on the material topic, I invited you to a chat in Discord about it. |
Thanks, we should definitely coordinate on an overall plan for this, so we don't all just keep doing the same work over and over again. |
|
All of this sounds fantastic. Is there a way to write to the tag the "used filament amount" for tracking purpose? |
Yah fair enough, I'm coming in cold and don't have a process nailed yet. Feels like it should be easier :) |
@kman3d, There is separate filament tracking support a few of the community are working on right now. Because there are nominally two tags per filament spool, its not so simple as writing the amount of used filament to the tag. Its not to say that wouldn't necessarily be useful information to have on it, but it cannot be the sole source of truth. Anyway, regardless of "how", I do expect to see some decent filament tracking coming before too long |
It can get quite unreliable pretty quickly. The only case it doesn't get unreliable is if you never move the spool from its holder (or at least the same side) from when it's new to when it's finished, and most of all: you never use it on other printers |
|
@Lemmons The idea is great. I would do the following changes:
As for the UI
This also means that UI would parse the Snapmaker U1 internal data structures. But I think this is fine, as we really then introduce pretty much web app. Please take a look also at the: #236. |
|
@paxx12 Awesome. Thanks. I'll see if I can get those changes made in the next day or two. |
dc330c3 to
4db586d
Compare
|
@paxx12 I had to do a pretty major rework of it, but I believe I have incorporated the changes requested. I'll post some new screenshots before too long of what the new ui looks like. |
|
@Lemmons Awesome |
✅ Build ArtifactsVersion:
|
|
@paxx12 I updated the pr description with the updated screenshots. There are still a few rough edges (such as the code currently not being able to tell the difference between an empty tag and an invalid/corrupted tag), but I think we can deal with those later. |
|
@Lemmons we need to think how to connect those also with @suchmememanyskill changes. I think probably |
✅ Build ArtifactsVersion:
|
|
Yeah, adding in the gcode should be enough. Although currently my filament detection system cannot write. Can see if i can implement that. |
|
@Lemmons I'm thinking that the best would be to drop all special handling of OpenSpool from firmware, just expose raw command to write data to tag. So, make I have my own |
✅ Build ArtifactsVersion:
|
That sounds reasonable. Would make it a bit more flexible to any tag type. |
✅ Build ArtifactsVersion:
|
✅ Build ArtifactsVersion:
|
8bb8526 to
1137955
Compare
✅ Build ArtifactsVersion:
|
| error, records, card_uid, cc_bytes = ndef_parse(data_buf) | ||
|
|
||
| # Expected NTAG215 CC: E1 10 3F 00 (NDEF magic, v1.0, 504 bytes, read/write) | ||
| # Expected NTAG216 CC: E1 10 6D 00 (NDEF magic, v1.0, 872 bytes, read/write) |
There was a problem hiding this comment.
other parts of the code don't support ntag216, but it won't hurt anything here.
|
@paxx12 I think this is read for review, if you don't have any other changes you'd like to see |
✅ Build ArtifactsVersion:
|
|
one item of potential discussion, I used urlsafe base64 encoding for the raw tag data payload in the gcode command, but I'd be find changing it to HEX, this is more of a "technically its more efficient during transmission" decisions which was unneeded. |
paxx12
left a comment
There was a problem hiding this comment.
I have some initial questions. I did not yet run this myself to test exactly how it behaves.
Random thought:
This is very interesting project, it just asks if it has to be part of this repo, or could it be managed externally.
I'm starting to think if this would not be better suited to be connected with filament-detect together and built to provide its own interface and actually provide the UI for that project.
This way both, would be treated as external dependency.
| @@ -0,0 +1,26 @@ | |||
| Including: home/lava/klipper/klippy/extras/filament_detect.py | |||
| --- rootfs.original/home/lava/klipper/klippy/extras/filament_detect.py 2026-01-19 20:46:51.443456566 +0000 | |||
| +++ rootfs/home/lava/klipper/klippy/extras/filament_detect.py 2026-02-08 22:00:00.000000000 +0000 | |||
There was a problem hiding this comment.
It seems it would be better to merge this change with prior patch, since this now creates patches that has to run in a specific sequence.
There was a problem hiding this comment.
yeah, I wasn't sure what the preference was for these sort of changes, but I'm fine with that.
| # NTAG tag write/erase operations | ||
| # Provides gcode commands for writing and erasing NTAG filament tags | ||
|
|
||
| [filament_tag] |
There was a problem hiding this comment.
I would likely add this as a klipper tweak, feature that has to be explicitly enabled.
| if len(data) > 12 and data[0] != 0xE1: | ||
| for i in range(min(16, len(data) - 4)): | ||
| if data[i] == 0xE1 and (data[i+1] == 0x10 or data[i+1] == 0x11 or data[i+1] == 0x40): | ||
| if (data[i] & 0xE1) == 0xE1 and (data[i+1] & 0x10) == 0x10: |
There was a problem hiding this comment.
Seems that only this change is required in this file? Correct as this improved ndef parsing? Can we drop all rest of changes? Can we put this change in separate commit?
| def _ensure_cc_bytes(self, channel, info): | ||
| """Ensure CC bytes (page 3) are correct for an NTAG tag. | ||
|
|
||
| CC is OTP (One-Time Programmable): hardware performs new = old | written, |
There was a problem hiding this comment.
Interesting. Forbid my ignorance, but can we erase the tag to write it next without performing this form of re-detect?
There was a problem hiding this comment.
yeah. This is mainly just to make sure that the CC bits are set to the expected values, and raise a warning if not. My understanding is that they should generally be set to the correct values by the manufacturer, but I haven't had a chance to go through and look at it in too much detail. When I was initially playing around with writing tags I corrupted the CC bits of a few of them, which lead me down a bit of a rabbit hole. A bit of the CC between both extras files can likely be cleaned up a bit, but likely a decent amount of it can be cleaned up, or regulated to more generic warning logs rather than method outputs, etc.
There was a problem hiding this comment.
definitely doesn't need to be done when erasing/rewriting an existing good tag.
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>RFID Tag Manager - Snapmaker U1</title> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css"> |
There was a problem hiding this comment.
I would really want to avoid external dependencies. Is this required? Or can we generate a minimal CSS?
There was a problem hiding this comment.
this is just the color picker. The native color picker doesn't have transparency support, and I wanted to be able to support a color picker with transparency. It would not be too difficult to just write a color picker with transparency support ourselves though.
| @@ -0,0 +1,164 @@ | |||
| <!DOCTYPE html> | |||
There was a problem hiding this comment.
@Lemmons I think we need to test this after enabling the Web Authentication. Can you take a look at auth.js use in firmware-config and remote-screen to read, inject bearer token and show when the authentication required?
There was a problem hiding this comment.
Sounds good. Auth actually is one my specialties😅
| [submodule "deps/screen-apps"] | ||
| path = deps/screen-apps | ||
| url = https://github.com/paxx12/screen-apps.git | ||
| [submodule "deps/PrintTag-Web"] |
There was a problem hiding this comment.
I'm still debating with myself about submodules or cache_git.sh.
There was a problem hiding this comment.
Personally, I really don't like submodules, but usually when I've used them it's in large, complex repos, where they wreak havoc. Here I'm happy to do whatever.
Yeah, the further along it has gotten, I'm starting to think the same. That said, I don't know how much more time I can realistically put into it. With that though, I want to see it in front of people and making the filament tagging ecosystem better, so for that reason alone I'd really like to see it to some form of completion. @suchmememanyskill should I pivot this to support your filament_detect project instead? I could first port the tag writing logic over, and then we could put the UI as a front end for the project? |
- Replace unversioned CDN links for Pickr with pinned local copies (v1.9.1 with SHA256 verification via cache_file.sh) so the UI works fully offline and builds are reproducible. - Switch PrintTag-Web from a git submodule to cache_git.sh at a pinned SHA (2e2d831), matching the pattern used by every other third-party dependency in this repo and removing the need to init submodules. - Add auth.js (shared from 99-remote-screen) to the rfid-manager page; fetch a Moonraker oneshot token before opening the WebSocket so the UI works correctly when force_logins is enabled. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
I've been building with and running this on my local hackjob branch and it's fantastic. Trying to write during a print will crash the printer currently. Needs this in 2 places in filament_tag.py to prevent arithmetic with None inside get_status |
|
It would be fantastic to have this incorporated, since no matter how many different aproaches I've tested each is lacking across usability, spoolman integration, tag operability with U1, etc. I don't see currently any pipeline that allows both filament quantity tracking, tag read and write as well as U1 tag reliable pickup. |
|
I've ran out of time to push this forward. I'd be happy if anyone wanted to take it over and get it over the finish line. |
d4be507 to
83fc480
Compare
|
I did rebase this on top of |
✅ Build ArtifactsVersion:
|
* Includes GCODE and a webui for tag management update readme a few more doc updates DRY out default density definitions They still are defined in the javascript as well as python, but at least now its only once in the python code Improve `RFID` troubleshooting steps (paxx12-snapmaker-u1#289) Update ntag writing support to use a urlsafe base64 encoded binary blob of raw data This will allow the write command to support various different data formats. remove file header remove unneeded extra uid parse logic Correctly handle CC bytes Warn if the bytes look off and aren't correctable. use cc values from filament_tag.py
…lors` Replaces the flat `color_hex`/`color2`-`color5` fields with `first_color` (a hex string) and `additional_colors` (an array of hex strings). The array is built from `RGB_2`–`RGB_5` sliced to `COLOR_NUMS - 1` entries, so the tag's declared color count is respected. All consumers (rendering, `populateWriteForm`, export) are updated accordingly.
83fc480 to
ab62fda
Compare
✅ Build ArtifactsVersion:
|
✅ Build ArtifactsVersion:
|
Web ui and apis runs as part of moonraker, accessible at http://{u1-hostname/ip}/rfid. Includes all rfid fields supported in v1.0.0. Also adds new new GCODE commands to support the web UI functionality. The web UI also contains an export and import tag functionality for ease of cloning/backing up tags, etc.
UI General Look
Empty and Missing Tag support
Properly shows when a tag is empty or has an error vs missing.


Mobile Browser Support
Also renders and works well on a mobile browser.

Snapmaker Native Tags
Native Snapmaker filament tags are support for reading, but not writing or erasing. The UI prevents submitting, and the api also rejects requests to modify them.