Skip to content

Instantly share code, notes, and snippets.

@benjaminrau
Last active March 12, 2024 09:15
Show Gist options
  • Save benjaminrau/d93a4ac062609740a3fdd3aef3ad342c to your computer and use it in GitHub Desktop.
Save benjaminrau/d93a4ac062609740a3fdd3aef3ad342c to your computer and use it in GitHub Desktop.
Home Assistant (HASS) with Homekit, Television Volume Control and Fire TV Stick connected to Sony Bravia

Home Assistant (HASS) with Homekit, Television Volume Control and Fire TV Stick connected to Sony Bravia

Basically it integrates and older Sony Bravia TV with Fire TV Stick on HDMI via Home Assistant in Apple Homekit with Siri Voice Control for Volume, Mute and Turning TV on and off.

Features of my setup

  • Voice control for television on, off, mute, set volume, play, pause
  • Control for television on, off, mute, set volume and input (which app to start) in Home app
  • Turn on TV light scene when TV starts playing
  • iOS Remote Widget inputs are forwarded to media player & Android TV

Used Integrations

Issues and how i approached them

  • i couldnt turn tv on and off reliably until i send to both Fire TV and Bravia the commands, thats why i bundled it in scripts instead of just sending on and off to one of them
  • while play and pause controls are related to firetv the volume is related to bravia, thus i decided to create a media player with universal plugin which wraps both media_players and queries the relevant subtype for specific attributes
  • voice control for volume was not even possible with proper supported_features value thus i created a fake light which sends the proper commands to the media player
  • connecting adb to firetv stick first made issues, restarting firetv helped
  • publishing the tv together with the other accessories is not possible, thus i created two bridges, one for everything else and one for the tv (media_player.fernseher) accessory only
  • when using a bulb or anything else to control the volume and utilize brightness or similar avoid to use "volume" or the respective word in native language in the device name since Homekit will try to do some magic when the device name contains keywords for charateristics

About supported_features

It took me a while to understand that the decimal number for supported_features is derived from the bitwise idicators which features are available for this media player / tv. This thread helped me a lot: https://community.home-assistant.io/t/how-to-read-interpret-supported-features/114152

