nfc2klipper/README.md
Sebastian Andersson b0c58fca13
Update README.md
Update description of link to https://github.com/ryanch/openprinttag_scanner
2026-02-16 10:59:08 +01:00

322 lines
11 KiB
Markdown

<!--
SPDX-FileCopyrightText: 2025 Sebastian Andersson <sebastian@bittr.nu>
SPDX-License-Identifier: GPL-3.0-or-later
-->
[![REUSE status](https://api.reuse.software/badge/github.com/bofh69/nfc2klipper)](https://api.reuse.software/info/github.com/bofh69/nfc2klipper)
![GitHub Workflow Status](https://github.com/bofh69/nfc2klipper/actions/workflows/pylint.yml/badge.svg)
# nfc2klipper
<p>
Automatically sets the loaded spool &amp; filament in klipper by using NFC/RFID tags.
<img align="right" src="images/nfc_reader_on_voron.jpg" width="200" height="158" alt="NFC Reader on Voron" />
</p>
- Table of Contents
- [Prepare for running nfc2klipper](#prepare-for-running-nfc2klipper)
- [Preparing an NFC reader](#preparing-an-nfc-reader)
- [PN532 bug in the nfcpy module](#pn532-bug-in-the-nfcpy-module)
- [Preparing klipper](#preparing-klipper)
- [Preparing the slicer](#preparing-the-slicer)
- [Preparing tags](#preparing-tags)
- [Using tag's id](#using-tags-id)
- [SPOOL & FILAMENT in tags](#spool--filament-in-tags)
- [Write tags with the web server](#write-tags-with-the-web-server)
- [Write with an app](#write-with-an-app)
- [Write with console application](#write-with-console-application)
- [Run automatically with systemd](#run-automatically-with-systemd)
- [Automatic upgrades with moonraker](#automatic-upgrades-with-moonraker)
- [Use with Happy-Hare](#use-with-happy-hare)
- [Use with Prusa's OpenPrintTag tags](#use-with-prusas-openprinttag-tags)
- [Use with OpenTag3D tags](#use-with-opentag3d-tags)
- [Related projects](#related-projects)
- [Developer info](#developer-info)
## Prepare for running nfc2klipper
Install python >= 3.9.
On some distributions you may need to install "python3-venv" or
something similar.
In the cloned repository's dir run:
```sh
python3 -m venv venv
venv/bin/pip3 install -r requirements.txt
```
Copy and update `nfc2klipper.cfg` to `~/.config/nfc2klipper/nfc2klipper.cfg`.
You can specify a custom configuration directory using the `-c` or `--config-dir` command-line option:
```sh
venv/bin/python3 nfc2klipper_backend.py -c /path/to/config/directory
```
## Preparing Spoolman
nfc2klipper can use RFID/NFC tags containing its own format, but
it can also use tags in other formats, like tags for
Filaman, OpenTag3D and probably many others.
For it to be able to use other tag formats, the spool needs to have
an extra `nfc_id` field (just like FilaMan). Add it in Spoolman under
settings -> extra fields -> spool.
## Preparing an NFC reader
I use a PN532 based reader (Elechouse PN532 NFC RFID Module V3, if you
want to use the same) connected via UART to the raspberry pi where this
program is running.
Many pages suggest connecting its VCC pin to 5V on the RPi. Don't!
It can run from 3.3V and then it won't risk slowly destroying the RPi's
GPIO pins.
See [here](https://learn.adafruit.com/adafruit-nfc-rfid-on-raspberry-pi/pi-serial-port)
for how to configure a raspberry pi for it (but change VCC pin...).
Run `sudo rpi-update` to avoid problems with older firmware on the pi.
There is a model for attaching it to the printer
[here](https://www.printables.com/model/798929-elechouse-pn532-v3-nfc-holder-for-voron-for-spoolm).
### PN532 bug in the nfcpy module
When running it on a raspberry pi's mini-uart (ttyS0 as device), it works fine.
When using the other UART (ttyAMA0), I can only run the programs once.
I have to power cycle the PN532 to get them to run again. Just rebooting
the pi doesn't help.
This seems to be due to a bug in nfcpy (version 1.0.4),
see (https://github.com/nfcpy/nfcpy/issues/186).
A workaround that works for me is to change
`venv/lib/python3.*/site-packages/nfc/clf/pn532.py`
around line 390, from:
```python
change_baudrate = True # try higher speeds
```
to:
```python
change_baudrate = False # try higher speeds
```
There is an included patch file that can be applied:
```sh
patch -p6 venv/lib/python3.*/site-packages/nfc/clf/pn532.py < pn532.py.patch
```
## Preparing klipper
When a tag has been read, it will send these gcodes to Klipper:
* `SET_ACTIVE_FILAMENT ID=n1`
* `SET_ACTIVE_SPOOL ID=n2`
See [klipper-spoolman.cfg](klipper-spoolman.cfg) for the klipper
config for them. Klipper must also have a `[save-variables]` section
in its config, see
[Klipper's documentation](https://www.klipper3d.org/Config_Reference.html#save_variables).
## Preparing the slicer
For every filament, add a custom start gcode that calls:
`ASSERT_ACTIVE_FILAMENT ID=<id>`
where `<id>` is its filament id in Spoolman.
This can be done automatically by using [spoolman2slicer](https://github.com/bofh69/spoolman2slicer).
## Preparing tags
Tags can either contain custom data for nfc2klipper, or the tags'
id can be used to lookup the spool in Spoolman.
The first method allows the system to work even if spoolman isn't
working for the moment, but without Spoolman it might be of limited value.
The second method allows nfc2klipper to be used with
[FilaMan](https://github.com/ManuelW77/Filaman) and with manufacturers'
tags of different formats.
## Runing the backend
Run `nfc2klipper_backend.py`.
See further down for running it as a systemd service.
`nfc2klipper.py` is only there for backwards compability and making
development easier.
### Using tag's id
The latest read tags' identifier can be set in the Spool record in Spoolman via the web
server's page, click on the "Set in Spoolman" button for the spool that's loaded.
That way the tag will be connected to that spool without having to change its data.
It will also make the spool connected in FilaMan.
### SPOOL & FILAMENT in tags
The tags should contain an NDEF record with a text block like this:
```
SPOOL:3
FILAMENT:2
```
The numbers are the id numbers that will be sent to the macros in
klipper via the [Moonraker](https://github.com/Arksine/moonraker) API.
#### Write tags with the web server
`nfc2klipper_api.py` can be run as a (WSGI) web server with for example
[Gunicorn](https://gunicorn.org). It will then serve a web page for
writing to the tags or setting the spool's id in Spoolman, like FilaMan does.
Please note that nfc2klipper does not implement any authentication, so
only run this on secure networks, or add reverse proxy (like nginx)
with some authentication. Follow the link above for Gunicorn's
documentation.
To run it with **little security**;
```sh
gunicorn --bind localhost:5001 nfc2klipper_api:app
```
Change localhost to your computer's hostname (or IP-address) if it should server
the whole network.
One can also start the file directly, but then it uses a development
web server with **no security** at all (if enabled in the configuration file).
The program uses the configuration file (`~/.config/nfc2klipper/nfc2klipper.cfg`) for
getting the unix domain name used to communicate with the `nfc2klipper_backend.py`.
The web page lists the current spools in Spoolman.
By pressing the "Write" button, its info is written to the nfc/rfid tag.
By pressing the "Set in Spoolman" button, the tag's id is stored in
an extra field for the spool in Spoolman.
#### Write with an app
There is an Android app, [Spoolman Companion](https://github.com/V-aruu/SpoolCompanion), for writing
to the tags.
#### Write with console application
The `write_tags.py` program fetches Spoolman's spools, shows a simple
text interface where the spool can be chosen, and when pressing return,
writes to the tag.
Use the `write_tag` script to stop the nfc2klipper service, run the
`write_tags.py` program and then start the service again after.
## Run automatically with systemd
Copy `nfc2klipper_backend.service` to `/etc/systemd/system`, then run:
```sh
sudo systemctl start nfc2klipper_backend
sudo systemctl enable nfc2klipper_backend
```
To see its status, run:
```sh
sudo systemctl status nfc2klipper_backend
```
To run the web server, copy `nfc2klipper_api.service` to
`/etc/systemd/system`, then run:
```sh
sudo systemctl start nfc2klipper_api
sudo systemctl enable nfc2klipper_api
```
To see its status, run:
```sh
sudo systemctl status nfc2klipper_api
```
## Automatic upgrades with moonraker
Moonraker can be configured to help upgrade nfc2klipper.
Copy the `moonraker-nfc2klipper.cfg` file to the same dir as where
`moonraker.conf` is. Include the config file by adding:
```toml
[include moonraker-nfc2klipper.cfg]
```
## Use with Happy-Hare
(This is completly untested by me, please let me know if it works or not)
Change the `setting_gcode` value in nfc2klipper.cfg to:
```gcode
MMU_GATE_MAP NEXT_SPOOLID={spool}
```
See Happy-Hare's [documentation](https://github.com/CooperGerman/Happy-Hare/wiki/Spoolman-Support#auto-setting-with-rfid-reader)
## Use with Prusa's OpenPrintTag tags
The PN532 reader can not read NFC type 5 tags. A newer reader, like PN5180, is needed, but there is limited python support for using it.
That reader requires a SPI bus plus at least one more pin, preferably four more. I don't have that many pins free on my RPi.
IF I add support for it, I will probably connect it to a RPi Pico instead and then connecting them to the computer via USB.
## Use with OpenTag3D tags
(This is not tested with real tags. Please open an issue if it works or not).
[OpenTag3d](https://opentag3d.info/) is a tag format containing info about the spool and filament.
nfc2klipper can read the format (v0.12, possibly later), create vendor, filament and spool records in Spoolman from the tag's data.
The Filament's name is by default generated from the tag's `material_base` `material_mod` and `color_name` fields.
That can be changed in the configuration file.
The created spools and filaments in spoolman gets the data from the tag. Which tag's data field should end up in which spoolman field
is also configurable.
See Spoolman's API documentation [here](https://donkie.github.io/Spoolman/) to see the names of the fields in Spoolman.
You can also add extra fields in Spoolman for saving the data from the OpenTag3D tags.
## Related projects
* [FilaMan](https://www.filaman.app/) - a filament management system.
* [esp_to_spoolman](https://github.com/dimbas80/esp_to_spoolman) - like nfc2klipper, but running on an ESP32.
* [OpenPrintTag Scanner](https://github.com/ryanch/openprinttag_scanner) - like esp_to_spoolman, but with display and for PrusaLink instead of Klipper.
* [spool2klipper](https://github.com/bofh69/spool2klipper) - to set the filament id (and other data) when the spool id is changed.
* [spoolman2slicer](https://github.com/bofh69/spoolman2slicer) - create filament config from Spoolman.
* [OpenTag3d](https://opentag3d.info/) tag format.
## Developer info
Pull requests are happily accepted, but before making one make sure
the code is formatted correctly and linted without errors.
Format the code by running `make fmt` and lint it with `make lint`.
Python types are used. Check them with `make typecheck`
Add copyright info in SPDX format in new files and check that it is correct with `make reuse`.