NFC reader with ESP32 instead of RPi?

Hi, I’d love to build something like the Sonos Vinyl Emulator or Music Cards but with ESP32 (as I have a couple of spare ones). I only need the board to send commands to the Home Assistant, I don’t need it to actually play anything. Playback is done through Spotify integration, with Sonos and/or Alexa Echo Dots acting as playback devices.

Or, the second way could be plugging an NFC reader plugged directly into my HA (HAOS) Rpi4, but it being a HAOS system doesn’t allow for running arbitrary code other than Docker containers. Or does the HA NFC feature support USB NFC readers directly?

Does anyone have a working setup like this? Thanks!

I have a setup with an esp32 and the rc522 RFID using ESPHome. The tag reader sends the card ID to HA, which then plays the linked album on a definded sonos speaker.

esphome:
  name: esptag
  platform: ESP32
  board: wemos_d1_mini32

wifi:
  ssid: ****
  password: ***

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32 Tags Fallback Hotspot"
    password: *****

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

# Flashlight CHECK PIN
output:
  - platform: gpio
    pin: GPIO2
    id: gpio_2

light:
  - platform: binary
    output: gpio_2
    name: esptag led

sensor:
  - platform: wifi_signal
    name: esptag wifi signal
    update_interval: 60s
 
  - platform: uptime
    name: esptag uptime

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

rc522_spi:
  cs_pin: GPIO5
  on_tag:
    then:
      - homeassistant.tag_scanned: !lambda 'return x;'

- id: handle_tag_scan
  alias: Handle Tag Scan
  trigger:
  - platform: event
    event_type: tag_scanned
  condition:
  - condition: template
    value_template: '{{ trigger.event.data.tag_id in tags }}'
  - condition: template
    value_template: '{{ trigger.event.data.device_id in media_players }}'
  action:
  - variables:
      media_player_entity_id: '{{ media_players[trigger.event.data.device_id] }}'
      media_content_id: '{{ tags[trigger.event.data.tag_id].media_content_id }}'
      media_content_type: '{{ tags[trigger.event.data.tag_id].media_content_type }}'
  - service: media_player.play_media
    target:
      entity_id: '{{ media_player_entity_id }}'
    data:
      media_content_id: '{{ media_content_id }}'
      media_content_type: '{{ media_content_type }}'
  - delay: 2
  mode: single
  max_exceeded: silent
  variables:
    media_players:
      35806262ce215ab1b3c48264530f3499: media_player.living_room
    tags:
      BB-D2-B9-1C:
        media_content_id: x-rincon-playlist:RINCON_5CAAFD2FF2C801400#A:ARTIST/ABC%20DEE/XYZ
        media_content_type: music
      C0-45-AA-7F:
        media_content_id: Playlistname
        media_content_type: playlist

Maybe this helps someone

Thank you, yes, I have ultimately built the Adonno ESP32 tag reader and it works great