# Control Roon with NFC cards

**URL:** <https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459>\
**Category:** Tinkering\
**Created:** [December 7, 2025, 10:37am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459 "2025-12-07T10:37:17Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 7, 2025, 10:37am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/1 "2025-12-07T10:37:17Z")

</div>

I built a simple system to control Roon with NFC cards. You tap a card on a reader, the album plays.

The idea came from wanting something physical again, like CDs but without the clutter. Any NFC card works - door badges, library cards, even old bank cards.

 ![Capture d’écran 2025-12-07 110127](https://roon-community-uploads.s3.amazonaws.com/original/4X/7/d/5/7d57b3148079bfc51e1a11f01887cffe23d845f2.png)

 ![unnamed](https://roon-community-uploads.s3.amazonaws.com/original/4X/6/6/9/6694a7adc1574101e3eb2c597a5ff544d359c465.jpeg)

**What it does:**

- Associate any NFC card with an album, genre, or playlist
- Web interface to program cards and see what’s playing
- Works on Windows or Raspberry Pi
- Multi-zone support

**Hardware needed:**

- ACR122U NFC reader (~$30) or similar PC/SC compatible
- Any computer or Raspberry Pi

GitHub: [GitHub - CVerde/nfc-roon-controller: NFC Roon Controller - Play albums with physical cards](https://github.com/CVerde/nfc-roon-controller)

Happy to answer questions or get feedback.

---

<div class="post-metadata">

**Author:** ![Alister\_Sibbald](https://community.roonlabs.com/letter_avatar/alister_sibbald/32/5_5575768a8748004e209b776fc1b2916d.png) [@Alister\_Sibbald](https://community.roonlabs.com/u/Alister_Sibbald)\
**Post date:** [December 15, 2025, 8:04pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/2 "2025-12-15T20:04:23Z")

</div>

Bravo Cyril!

Thank you for this. I’ve just installed it and written my first card. The whole process was extremely simple and flawless. Well done!

This will be a little present for my wife - who hardly plays any music any more as she could never come to terms with the whole “music in the phone” thing.

I thoughtlessly sold my CD player and all my CDs, and since then she hasn’t really been able to use the music system.

I can’t really get the CD player and all the CDs back - but I think this will allow her to begin to enjoy her music again.

Thanks very much.

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 17, 2025, 11:00am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/3 "2025-12-17T11:00:04Z")

</div>

Hello, thank you very much for your feedback. It’s good to know my project was useful to someone. I designed it so my five-year-old son could use it, so in principle it should work for an adult as well!

I spent some time designing a version of the project that sends album artwork to a small secondary screen. But now that’s finished, I’ll resume development of the main branch.

Are there improvements or additions that would seem interesting to you?

I know the shuffle function doesn’t work very well and I’d really like to be able to implement smart playlists, even if they don’t work in the Roon API.

---

<div class="post-metadata">

**Author:** ![Alister\_Sibbald](https://community.roonlabs.com/letter_avatar/alister_sibbald/32/5_5575768a8748004e209b776fc1b2916d.png) [@Alister\_Sibbald](https://community.roonlabs.com/u/Alister_Sibbald)\
**Post date:** [December 17, 2025, 2:15pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/4 "2025-12-17T14:15:33Z")

</div>

Cyril,

I haven’t used it enough to make many particularly useful comments - but I will once I have. One behaviour I noticed, which was unexpected, was that if you live the NFC card lying on the reader, then it re-starts the song/album of that card every couple of seconds - presumably because it detects the card again.  
It’s not a big deal, but at least the option to leave the card lying on the reader without this happening would be nice. So, if it detects a card and it’s the same card as the one it detected before, it just continues playing. But as I said, not. big deal.

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 17, 2025, 7:53pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/5 "2025-12-17T19:53:19Z")

</div>

Good idea.  
Before implementing a user-selectable cooldown time in the admin interface, I changed the server code so there’s a 3600-second (1-hour) cooldown between scans of the same card to resume playback from that card.  
This only affects “music” cards, not special cards.  
It’s not the most elegant solution in terms of code, but it works.

```auto
     if action == "play" and uid == state.last_uid and (time.time() - state.last_time) < 3600:
            logger.info("Same card scanned again, ignoring")
            return jsonify({"status": "ignored", "message": "same card"})

        state.scan(uid)

```

I’m currently working on the system that generates PDF files of pages to print for making cards (admin interface).  
I’ll soon upload the STL files to GitHub for a small device to easily manufacture custom cards.

 ![CARD-MAKER](https://roon-community-uploads.s3.amazonaws.com/original/4X/e/d/4/ed431b8aaa5c707c0bee652dda1300dac99edb79.jpeg)

---

<div class="post-metadata">

**Author:** ![Alister\_Sibbald](https://community.roonlabs.com/letter_avatar/alister_sibbald/32/5_5575768a8748004e209b776fc1b2916d.png) [@Alister\_Sibbald](https://community.roonlabs.com/u/Alister_Sibbald)\
**Post date:** [December 18, 2025, 3:43pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/6 "2025-12-18T15:43:23Z")

</div>

Cyril, that looks great.

I’ve spent quite a lot of time printing labels for the front and back of standard white NFC cards (credit card size) using Avery 80mm x 50mm glossy white inkjet labels.  
It works fine - it’s just quite labour intensive. So I’m very interested to see what you’re doing with your labelling approach.

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [December 23, 2025, 3:46pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/7 "2025-12-23T15:46:57Z")

</div>

Thank you so much Cyril, this is exactly what I was looking for after Plexamp added the NFC feature.  
Currently struggling with pyscard install (say problem building the wheel on pc and pi) but will search some options

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 23, 2025, 7:10pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/8 "2025-12-23T19:10:11Z")

</div>

The pyscard wheel build issue usually comes from missing dependencies. On the pi, try:

```auto
sudo apt-get install swig libpcsclite-dev pcscd
pip install pyscard

```

If it still doesn’t work, feel free to share the error messages, I can help you troubleshoot.  
Also, the project is still evolving and I’m open to ideas. If you have suggestions or run into use cases I haven’t thought of, let me know!  
What’s your intended NFC reader setup?

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [December 24, 2025, 11:30am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/9 "2025-12-24T11:30:38Z")

</div>

Thank you Cyril for trying to help unfortunately the pi still will not install pyscard. Does seem to be a dependency problem, I just card find it. I will keep trying. The error reports  
swig is already the newest version (4.3.0-1).  
libpcsclite-dev is already the newest version (2.3.3-1).  
pcscd is already the newest version (2.3.3-1).  
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.  
× Building wheel for pyscard (pyproject.toml) did not run successfully.  
ERROR: Failed building wheel for pyscard  
Failed to build pyscard  
ERROR: Failed to build installable wheels for some pyproject.toml based projects (pyscard)

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 24, 2025, 11:04pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/10 "2025-12-24T23:04:59Z")

</div>

Can you share the full build output? The error you posted shows the wheel failed but not why. You can run this to get the log:

```auto
pip install pyscard --no-cache-dir -v 2>&1 | tail -100

```

What Pi model and OS version are you running? Sometimes it’s a compiler issue.

Let me know what you find.

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [December 29, 2025, 9:55am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/11 "2025-12-29T09:55:55Z")

</div>

Thanks for the log command. Its a RPi 3 Model B+ running diet pi. So maybe diet pi is missing the dependencies needed, I will try another system  
Error is  
(venv) root@DietPi:~/nfc-roon-controller# pip install -r requirements.txt  
Looking in indexes: [Simple index](https://pypi.org/simple), [piwheels - Simple index](https://www.piwheels.org/simple)  
Collecting flask\>=3.0.0 (from -r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/flask/flask-3.1.2-py3-none-any.whl](https://www.piwheels.org/simple/flask/flask-3.1.2-py3-none-any.whl) (103 kB)  
Collecting roonapi\>=0.1.6 (from -r requirements.txt (line 2))  
Using cached [https://archive1.piwheels.org/simple/roonapi/roonapi-0.1.6-py3-none-any.whl](https://archive1.piwheels.org/simple/roonapi/roonapi-0.1.6-py3-none-any.whl) (21 kB)  
Collecting websocket-client==1.6.4 (from -r requirements.txt (line 3))  
Using cached [https://www.piwheels.org/simple/websocket-client/websocket\_client-1.6.4-py3-none-any.whl](https://www.piwheels.org/simple/websocket-client/websocket_client-1.6.4-py3-none-any.whl) (57 kB)  
Requirement already satisfied: requests\>=2.28.0 in ./venv/lib/python3.13/site-packages (from -r requirements.txt (line 4)) (2.32.5)  
Collecting pyscard\>=2.0.0 (from -r requirements.txt (line 5))  
Using cached pyscard-2.3.1.tar.gz (160 kB)  
Installing build dependencies … done  
Getting requirements to build wheel … done  
Preparing metadata (pyproject.toml) … done  
Collecting blinker\>=1.9.0 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/blinker/blinker-1.9.0-py3-none-any.whl](https://www.piwheels.org/simple/blinker/blinker-1.9.0-py3-none-any.whl) (8.5 kB)  
Collecting click\>=8.1.3 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/click/click-8.3.1-py3-none-any.whl](https://www.piwheels.org/simple/click/click-8.3.1-py3-none-any.whl) (108 kB)  
Collecting itsdangerous\>=2.2.0 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/itsdangerous/itsdangerous-2.2.0-py3-none-any.whl](https://www.piwheels.org/simple/itsdangerous/itsdangerous-2.2.0-py3-none-any.whl) (16 kB)  
Collecting jinja2\>=3.1.2 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/jinja2/jinja2-3.1.6-py3-none-any.whl](https://www.piwheels.org/simple/jinja2/jinja2-3.1.6-py3-none-any.whl) (134 kB)  
Collecting markupsafe\>=2.1.1 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached markupsafe-3.0.3-cp313-cp313-manylinux2014\_aarch64.manylinux\_2\_17\_aarch64.manylinux\_2\_28\_aarch64.whl.metadata (2.7 kB)  
Collecting werkzeug\>=3.1.0 (from flask\>=3.0.0-\>-r requirements.txt (line 1))  
Using cached [https://www.piwheels.org/simple/werkzeug/werkzeug-3.1.4-py3-none-any.whl](https://www.piwheels.org/simple/werkzeug/werkzeug-3.1.4-py3-none-any.whl) (224 kB)  
Collecting ifaddr\>=0.1.0 (from roonapi\>=0.1.6-\>-r requirements.txt (line 2))  
Using cached [https://www.piwheels.org/simple/ifaddr/ifaddr-0.2.0-py3-none-any.whl](https://www.piwheels.org/simple/ifaddr/ifaddr-0.2.0-py3-none-any.whl) (12 kB)  
Requirement already satisfied: six\>=1.10.0 in ./venv/lib/python3.13/site-packages (from roonapi\>=0.1.6-\>-r requirements.txt (line 2)) (1.17.0)  
Requirement already satisfied: charset\_normalizer\<4,\>=2 in ./venv/lib/python3.13/site-packages (from requests\>=2.28.0-\>-r requirements.txt (line 4)) (3.4.4)  
Requirement already satisfied: idna\<4,\>=2.5 in ./venv/lib/python3.13/site-packages (from requests\>=2.28.0-\>-r requirements.txt (line 4)) (3.11)  
Requirement already satisfied: urllib3\<3,\>=1.21.1 in ./venv/lib/python3.13/site-packages (from requests\>=2.28.0-\>-r requirements.txt (line 4)) (1.26.20)  
Requirement already satisfied: certifi\>=2017.4.17 in ./venv/lib/python3.13/site-packages (from requests\>=2.28.0-\>-r requirements.txt (line 4)) (2025.11.12)  
Using cached markupsafe-3.0.3-cp313-cp313-manylinux2014\_aarch64.manylinux\_2\_17\_aarch64.manylinux\_2\_28\_aarch64.whl (24 kB)  
Building wheels for collected packages: pyscard  
Building wheel for pyscard (pyproject.toml) … error  
error: subprocess-exited-with-error

× Building wheel for pyscard (pyproject.toml) did not run successfully.  
│ exit code: 1  
╰─\> [23 lines of output]  
/tmp/pip-build-env-1z83qpyk/overlay/lib/python3.13/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated.  
!!

```
          ********************************************************************************
          Please consider removing the following classifiers in favor of a SPDX license expression:

          License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)

          See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
          ********************************************************************************

  !!
    self._finalize_license_expression()
  running bdist_wheel
  running build
  running build_py
  running build_ext
  building 'smartcard.scard._scard' extension
  swigging src/smartcard/scard/scard.i to src/smartcard/scard/scard_wrap.c
  swig -python -outdir src/smartcard/scard -DPCSCLITE -o src/smartcard/scard/scard_wrap.c src/smartcard/scard/scard.i
  creating build/temp.linux-aarch64-cpython-313/src/smartcard/scard
  aarch64-linux-gnu-gcc -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -DVER_PRODUCTVERSION=2,3,1,0000 -DVER_PRODUCTVERSION_STR=2.3.1 -DPCSCLITE=1 -Isrc/smartcard/scard/ -I/usr/include/PCSC -I/usr/local/include/PCSC -I/root/nfc-roon-controller/venv/include -I/usr/include/python3.13 -c src/smartcard/scard/helpers.c -o build/temp.linux-aarch64-cpython-313/src/smartcard/scard/helpers.o
  error: command 'aarch64-linux-gnu-gcc' failed: No such file or directory
  [end of output]

```

note: This error originates from a subprocess, and is likely not a problem with pip.  
ERROR: Failed building wheel for pyscard  
Failed to build pyscard  
error: failed-wheel-build-for-install

× Failed to build installable wheels for some pyproject.toml based projects  
╰─\> pyscard

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [December 30, 2025, 8:31pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/12 "2025-12-30T20:31:00Z")

</div>

Got it, the error is clear now: `aarch64-linux-gnu-gcc` is missing. DietPi is minimal by design, so the compiler isn’t included by default.

Try that

```auto
sudo apt-get install gcc build-essential python3-dev

```

after that, run `pip install pyscard` again.  
If gcc still shows as missing after install, you might need to reboot or check that `/usr/bin/gcc` exists.  
Let me know how it goes!

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [January 5, 2026, 9:20am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/13 "2026-01-05T09:20:27Z")

</div>

That was spot on, thanks Cyril. Installed aarch64-linux-gnu-gcc and Pyscard installed just fine.

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [January 7, 2026, 1:30pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/14 "2026-01-07T13:30:53Z")

</div>

good news!

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [January 7, 2026, 1:32pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/15 "2026-01-07T13:32:07Z")

</div>

I implemented Kindle Touch (2012) support for my card reader system to display the currently playing track. The plan is to integrate everything into a small piece of furniture or enclosure. The Kindle Touch hack is fairly specific to this model and my setup, but if anyone’s interested, I could clean up the code and make it available.

 ![unnamed](https://roon-community-uploads.s3.amazonaws.com/original/4X/9/e/4/9e4ad050b7140528a8afc2d9e27a0502c31aebad.jpeg)

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [January 9, 2026, 3:40pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/16 "2026-01-09T15:40:44Z")

</div>

Screen output looks great Cyril, I would certainly give it a try.

I’ve now got a my first 4 cards setup and having fun testing them out.  
1 thing I have noticed is that sometimes cards do not react if the player is already in use. Is this by design so as not to stop the current playback? Or have my cards maybe just not been picked up by the reader

---

<div class="post-metadata">

**Author:** ![Cyril\_Verde](https://community.roonlabs.com/letter_avatar/cyril_verde/32/5_5575768a8748004e209b776fc1b2916d.png) [@Cyril\_Verde](https://community.roonlabs.com/u/Cyril_Verde)\
**Post date:** [January 9, 2026, 3:52pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/17 "2026-01-09T15:52:04Z")

</div>

Glad it’s working!  
There’s a 30-second delay by design. If you scan the same card twice within 30 seconds, the second scan is ignored. This is so you can leave a card on the reader as a visual reference without it restarting the album constantly. But if you’re scanning a different card and nothing happens, that’s not expected. Could be a reader issue.

---

<div class="post-metadata">

**Author:** ![AxelF](https://community.roonlabs.com/letter_avatar/axelf/32/5_5575768a8748004e209b776fc1b2916d.png) [@AxelF](https://community.roonlabs.com/u/AxelF)\
**Post date:** [February 17, 2026, 11:05am UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/18 "2026-02-17T11:05:11Z")

</div>

Love this idea — went down a similar path a while back.

Built some NFC cards to trigger Roon playlists/zones because I missed the haptic side of music control. Started with simple tags, ended up making acrylic printed cards that feel more like physical media.

Tap card → music starts. Surprisingly satisfying 👍

 ![IMG_1930.HEIC](https://roon-community-uploads.s3.amazonaws.com/original/4X/c/a/0/ca01f702d2896608c9eb1b08e6f922abe4d09248.jpeg)

 ![IMG_1931.HEIC](https://roon-community-uploads.s3.amazonaws.com/original/4X/6/5/7/657d228f4a36d7bbfb314c26b99371404e1615e5.jpeg)

---

<div class="post-metadata">

**Author:** ![Matt\_Perry](https://community.roonlabs.com/user_avatar/community.roonlabs.com/matt_perry/32/92446_2.png) [@Matt\_Perry](https://community.roonlabs.com/u/Matt_Perry)\
**Post date:** [February 22, 2026, 12:41pm UTC](https://community.roonlabs.com/t/control-roon-with-nfc-cards/311459/19 "2026-02-22T12:41:22Z")

</div>

This has been so much fun to play around with I decided to integrate my nfc reader into a cd wall display

 ![1000125121](https://roon-community-uploads.s3.amazonaws.com/original/4X/2/5/8/258156f7e3d0cc148a3e307c9c94f266669d6683.jpeg)

 ![1000125123](https://roon-community-uploads.s3.amazonaws.com/original/4X/4/4/d/44d5603f7eba1b3fdaed56d5e7d11732b42faa8c.jpeg)

I removed the nfc reader plastic case and attached it to the back of the display, attached nfc tags and magnets to the cd cases and now the centre cd plays when put in place. Still working on it but working great so far.
