I need some help. We use Emby server with firetv’s throughout our house. My 3 year old has special needs… We have finally gotten her to stay in her room until her clock turns green at 7am… then she runs down the stair and wakes me up… “papa I want a show…” I’d like to be able to automate launching the emby app on a firetv stick and then starting one of several movies, at 7am on the tv in her room. Any takers on how to do this? I have the firetv’s connected to home assistant. Thanks in advance to anyone that can help!
/Rob
I don’t know anything about the emby integration, but you can launch a Fire TV app using the media_player.select_source
service and providing the app ID as the source
parameter; see here for documentation.
Also, the firetv
component will be renamed to androidtv
in the next release. It should detect that it’s a Fire TV device, not an Android TV device, but you can help it out by adding device_class: firetv
to your config.
I figured it out, thanks
Do you mind sharing how?
at what level explanation are you looking?
You need to generate an API key for your emby server.
For each FireTV or FireTV Stick, you need to create a command line sensor that includes the device ID in the curl call to the Emby API.
I use Postman to find this information. The GET call for my setup looks like this:
http://tv.domain.com:8096/emby/Devices
and headers:
X-Emby-Token=xxxxxxx
Content-Type=application/json
The Response should look like this:
{
“Items”: [
{
“Name”: “SMG965U”,
“Id”: “63e06b564b84b016”,
“LastUserName”: “Rob”,
“AppName”: “Emby for Android Mobile”,
“AppVersion”: “3.0.48”,
“LastUserId”: “70ed5f4b409f4dcd83526a04bc25e0a8”,
“DateLastActivity”: “2019-05-19T21:49:35.0000000Z”,
“IconUrl”: “https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/android.png”
},
{
“Name”: “Hedrick Living Room”,
“Id”: “4a31382947bbd1a2”,
“LastUserName”: “Family”,
“AppName”: “AndroidTv”,
“AppVersion”: “1.6.94a”,
“LastUserId”: “0588ff12bc3e45fdbaeee9fc15d27a09”,
“DateLastActivity”: “2019-05-19T21:47:06.0000000Z”,
“IconUrl”: “https://mediabrowser.github.io/Emby.AndroidTv/appicon.png”
},
{
“Name”: “Playroom”,
“Id”: “66a3382525ce0893”,
“LastUserName”: “Olivia”,
“AppName”: “AndroidTv”,
“AppVersion”: “1.6.94a”,
“LastUserId”: “81839facd92b4c86991c3088275a859b”,
“DateLastActivity”: “2019-05-19T21:26:23.0000000Z”,
“IconUrl”: “https://mediabrowser.github.io/Emby.AndroidTv/appicon.png”
},
You want the Id from this information for each device you want to control.
- platform: command_line
name: embysessionplayroom
command: "curl -H \"Content-Type: application/json\" -H \"X-Emby-Token: xxxxxxxxxxxxxxxxxxx\" -X GET \"http://tv.domain.com:8096/emby/Sessions\" | jq -r '.[] | select(.DeviceId==\"66a3382525ce0893\") | .Id'"
scan_interval: 4
Make sure you escape all quotes inside the command with a backslash as I have
This sensor will report back the unique session id later.
You need to also get the Id for the user you want to login as.
Use the same method as for devices, but your GET is
http://tv.domain.com:8096/emby/Users
Finally, you need a list of Movies and their ID’s that the user you want to control is allow to watch.
Same headers as above
http://tv.chucklehead.lol:8096/emby/Users/USERIDGUID/Items?Recursive=true&IncludeItemTypes=Movie
Create an input_select for the movies. Make sure you remove illegal characters.
firetv_movies:
name: firetv_movies
options:
- Cinderella
- Despicable Me
- Despicable Me 2
- Despicable Me 3
- Finding Nemo
- Frosty the Snowman
- Frozen
- Harry Potter and the Philosophers Stone
- Lady and the Tramp
- Madagascar
- Madagascar 3 Europes Most Wanted
- Madagascar Escape 2 Africa
- Monsters, Inc.
- One Hundred and One Dalmatians
- Pinocchio
- Pocahontas
- Rudolph the Red-Nosed Reindeer
- Snow White and the Seven Dwarfs
- The Lion King
- The Little Mermaid
- Willy Wonka & the Chocolate Factory
initial: The Little Mermaid
icon: mdi:movie
Create an input_datetime
liv_trigger_time:
name: "turn on liv show"
has_date: false
has_time: true
initial: '07:00'
In your configuration.yaml make sure you can control the firestick thru the androidtv platform
- platform: androidtv
name: Olivias Room
host: 172.17.17.5
adbkey: !secret adbkey_olivia
There are several automations that need to be created. Before I did this I connected to all my firesticks via adb and changed the configuration so that they never go to sleep or turn off… This is important.
This is what my final card looks like:
Create the rest_command:
emby_start_show:
url: http://tv.domain.com: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}'
Create the automation’s:
- id: '155648556587'
alias: call automations for olivia device at time
initial_state: true
trigger:
- platform: template
value_template: '{{ states.sensor.time.state == (states.input_datetime.liv_trigger_time.attributes.timestamp
| int | timestamp_custom("%H:%M", False)) }}'
action:
- service: automation.trigger
entity_id: automation.launch_emby_on_olivia_device
- service: automation.trigger
entity_id: automation.play_emby_show_on_olivia_device
- service: automation.trigger
entity_id: automation.turn_olivias_tv_on
The TV turn on action is for my harmony IR device to turn on the TV
- id: '15855573698'
alias: launch emby on olivia device
trigger: []
condition:
- condition: state
entity_id: automation.call_automations_for_olivia_device_at_time
state: 'on'
action:
- service: script.adb_start_emby_on_device
data_template:
device: '{% if is_state(''input_select.firetv_device'',''Olivias Room'') %}
media_player.olivias_room {% elif is_state(''input_select.firetv_device'',''Playroom'') %}
media_player.play_room {% elif is_state(''input_select.firetv_device'',''Bathroom'') %}
media_player.bathroom {% else %} media_player.olivias_room {% endif %}
- id: '15857596587'
alias: play emby show on olivia device
trigger: []
condition:
- condition: state
entity_id: automation.call_automations_for_olivia_device_at_time
state: 'on'
action:
- wait_template: "{{ not is_state('sensor.embysessionolivia', '') }}"
- service: rest_command.emby_start_show
data_template:
show: '{% if is_state(''input_select.firetv_movies'',''Cinderella'') %} 24959
{% elif is_state(''input_select.firetv_movies'',''Despicable Me'') %} 60872
{% elif is_state(''input_select.firetv_movies'',''Despicable Me 2'') %} 67305
{% elif is_state(''input_select.firetv_movies'',''Despicable Me 3'') %} 67175
{% elif is_state(''input_select.firetv_movies'',''Finding Nemo'') %} 60819
{% elif is_state(''input_select.firetv_movies'',''Frosty the Snowman'') %}
36271 {% elif is_state(''input_select.firetv_movies'',''Frozen'') %} 24954
{% elif is_state(''input_select.firetv_movies'',''Harry Potter and the Philosophers
Stone'') %} 67224 {% elif is_state(''input_select.firetv_movies'',''Lady and
the Tramp'') %} 24957 {% elif is_state(''input_select.firetv_movies'',''Madagascar'')
%} 60841 {% elif is_state(''input_select.firetv_movies'',''Madagascar 3 Europes
Most Wanted'') %} 67174 {% elif is_state(''input_select.firetv_movies'',''Madagascar
Escape 2 Africa'') %} 67155 {% elif is_state(''input_select.firetv_movies'',''Monsters,
Inc.'') %} 24958 {% elif is_state(''input_select.firetv_movies'',''One Hundred
and One Dalmatians'') %} 50077 {% elif is_state(''input_select.firetv_movies'',''Pinocchio'')
%} 24950 {% elif is_state(''input_select.firetv_movies'',''Pocahontas'') %}
24953 {% elif is_state(''input_select.firetv_movies'',''Rudolph the Red-Nosed
Reindeer'') %} 36272 {% elif is_state(''input_select.firetv_movies'',''Snow
White and the Seven Dwarfs'') %} 24952 {% elif is_state(''input_select.firetv_movies'',''The
Lion King'') %} 57496 {% elif is_state(''input_select.firetv_movies'',''The
Little Mermaid'') %} 24956 {% elif is_state(''input_select.firetv_movies'',''Willy
Wonka & the Chocolate Factory'') %} 92962 {% else %} 60819 {% endif %}
'
token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
userid: 81839facd92b4c86991c3088275a859b
session: '{{ states.sensor.embysessionolivia.state }}'
Tie it all together with a UI-Lovelace card like this:
- title: Automation
icon: ‘mdi:home-automation’
panel: false
path: automation
theme: default
type: vertical-stack
cards:
- type: custom:compact-custom-header
main_config: false
disable: false
header: true
menu: show
background_image: true
notifications: show
voice: hide
options: clock
clock_format: 12
exceptions:
- conditions:
user: dashboard
config:
show_tabs: 12
- type: entities
title: Olivia Automation
show_header_toggle: false
entities:
- entity: automation.call_automations_for_olivia_device_at_time
name: Enable/Disable
- entity: input_datetime.liv_trigger_time
name: Time
- entity: input_select.firetv_device
name: Device
- entity: input_select.firetv_movies
name: Movie
Wow, thank you for the detailed reply. I’ll give it a go!
An update: I wanted to make this a little more dynamic and also wanted to be able to shuffle episode of key tv shows like Paw Patrol. So I created a tag in each series called kids.
Then I created a Rest Sensor that polls the emby api for series with the tag for kids and makes the ‘state’ of said sensor a comma delimited string of name and id… IE ‘Doc McStuffins:8554,Some Show:1234’
- platform: rest
resource: http://tv.domain.com:8096/emby/Items?Recursive=true&IncludeItemTypes=Series&Tags=kids
method: GET
scan_interval: 1800
headers:
Content-Type: 'application/json'
X-Emby-Token: 'xxxxxxxxxxxxxxxxxxxxxxx'
name: emby_kids_series
value_template: >
{% for item in value_json.Items -%}
{{ item.Name }}:{{item.Id}}{% if not loop.last %},{% endif %}
{%- endfor %}
At system startup, after the Rest Sensor is populated, my automation calls back to the local Home Assistant API and updates the Menu Choices for TV Show with the name values from the Rest API.
update_firetv_shows:
url: "http://localhost:8123/api/services/input_select/set_options"
method: POST
headers:
content-type: "application/json"
Authorization: "Bearer xxxxxxxxxxxxxxxxxxxxxxxxx"
payload: >-
{
"entity_id": [
"input_select.firetv_shows"
],
"options": [
{% set temp =states.sensor.emby_kids_series.state.split(',') %}
{%- for item in temp %}
"{{item.split(':')[0]}}"{% if not loop.last %}, {% endif %}
{%- endfor %}
]
}
If TV Show is selected, The automation will pass The SeriesId, UserId, API Token and SessionId to a home assistant script,
- id: '158575965865'
alias: play emby show on olivia device2
trigger: []
condition:
- condition: state
entity_id: automation.call_automations_for_olivia_device_at_time
state: 'on'
- condition: state
entity_id: input_select.firetv_media_select
state: 'TV Show'
action:
- wait_template: "{{ not is_state('sensor.embysessionolivia', '') }}"
- service: script.get_seasons_for_series
data_template:
show: '{% set temp =states.sensor.emby_kids_series.state.split('','') %}
{%- for item in temp %}
{% if states.input_select.firetv_shows.state == item.split('':'')[0] %}
{{item.split('':'')[1]}}
{% endif %}
{%- endfor %}'
token: b7cee43a658b40ff8e40c2a6e3e7dd55
userid: 81839facd92b4c86991c3088275a859b
session: '{{ states.sensor.embysessionolivia.state }}'
get_seasons_for_series:
sequence:
- service: shell_command.get_episodes_cmd
data_template:
show: '{{ show }}'
token: '{{ token }}'
userid: '{{ userid }}'
session: '{{ session }}'
Which then passes the variables to a shell_command…
get_episodes_cmd: bash /home/rob/scripts/get_episodes.sh {{show}} {{token}} {{userid}} {{session}}
The bash script pulls all the episodes in the series and puts the Id’s into an array… then it randomly selects 10 Id’s and concatenates then into a string like ‘ItemIds=1234&ItemIds=5678’. This is passes this string into the emby api call to launch the playlist.
seasons=$1
token=$2
userid=$3
session=$4
set -a arr
for i in $(echo $seasons | sed "s/,/ /g")
do
arr+=( $(curl -H "Content-Type: application/json" -H "X-Emby-Token: $token" -X GET "http://tv.chucklehead.lol:8096/emby/Items?&Recursive=true&ParentId=$i&IncludeItemTypes=episode" | jq -r '.[][]? | .Id') )
done
result=''
size=${#arr[@]}
for ((i=1;i<=10;i++)); do
index="$(($RANDOM % $size))"
rand="${arr[$index]}"
result="$result$rand,"
done
result=${result::-1}
curl -X POST "http://tv.chucklehead.lol:8096/emby/Sessions/$session/Playing?ItemIds=$result&PlayCommand=PlayNow&api_key=$token" -H "accept: */*" \
-H "Content-Type: application/json" -d "{\"ControllingUserId\":\"$userid\",\"SubtitleStreamIndex\":0,\"AudioStreamIndex\":0,\"MediaSourceId\":\"string\",\"StartIndex\":0}"
first of all thank you very much for sharing this and the detailed instructions. I’m using Jellifyn and this works with it as well.
I was able to follow your first set of instructions and got it working.
I then attempted the dynamic sensor and I’m stuck.
The sensor.emby_kids_series doesnt work for me. I populated your resource in Postman and got “object reference not set to an instance of an object”
If I try it like this:
http://192.168.1.100:8096/emby/Users/userid/Items?Recursive=true&IncludeItemTypes=Movie&Tags=kids
it works. I get the filtered information.
The problem is that if I try to use it like that in HA as rest, it doesnt work because of the 255 characters limiation.
Any workaround you maybe able to suggest is welcome
Thank you again
Edit: so the problem is not that it cant run the sensor. The problem is the string back is over 255 char in my case. If I tag a couple of videos, it works.
So this limitation doesnt let the sensor work
Anyone know if its possible to make so it automatically starts to cast media to a speaker?
Im using this for music =)
Have you figured out how to cast music to a speaker? I would be interested in a solution too
No, i got logitech media server in docker with chromecast addon. Works perfect with home assistant too =)
Cheers for the quick reply. I will look into it
Np, plugin name is “chromecast bridge”
I’d like to thank you for writing this, it’s really helped me wrap my head around accessing Emby’s API for the first time, and I don’t think I’d have been able to get my NFC tags working without this post.
One area I’m kind of getting stumped on is playing a random episode of a particular show.
I’m not using a drop-down or anything like what you’re using for your setup, but I have NFC tags that each play a certain title. So far I’ve limited myself to each tag playing a specific movie, but when it comes to TV shows, I’d like each tag to start playback of a particular show, but a random episode of said show.
What do you think would be the best way of going about this? I’d only need it to play a single episode and then stop until the tag is scanned again and then play another random episode of the same show.
EDIT:
I ended up figuring this out on my own, and it turned out to be much easier than I thought! All I had to do was find out the range of numbers for the ID’s of the episodes that I wanted and template them so a random episode would be chosen for show:
show: '{{ range(614262,614301)| random }}'