Hi everyone!
Wanted to share a project I made for my kids: a movie library based on NFC tags.
I wanted to bring back the physicality of VHS tapes and DVDs.
The idea is simple: they browse through our catalog, pick a card, put it on the scanner, and watch a movie.
On the hardware side, I used an ESP32 (C3 Super Mini) and the RC522 NFC reader. The ESP32 is flashed with ESPHome for seamless integration with Home Assistant and local control.
ESPHome Configuration
---
substitutions:
devicename: "nfc-scanner"
friendly_name: "NFC Scanner"
packages:
esphome: !include common/esphome.yaml
api: !include common/api.yaml
logger: !include common/logger.yaml
wifi: !include common/wifi.yaml
esphome:
# Magic variables to get the ESP32C3 Super Mini to work
platformio_options:
board_build.f_flash: 40000000L
board_build.flash_mode: dio
board_build.flash_size: 4MB
on_boot:
priority: 600
then:
- rtttl.play: 'short:d=4,o=5,b=100:16e6,16e6'
esp32:
variant: ESP32C3
board: esp32-c3-devkitm-1
framework:
type: esp-idf
status_led:
pin:
number: GPIO8
inverted: true
output:
- platform: ledc
pin: GPIO3
id: buzzer
rtttl:
output: buzzer
spi:
clk_pin: GPIO4
mosi_pin: GPIO6
miso_pin: GPIO5
rc522_spi:
cs_pin: GPIO7
on_tag:
then:
- rtttl.stop:
- homeassistant.tag_scanned: !lambda 'return x;'
- rtttl.play: 'short:d=4,o=5,b=100:16e6,16e6'
When an NFC tag is scanned, ESPHome emits a tag_scanned
event to Home Assistant. This is being used to play the correct movie on our Apple TV via Plex. To do that, I maintain a “mapping” between tag IDs and Plex IDs.
The automation only works between certain hours to prevent the kids from abusing the system and watching TV all the time
Home Assistant automation
- alias: "NFC Reader - Plex"
description: ""
mode: single
trigger:
- platform: event
event_type: tag_scanned
# Only allow movies to be played in the morning and evening.
# Broad time window to allow for some flexibility in schedule.
condition:
- condition: or
conditions:
- condition: time
after: '05:00:00'
before: '09:00:00'
- condition: time
after: '18:00:00'
before: '19:50:00' # Bed time!
action:
- variables:
# Map the ID of each tag to a Plex ID. The "name" attribute is
# not used but nice to have for debugging.
NFC_MAPPING:
53-77-08-69-71-00-01:
name: Ratatouille
plex_id: 37353
53-72-08-69-71-00-01:
name: Coco
plex_id: 3135
# ...
- if:
# Make sure the scanned tag is in the mapping
- alias: "NFC tag is in the mapping"
condition: template
value_template: "{{ trigger.event.data.tag_id in NFC_MAPPING }}"
then:
# Turn on the Apple TV (and the TV itself) when it's in standby
- if:
- condition: state
entity_id: media_player.appletv_living
state: standby
then:
- service: media_player.turn_on
data: {}
target:
entity_id: media_player.appletv_living
- delay:
seconds: 5
# Take the Plex ID from the mapping and send a deep link to the
# Apple TV. This will automatically open the Plex app and start
# or resume the given movie.
- service: media_player.play_media
target:
entity_id: media_player.appletv_living
data:
media_content_type: url
media_content_id: "plex://play/?metadataKey=%2Flibrary%2Fmetadata%2F{{ NFC_MAPPING[trigger.event.data.tag_id].plex_id }}&server=xxxxxxxxxxxxxx"
# Set an appropriate (low) volume on our Sonos Beam
# Volume controls on Apple TV only support up/down when using an eARC
# speaker.
- service: media_player.volume_set
data:
volume_level: 0.17
target:
entity_id: media_player.sonos_tv
Using “physical” media has many benefits in my opinion:
-
You have a limited choice of movies to watch. When I was a kid, we didn’t have an infinite catalog of movies to watch. We had a handful of VHS tapes and DVDs. We watched the same movies over and over again, each time discovering new details we would have missed otherwise.
-
It gives my kids autonomy. They can decide what they want to watch and are not dependent on us to operate the remote and navigate to the correct app. (Autonomy within certain time periods, we don’t want them watching a lot of TV)
-
With autonomy comes responsibility. When allowed, they can watch any movie they like. They can even switch between movies. But the timeframe is fixed. They can watch a good chunk of one movie, or they can watch a tiny bit of 10 different movies. It’s completely up to them.
-
They will need to learn to collaborate and compromise. We only have one TV and two half-hour slots to watch it. They must quickly agree on a movie or forfeit their viewing time. Or perhaps they use their creativity to come up with a system to decide who gets to choose the movie, eg: “You can pick in the morning, I’ll pick in the evening.”
Other benefits: it’s cheaper to buy second hand Blurays than keeping a Netflix or Disney+ subscription. My kids keep watching the same movies over and over again. Plus, the Blurays come with dubbed versions (horrible, I knnow) and many extras that are often fun to watch. I specifically love behind the scenes content.
My kids love this system, and it’s super reliable. The only issue I’m having is with TV Shows. I currently use Plex deep links to play a specific movie on my Apple TV. If I want to play TV Shows, I need to go through the Plex integration, but for some reason it complains that my Apple TV doesn’t accept playback controls.
→ I still have this issue, but I found a workaround by using smart playlists and regular deep links: NFC Movie Library - #9 by Savjee
You can read the full write-up here. My 3D models are also available if you want to recreate this setup.