- id: '1638559800060'
alias: Nachtlicht
description: ''
trigger:
- type: motion
platform: device
device_id: 38aec96398f2d4948ceac05dfa87fcf4
entity_id: binary_sensor.eingang_bewegungsmelder_motion
domain: binary_sensor
condition:
- type: is_illuminance
condition: device
device_id: 38aec96398f2d4948ceac05dfa87fcf4
entity_id: sensor.eingang_bewegungsmelder_light_level
domain: sensor
below: 1.5
action:
- scene: scene.nachtlicht
mode: single
- id: '1638560789701'
alias: TV-Licht
description: ''
trigger:
- platform: state
entity_id: media_player.fernseher
to: playing
condition:
- condition: sun
after: sunset
action:
- scene: scene.tv_licht
mode: single
- id: '1638560789702'
alias: Call androidtv.adb_command on HomeKit Remote key presses
trigger:
- platform: event
event_type: homekit_tv_remote_key_pressed
event_data:
entity_id: media_player.fernseher
action:
- service: androidtv.adb_command
data_template:
entity_id: media_player.android_tv
command: "{% set key_map = {'arrow_right': 'RIGHT', 'arrow_down' : 'DOWN', 'arrow_left':
'LEFT', 'arrow_up': 'UP', 'select': 'ENTER', 'back': 'BACK', 'information':
'HOME'} %} {{ key_map[trigger.event.data['key_name']] }}"
# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:
# Text to speech
tts:
- platform: google_translate
group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
homeassistant:
customize: !include customize.yaml
media_player: !include mediaplayer.yaml
homekit: !include homekit.yaml
light: !include light.yaml
# Just to hide all the sources on Bravia TV, which are not relevant due to Fire TV usage
media_player.sony_bravia_tv:
friendly_name: Fernseher
icon: mdi:television
device_class: tv
source_list:
- HDMI 1
# Television accessories have to be published as seperate bridge, otherwise not supported
# Thus we it in mode accessory and everything else with default mode: bridge
- name: All Devices
auto_start: true
port: 21065
filter:
exclude_domains:
- media_player
- remote
- scene
- automation
- person
- device_tracker
exclude_entities:
- switch.sonos_schlafzimmer_lautsprecher_crossfade
- switch.sonos_kuche_lautsprecher_crossfade
- switch.sonos_wohnzimmer_lautsprecher_crossfade
- switch.sonos_bad_lautsprecher_crossfade
- name: Fernseher
auto_start: true
port: 21066
pincode: 123-22-222
mode: accessory
filter:
include_domains:
- media_player
include_entities:
- media_player.fernseher
- platform: template
lights:
fernseher_lautstaerke:
friendly_name: "Theater"
value_template: >-
{% if is_state('media_player.fernseher', 'playing') %}
{% if state_attr('media_player.fernseher', 'is_volume_muted') %}
off
{% else %}
on
{% endif %}
{% else %}
off
{% endif %}
icon_template: >-
{% if is_state('media_player.fernseher', 'playing') %}
{% if state_attr('media_player.fernseher', 'is_volume_muted') %}
mdi:lightbulb-off
{% else %}
mdi:lightbulb-on
{% endif %}
{% else %}
mdi:lightbulb-off
{% endif %}
level_template: >-
{% if is_state('media_player.fernseher', 'playing') %}
{{ (state_attr('media_player.fernseher', 'volume_level')|float * 625)|int }}
{% else %}
0
{% endif %}
turn_on:
service: media_player.volume_mute
target:
entity_id: media_player.fernseher
data:
is_volume_muted: false
turn_off:
service: media_player.volume_mute
target:
entity_id: media_player.fernseher
data:
is_volume_muted: true
set_level:
service: media_player.volume_set
target:
entity_id: media_player.fernseher
data:
volume_level: "{{ (brightness / 625 * 100)|int / 100 }}"
- platform: universal
name: Fernseher
children:
- media_player.android_tv
- media_player.sony_bravia_tv
state_template: >
{% if is_state('media_player.android_tv', 'standby') and is_state('media_player.sony_bravia_tv', 'playing') %}
idle
{% else %}
{{ states('media_player.android_tv') }}
{% endif %}
commands:
media_play:
service: androidtv.adb_command
data:
command: "input keyevent KEYCODE_MEDIA_PLAY_PAUSE"
entity_id: media_player.android_tv
media_pause:
service: androidtv.adb_command
data:
command: "input keyevent KEYCODE_MEDIA_PLAY_PAUSE"
entity_id: media_player.android_tv
turn_on:
service: script.fernseher_einschalten
turn_off:
service: script.fernseher_ausschalten
volume_up:
service: media_player.volume_up
target:
entity_id: media_player.sony_bravia_tv
volume_down:
service: media_player.volume_down
target:
entity_id: media_player.sony_bravia_tv
volume_mute:
service: media_player.volume_mute
target:
entity_id: media_player.sony_bravia_tv
data:
is_volume_muted: "{{ is_volume_muted }}"
volume_set:
service: media_player.volume_set
target:
entity_id: media_player.sony_bravia_tv
data:
volume_level: "{{ volume_level }}"
select_source:
service: media_player.select_source
target:
entity_id: media_player.android_tv
data:
source: "{{ source }}"
attributes:
is_volume_muted: media_player.sony_bravia_tv|is_volume_muted
volume_level: media_player.sony_bravia_tv|volume_level
source: media_player.android_tv|source
source_list: media_player.android_tv|source_list
state: media_player.android_tv
entity_picture: media_player.android_tv|entity_picture
supported_features: media_player.android_tv|supported_features
device_class: tv
supported_features: 1225 # Not working but the correct features: 11981 (alt: 22961)
- platform: androidtv
name: Android TV
device_class: firetv
host: 192.168.0.39
exclude_unnamed_apps: true
apps:
com.amazon.tv.launcher: "Home"
com.netflix.ninja: "Netflix"
com.amazon.avod: "Prime Video"
com.amazon.firetv.youtube: "YouTube"
com.apple.atve.amazon.appletv: "Apple TV"
com.zdf.android.mediathek: "ZDF"
com.zappntv: "Zappn TV"
com.amazon.firebat: ""
com.amazon.venezia: ""
turn_on_command: "input keyevent 3"
turn_off_command: "input keyevent 223"
state_detection_rules:
'com.amazon.tv.launcher':
- 'standby'
'com.netflix.ninja':
- 'media_session_state'
'com.zappntv':
- 'playing':
'wake_lock_size': 17
- 'playing':
'wake_lock_size': 16
- 'standby'
'com.amazon.avod':
- 'playing':
'wake_lock_size': 4
- 'playing':
'wake_lock_size': 3
- 'paused':
'wake_lock_size': 2
- 'paused':
'wake_lock_size': 1
- 'standby'
# Nightlight which is triggered by motion sensor
- id: '1638558751218'
name: Nachtlicht
entities:
light.kuche_lichtstreifen:
min_mireds: 153
max_mireds: 500
effect_list:
- colorloop
- random
supported_color_modes:
- color_temp
- hs
color_mode: color_temp
brightness: 51
color_temp: 385
hs_color:
- 28.631
- 69.118
rgb_color:
- 255
- 162
- 78
xy_color:
- 0.538
- 0.388
effect: none
friendly_name: Küche Lichtstreifen
supported_features: 63
state: 'on'
light.couch:
supported_color_modes:
- brightness
color_mode: brightness
brightness: 51
friendly_name: Couch
supported_features: 41
state: 'on'
icon: mdi:weather-night
# TV Light which is triggered when tv starts playing
- id: '1638560632333'
name: TV-Licht
entities:
light.couch:
supported_color_modes:
- brightness
color_mode: brightness
brightness: 51
friendly_name: Couch
supported_features: 41
state: 'on'
light.esstisch_1:
min_mireds: 153
max_mireds: 454
supported_color_modes:
- color_temp
color_mode: color_temp
brightness: 20
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Esstisch 1
supported_features: 43
state: 'on'
light.esstisch_2:
min_mireds: 153
max_mireds: 454
supported_color_modes:
- color_temp
color_mode: color_temp
brightness: 26
color_temp: 454
hs_color:
- 29.79
- 84.553
rgb_color:
- 255
- 146
- 39
xy_color:
- 0.579
- 0.388
friendly_name: Esstisch 2
supported_features: 43
state: 'on'
light.deko_licht_1:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 1
supported_features: 41
state: 'off'
light.deko_licht_2:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 2
supported_features: 41
state: 'off'
light.demo_licht_3:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 3
supported_features: 41
state: 'off'
light.demo_licht_4:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 4
supported_features: 41
state: 'off'
light.deko_licht_5:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 5
supported_features: 41
state: 'off'
light.deko_licht_6:
supported_color_modes:
- brightness
friendly_name: Deko-Licht 6
supported_features: 41
state: 'off'
icon: mdi:television
# Bundles the actions to be performed to power on TV
fernseher_einschalten:
alias: Fernseher - Einschalten
sequence:
- service: media_player.turn_on
target:
entity_id:
- media_player.sony_bravia_tv
- service: androidtv.adb_command
data:
entity_id: media_player.android_tv
command: POWER
mode: single
icon: mdi:toggle-switch-outline
# Bundles the actions to be performed when powering off tv
fernseher_ausschalten:
sequence:
- service: media_player.turn_off
target:
entity_id:
- media_player.sony_bravia_tv
- service: androidtv.adb_command
data:
entity_id: media_player.android_tv
command: SLEEP
mode: single
alias: Fernseher - Ausschalten
icon: mdi:toggle-switch-off-outline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment