Since I’ve been working on this for the past few days and (with the help of some other Home Assistant users) managed to get everything set up and working nicely, I thought I’d share my setup here!
I started by building the actual NFC tag reader using the code from Adonno’s tag reader. This was simple enough and only required a few cheap components.
I then started creating the automation, but since I’d never dealt with accessing an API or using REST calls before, I got a head start by adapting this excellent write up on the Home Assistant forums to fit my particular needs for accessing the Emby API (it could be adapted to other API’s, but this is the one I needed in particular).
I used Postman to get the device and session ID’s from Emby, as well as to figure out the paths, etc for certain shows/genres.
Here is the automation I ended up with:
- alias: EMBY - NFC Tag Scanned
trigger:
platform: event
event_type: tag_scanned
variables:
scanners:
# A separate section here for each NFC scanner (I currently only use one)
a67fd665fe2815113ce31287a4edb141:
tv: Livingroom TV
sensor_id: sensor.embysession_livingroom
session_id: !secret emby_livingroom_sessionid
tts_target: media_player.echo_show
media_player: switch.livingroom_hub_emby_theater
turn_on_emby: script.turn_on_emby_livingroom
open_emby: script.open_emby_livingroom
tags:
# A separate section here for each tag that gets scanned
04-7F-74-5A-AF-4F-81:
show: 1149104
title: Baby Shark
04-42-E0-5A-AF-4F-80:
show: '{{ states.sensor.emby_random_green_eggs_and_ham_episode.state }}'
title: Green Eggs and Ham
04-6B-A1-5A-AF-4F-81:
show: '{{ states.sensor.emby_random_blue_s_clues_episode.state }}'
title: Blue's Clues
04-F0-E9-5A-AF-4F-80:
show: '{{ states.sensor.emby_random_rusty_rivets_episode.state }}'
title: Rusty Rivets
55-38-CB-2A:
show: '{{ states.sensor.emby_random_dinosaur_train_episode.state }}'
title: Dinosaur Train
04-73-7B-5A-AF-4F-81:
show: '{{ states.sensor.emby_random_comedy_movie.state }}'
title: A Random Comedy Movie
04-5B-A6-5A-AF-4F-81:
show: '{{ states.sensor.emby_random_horror_movie.state }}'
title: A Random Horror Movie
04-68-49-5A-AF-4F-81:
show: '{{ states.sensor.emby_random_chick_flick.state }}'
title: A Random Chick Flick
04-1A-6B-5A-AF-4F-80:
show: '{{ states.sensor.emby_random_space_movie.state }}'
title: A Random Space Movie
04-BB-CF-5A-AF-4F-80:
show: '{{ states.sensor.emby_random_action_movie.state }}'
title: A Random Action Movie
04-5C-DC-5A-AF-4F-81:
show: '{{ states.sensor.emby_random_superhero_movie.state }}'
title: A Random Superhero Movie
condition:
- "{{ trigger.event.data.tag_id in tags }}"
- "{{ trigger.event.data.device_id in scanners }}"
action:
# Get Alexa to tell me what's playing, and where
- service: notify.alexa_media
data_template:
target: '{{ scanners[trigger.event.data.device_id].tts_target }}'
message: "Playing {{ tags[trigger.event.data.tag_id].title }} on the {{ scanners[trigger.event.data.device_id].tv }}"
data:
type: "tts"
# Make sure Emby is open, and if it isn't, start it
- service_template: >
{% if (is_state( scanners[trigger.event.data.device_id].media_player , "off")) %}
{{ scanners[trigger.event.data.device_id].turn_on_emby }}
{% else %}
{{ scanners[trigger.event.data.device_id].open_emby }}
{% endif %}
- wait_template: "{{ not is_state(scanners[trigger.event.data.device_id].sensor_id, '') }}"
# Send the rest_command to Emby to play the selected title
- service: rest_command.emby_start_show
data_template:
show: '{{ tags[trigger.event.data.tag_id].show }}'
token: !secret emby_key
userid: !secret emby_user
session: '{{ scanners[trigger.event.data.device_id].session_id }}'
The above automation relies on a decent handful of sensors I created with the help of some other Home Assistant users. The first are a couple of sensors that get the SessionId from each Emby instance which serve two purposes: Lets my automation check to make sure an instance is running, and lets the automation know which instance to send the command to, depending on which room the NFC tag was scanned in (I currently only have one scanner, but it’s set up in a way to make adding more scanners very simple). Below is the rest_command that sends the call to Emby in order to play the selected Movie/Episode and the sensors needed to select what to play.
rest_command:
emby_start_show:
url: http://192.168.1.240:8096/emby/Sessions/{{ session }}/Playing?ItemIds={{ show }}&PlayCommand=PlayNow&api_key={{ token }}
method: POST
headers:
accept: '*/*'
Content-Type: 'application/json'
payload: '{"ControllingUserId":"{{ userid }}","SubtitleStreamIndex":0,"AudioStreamIndex":0,"StartIndex":0}'
SessionId sensor:
- platform: command_line
name: embysession_livingroom
command: "curl -H \"Content-Type: application/json\" -H \"X-Emby-Token: xxxxxxxxxxxxxx\" -X GET \"http://192.168.1.240:8096/emby/Sessions\" | jq -r '.[] | select(.DeviceId==\"Livingroom\") | .Id'"
scan_interval: 5
- platform: command_line
name: embysession_bedroom
command: "curl -H \"Content-Type: application/json\" -H \"X-Emby-Token: xxxxxxxxxxxxxx\" -X GET \"http://192.168.1.240:8096/emby/Sessions\" | jq -r '.[] | select(.DeviceId==\"Bedroom\") | .Id'"
scan_interval: 5
Next, I created some sensors to get the total item count for each category:
- platform: rest
resource: http://192.168.1.240:8096/emby/Shows/543045/Episodes
name: "Emby - ID Count_Blue's Clues"
value_template: '{{value_json.TotalRecordCount}}'
scan_interval: 600
headers:
X-Emby-Token: xxxxxxxxxxxxxxxx
Content-Type: application/json
- platform: rest
resource: http://192.168.1.240:8096/emby/items?Recursive=true&IncludeItemTypes=Movie&Genres=comedy
name: "Emby - ID Count_Comedy Movies"
value_template: '{{value_json.TotalRecordCount}}'
scan_interval: 600
headers:
X-Emby-Token: xxxxxxxxxxxxxxxx
Content-Type: application/json
This sensor reads the API call and counts the total number of item ID’s in each category and sets it as the sensors value, which gets updated every 10 minutes.
Next, I set up some sensors to take the item counts from the previous sensors, and randomize them to pick a random Movie/Episode:
- platform: rest
name: "Emby - Random Blue's Clues Episode"
scan_interval: 4
resource: http://192.168.1.240:8096/emby/Shows/543045/Episodes
value_template: '{{value_json.Items[range(0,((states.sensor.emby_id_count_blue_s_clues.state | int) -1 ))|random].Id}}'
headers:
X-Emby-Token: xxxxxxxxxxxxxxxx
Content-Type: application/json
- platform: rest
name: "Emby - Random Comedy Movie"
scan_interval: 4
resource: http://192.168.1.240:8096/emby/items?Recursive=true&IncludeItemTypes=Movie&Genres=comedy
value_template: '{{value_json.Items[range(0,((states.sensor.emby_id_count_comedy_movies.state | int) -1 ))|random].Id}}'
headers:
X-Emby-Token: xxxxxxxxxxxxxxxx
Content-Type: application/json
The value of these sensors get passed to the automation in the beginning of this post to tell it which Movie/Episode to play when a tag is scanned.
The end result is a simple to use system that even my toddler can use! He has a set of cards depicting some of his favourite TV shows, and when scanned will play a random episode. I’ve also made cards for my wife and I to help with choosing a random movie to watch in particular categories