Universal Remote Card - Buttons, Touchpads, Sliders, and Keyboards for Multiple Platforms

Youā€™d have to add custom svg icons for them as described here. You could also use CSS to instead use an image as described here.

This card is great but iā€™m strugling adding a custom_source of any app installed on my Android TV, in this case SmartTube

I thought that app_id should be used com.liskovsoft.smarttubetv.beta but it doesnā€™t seem to work. Also looked for a source in dev tools but it doesnā€™t give me any hints.

Do you have an example on how to add a custom_source for any app installed on my Philips Android TV?

For Smartube Iā€™m using the card default YouTube source vnd.youtube://. It does throw an error message at the bottom of the screen saying it canā€™t process the intent but it works anyway. Have you tried any of the alternates for YouTube or Smartube in the Android TV deep linking guide??

As for examples there a section in the README in custom keys and sources that has this example:

custom_sources:
  max:
    icon: hbo
    source: hbomax://deeplink

With source being found using the deep linking guide.

1 Like

Thanks for your reply, i missed the deep link part my apologies.

1 Like

Iā€™ve just released v3.1.0, which adds jinja2-like templating using nunjucks.

Because this uses nunjucks to recreate Home Assistant templating, I have to reimplement some of its functions as described in the Home Assistant templating documentation. So far the following functions are implemented:

  • states
  • is_state
  • state_attr
  • is_state_attr
  • has_value
  • iif
  • match_media

Hereā€™s some examples of using templates with this card:

rows:
  - - '{{ "navigation_buttons" if match_media("(orientation: landscape)") else "navigation_touchpad" }}'
  - - '{{ "sunroom_light" if is_state("light.sunroom_ceiling", "off") else "volume_slider" }}'
custom_keys:
  sunroom_light:
    icon: >-
      {{ iif(is_state("light.sunroom_ceiling", "on"), "mdi:ceiling-light",
      "mdi:ceiling-light-outline") }}
    service: light.toggle
    data:
      entity_id: light.sunroom_ceiling
    style:
      color: |
        {% if is_state("light.sunroom_ceiling", "on") %}
        rgb({{ state_attr("light.sunroom_ceiling", "rgb_color") }})
        {% endif %}

Note: You still need to use VALUE for slider service call data.

2 Likes

Hi @Nerwyn, thanks a lot for your amazing card, works like a charm!

Here my custom config for a Samsung SmartTV, integrated with HA using ha-samsungtv-smart (GitHub - ollo69/ha-samsungtv-smart: šŸ“ŗ Home Assistant SamsungTV Smart Component with simplified SmartThings API Support configurable from User Interface.).

Hope it can help other using this amazing card!

type: custom:android-tv-card
media_player_id: media_player.samsung_tv_75_salotto_ci
custom_icons:
  dazn: >-
    m14.774 8.291.772-2.596.79 2.596zm3.848
    2.268-2.025-6.128c-.045-.135-.097-.224-.154-.266a.497.497 0 0
    0-.28-.063h-1.12a.485.485 0 0 0-.284.068c-.06.045-.11.132-.149.261l-2.045
    6.128c-.025.032-.038.096-.038.192 0 .149.09.223.27.223h.84c.076 0
    .139-.003.187-.01a.207.207 0 0 0 .116-.048.326.326 0 0 0
    .077-.116c.022-.051.046-.119.072-.202l.318-1.071h2.306l.327
    1.051c.026.09.051.16.077.213a.395.395 0 0 0
    .087.12c.031.028.07.047.114.053h.002c.045.006.103.01.173.01h.897c.18 0
    .27-.074.27-.223a.59.59 0 0 0-.005-.09.878.878 0 0
    0-.036-.108l.003.006zm-.994 2.467h-.646c-.168
    0-.279.024-.333.072-.055.049-.082.147-.082.295v3.638l-1.91-3.647c-.076-.155-.152-.253-.226-.295-.074-.041-.204-.063-.39-.063h-.599c-.167
    0-.278.025-.332.073-.055.048-.082.147-.082.294v6.138c0
    .148.025.246.077.294.052.048.16.072.328.072h.656c.167 0
    .278-.024.332-.072.055-.048.082-.146.082-.294v-3.648l1.91
    3.657c.077.155.152.253.227.295.073.042.204.062.39.062h.598c.167 0
    .278-.024.333-.072.054-.048.082-.146.082-.294v-6.138c0-.148-.028-.246-.082-.294-.055-.048-.166-.073-.333-.073zm3.203-.581
    1.665 1.665v8.385H1.505V14.11l1.663-1.664a.63.63 0 0 0 0-.89L1.504
    9.891V1.505h20.991v8.384l-1.665 1.666a.63.63 0 0 0 0 .89zM24
    0H0v10.613L1.387 12 0 13.387V24h24V13.387L22.613 12 24 10.613zM10.67
    18.469H7.96l2.855-4.014a.67.67 0 0 0 .087-.155.425.425 0 0 0
    .019-.135v-.772c0-.148-.028-.246-.082-.294-.055-.048-.166-.073-.334-.073H6.382c-.149
    0-.245.028-.29.082-.045.055-.068.169-.068.343v.58c0
    .172.023.287.068.341.045.055.141.083.29.083h2.545L6.11 18.469a.438.438 0 0
    0-.107.27v.792c0 .148.027.245.082.294.055.048.167.072.334.072h4.25c.148 0
    .245-.027.29-.081.045-.055.068-.17.068-.344v-.579c0-.173-.023-.287-.068-.342-.045-.055-.142-.082-.29-.082zM9.408
    8.233c0 .264-.017.484-.052.661a1.08 1.08 0 0 1-.174.43.648.648 0 0
    1-.318.231 1.523 1.523 0 0 1-.487.068h-.79v-4.17h.79c.366 0
    .63.11.79.324.16.215.241.571.241
    1.067v1.389zm1.38-2.789c-.225-.457-.533-.795-.921-1.013-.39-.219-.88-.328-1.47-.328H6.418c-.167
    0-.278.024-.333.072-.054.049-.082.147-.082.294v6.138c0
    .148.028.246.082.295.055.048.166.072.333.072h2.218c1.048 0 1.765-.447
    2.15-1.342.09-.205.153-.413.188-.622a4.91 4.91 0 0 0
    .054-.796V6.911c0-.367-.018-.656-.054-.868a2.2 2.2 0 0 0-.193-.612l.006.013z
custom_keys:
  '0':
    icon: mdi:numeric-0
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_0
  '1':
    icon: mdi:numeric-1
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_1
  '2':
    icon: mdi:numeric-2
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_2
  '3':
    icon: mdi:numeric-3
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_3
  '4':
    icon: mdi:numeric-4
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_4
  '5':
    icon: mdi:numeric-5
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_5
  '6':
    icon: mdi:numeric-6
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_6
  '7':
    icon: mdi:numeric-7
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_7
  '8':
    icon: mdi:numeric-8
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_8
  '9':
    icon: mdi:numeric-9
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_9
  up:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_UP
  down:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_DOWN
  left:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_LEFT
  right:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_RIGHT
  center:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_ENTER
  power:
    icon: mdi:power
    service: media_player.toggle
    target:
      entity_id: media_player.samsung_tv_75_salotto_ci
  home:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_HOME
  back:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_RETURN
  volume_mute:
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_MUTE
  ch_up:
    icon: mdi:arrow-up-bold
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_CHUP
  ch_down:
    icon: mdi:arrow-down-bold
    service: media_player.play_media
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      media_content_type: send_key
      media_content_id: KEY_CHDOWN
  DAZN:
    icon: dazn
    service: media_player.select_source
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      source: DAZN
  netflix:
    icon: mdi:netflix
    service: media_player.select_source
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      source: Netflix
  youtube:
    icon: mdi:youtube
    service: media_player.select_source
    data:
      entity_id: media_player.samsung_tv_75_salotto_ci
      source: YouTube
  light_off:
    icon: mdi:lightbulb-group-off
    service: light.turn_off
    target:
      entity_id: light.all_lights
  light_on:
    icon: mdi:lightbulb
    service: light.turn_on
    target:
      entity_id: light.soggiorno
rows:
  - - power
    - null
    - volume_mute
    - null
    - light_on
    - light_off
  - - volume_slider
  - - null
  - - ch_up
    - ch_down
  - - null
  - - netflix
    - youtube
    - DAZN
    - primevideo
    - spotify
  - - navigation_touchpad
  - - back
    - home
  - - 1
    - 2
    - 3
    - 4
    - 5
  - - 6
    - 7
    - 8
    - 9
    - 0

1 Like

Searched a bit and am having trouble with one thing. Is there a way to define a source button for Kodi? I havenā€™t managed to figure it out yet.

Iā€™ve got a Sony XR 65a83j, and it has the function to turn off the screen (while leaving the TV itself on) in the TV hotbar, a very handy function for using TV to play music. Do you know if and how it would be possible to configure this to have it as a dedicated button I can press on my phone to turn off the screen?

Also I have an app ā€œTV Broā€, which is essentially a browser on my TV. Any idea how I can pull this browser app source, and also navigate inside of it via my mobile phone (is there even a way to just navigate via ā€œmouseā€, but via mobile?)

Hello Nerwyn
Thanks for the great work. I started using your card a few weeks ago. I tried your latest nunchuck update to animate buttons. I dont know why the new buttons work on my galaxy tab-s3 tablet but they donā€™t work on my laptop and s22ultra phone. Actually the icons dont show up on the card but they work when you touch on their supposed places on the screen.

Can you please advice how can I solve this problem

This is a picture from the non working version from my laptop, Normally the card is full of buttons but the buttons with conditional icons with nunchucks dont show up. only buttons with normal icons show up.

99% of the time Inconsistent behavior between modern devices is a caching issue. Have you tried clearing browser cache on or restarting the non-working devices?

Not sure what a TV hotbar is, but youā€™d have to figure out if this command is being sent via IR, RF, ADB, the remote API, or something Sony proprietary, and then figure out if itā€™s possible to call that from Home Assistant.

For creating new sources, see this thread: Android TV Remote - App Links/Deep Linking - Guide. Iā€™m also not sure about 1:1 mouse control on Android TV. I know itā€™s possible on Windows using Unified Remote, but I donā€™t think the 1:1 mouse capability of that is possible on Home Assistant.

Iā€™m not a Kodi user, but if there is a way to do it it would be in the Kodi JSON-RPC API documentation.

Thx to this project, very cool and handy to control my media devices.

Here an example of my popup control with a logitech harmony. It is based on the Rounded Theme which you can find here

type: custom:android-tv-card
remote_id: remote.wohnzimmer
slider_id: media_player.denon_avr_2113
button_style:
  width: 100px
  height: 100px
  border-radius: 20px
  background: var(--contrast3)
  '--size': 32px
touchpad_style:
  height: 200px
  background: url( '{{ state_attr("media_player.vu_wohnzimmer", "entity_picture") }}') center no-repeat
  background-color: var(--contrast3)
slider_style:
  '--border-radius': 12px
  height: 24px
  '--background-height': 12px
  '--color': var(--contrast18)
  '--background': var(--contrast3) 
rows:
  - - exit
    - home
    - power
  - - menu
    - channelup
    - channeldown  
  - - volume_slider    
  - - navigation_touchpad
  - - red
    - green
    - yellow
    - blue
custom_keys:
  power:
    icon: mdi:power
    service: select.select_option
    service_data:
      entity_id: select.wohnzimmer_activities 
      option: power_off
    style:
      color: |
        {% if is_state("select.wohnzimmer_activities", "Fernsehen") %}
          var(--black)          
        {% endif %}        
      background: |
        {% if is_state("select.wohnzimmer_activities", "Fernsehen") %}
          var(--red) 
        {% elif is_state("select.wohnzimmer_activities", "power_off") %}
          var(--green)                      
        {% endif %}  
  menu:
    icon: mdi:menu
    service: remote.send_command
    service_data:
      device: 26195962
      command: Menu   
      entity_id: remote.wohnzimmer     
  channelup: 
    icon: mdi:arrow-up-circle
    service: remote.send_command
    service_data:
      device: 26195962
      command: ChannelUp    
      entity_id: remote.wohnzimmer 
  channeldown: 
    icon: mdi:arrow-down-circle
    service: remote.send_command
    service_data:
      device: 26195962
      command: ChannelDown  
      entity_id: remote.wohnzimmer        
  yellow:
    entity: remote.wohnzimmer
    icon: mdi:circle
    service: remote.send_command
    service_data:  
      device: 26195962
      command: Yellow 
      entity_id: remote.wohnzimmer 
    style:       
      border-radius: 22px
      background: var(--contrast3)
      color: var(--yellow) 
      height: 40px  
      '--size': 25px     
      width: 75px          
  blue:
    entity: remote.wohnzimmer
    icon: mdi:circle
    service: remote.send_command
    service_data:  
      device: 26195962
      command: Blue 
      entity_id: remote.wohnzimmer 
    style:       
      border-radius: 22px
      background: var(--contrast3)
      color: var(--blue) 
      height: 40px
      '--size': 25px  
      width: 75px                        
  red:
    entity: remote.wohnzimmer
    icon: mdi:circle
    service: remote.send_command
    service_data:  
      device: 26195962
      command: Red
      entity_id: remote.wohnzimmer 
    style:       
      border-radius: 22px
      background: var(--contrast3)
      color: var(--red) 
      height: 40px       
      '--size': 25px   
      width: 75px                
  green:
    entity: remote.wohnzimmer
    icon: mdi:circle
    service: remote.send_command
    service_data:  
      device: 26195962
      command: Green
      entity_id: remote.wohnzimmer 
    style:       
      border-radius: 22px
      background: var(--contrast3)
      color: var(--green)    
      height: 40px    
      '--size': 25px  
      width: 75px                    
  up:
    icon: mdi:arrow-up-bold
    service: remote.send_command
    entity: remote.wohnzimmer
    service_data:    
      device: 26195962
      command: DirectionUp
      entity_id: remote.wohnzimmer
  right:
    icon: mdi:arrow-right-bold
    service: remote.send_command
    service_data:
      device: 26195962
      command: DirectionRight
      entity_id: remote.wohnzimmer
  left:
    icon: mdi:arrow-left-bold
    service: remote.send_command
    service_data:
      device: 26195962
      command: DirectionLeft
      entity_id: remote.wohnzimmer
  down:
    icon: mdi:arrow-down-bold
    service: remote.send_command
    service_data:
      device: 26195962
      command: DirectionDown   
      entity_id: remote.wohnzimmer
  center:
    icon: mdi:circle-outline
    service: remote.send_command
    service_data:
      device: 26195962
      command: OK       
      entity_id: remote.wohnzimmer
  exit:    
    icon: mdi:keyboard-return
    service: remote.send_command
    service_data:        
      device: 26195962
      command: Exit    
      entity_id: remote.wohnzimmer    
3 Likes

Not sure what a TV hotbar is

essentially on the Sony Bravia TV remote thereā€™s a button (gear icon) that when pressed displays a small bar on the bottom of the TV with some pre-configured options (to quickly switch picture / audio modes, change brightness but also to just turn off the screen). I guess itā€™s just a collection of specific functions that are in the main settings as well, but just presented to you in an easier accessible way.

Unfortunately Iā€™m out of my depth to even begin trying to find out how to figure out how that command is being sent to the TV

You should look into the Sony Bravia TV Home Assistant integration and see if it does what you need. If not you could also look into a smart IR remote like a Broadlink (which I personally use for TV and AV receiver controls) to learn and send IR and RF remote commands.

Right you are, in the log I found that ā€œPictureOffā€ corresponds to the key command to turn off the screen. Tried it via Developer Tools ā†’ Service Calls ā†’ Remote:Send command and it works.

Now Iā€™m trying to integrate into the custom card, but am struggling to correctly define th custom key. Could me out how to do it properly?

Hereā€™s how the service call that works in developer tools looks like

service: remote.send_command
target:
  entity_id:
    - remote.sony_bravia_tv
  device_id: []
  area_id: []
data:
  command: PictureOff

trying to implement it like this in the custom card:

type: custom:android-tv-card
remote_id: remote.sony_xr_65a83j
slider_id: media_player.sony_bravia_tv
keyboard_id: remote.sony_xr_65a83j_adb
title: Fernseher
custom_keys:
  screen_off:
    icon: mdi:selection-remove
    service: remote.send_command
    target:
      entity_id:
        - remote.sony_bravia_tv
      data:
        command: PictureOff
rows:
  - - back
    - power
    - home
    - screen_off

but then I get the following error:
image

I tried to change the remote_id further up in the custom card, and then the command just works, but then I lose the functionality of the other commands youā€™ve programmed

Your data block is an indent level too deep.

type: custom:android-tv-card
remote_id: remote.sony_xr_65a83j
slider_id: media_player.sony_bravia_tv
keyboard_id: remote.sony_xr_65a83j_adb
title: Fernseher
custom_keys:
  screen_off:
    icon: mdi:selection-remove
    service: remote.send_command
    target:
      entity_id:
        - remote.sony_bravia_tv
    data:
      command: PictureOff
rows:
  - - back
    - power
    - home
    - screen_off

I also have my personal remote in popup controls using browser mod popup cards, card-mod, and layout-card media queries for horizontal and vertical layouts, which is opened via a regular Home Assistant button set to the remote entity.

type: custom:popup-card
card:
  type: custom:layout-card
  cards:
    - type: tile
      entity: media_player.lounge_tv
      icon_tap_action:
        action: toggle
      vertical: false
    - type: custom:android-tv-card
      remote_id: remote.lounge_google_tv
      adb_id: media_player.lounge_google_tv_adb
      custom_keys:
        volume_down:
          service: script.amplifier_volume_down
        volume_mute:
          service: script.amplifier_volume_mute
        volume_up:
          service: script.amplifier_volume_up
      alt_volume_icons: true
      rows:
        - - - - back
              - null
              - home
              - null
              - menu
            - - volume_down
              - null
              - volume_mute
              - null
              - volume_up
            - - rewind
              - null
              - play_pause
              - null
              - fast_forward
            - - netflix
              - disney
              - hulu
              - max
              - primevideo
            - - plex
              - vudu
              - youtube
              - spotify
          - - - keyboard
              - search
            - - navigation_touchpad
      touchpad_height: 325px
      view_layout:
        show:
          mediaquery: '(orientation: landscape)'
      card_mod:
        style: |
          ha-card {
            padding: 0 !important;
          }
    - type: custom:android-tv-card
      remote_id: remote.lounge_google_tv
      adb_id: media_player.lounge_google_tv_adb
      alt_volume_icons: true
      custom_keys:
        volume_down:
          service: script.amplifier_volume_down
        volume_mute:
          service: script.amplifier_volume_mute
        volume_up:
          service: script.amplifier_volume_up
      touchpad_height: 340px
      rows:
        - - back
          - home
          - play_pause
        - - keyboard
          - search
        - - volume_buttons
        - - navigation_touchpad
      view_layout:
        show:
          mediaquery: '(orientation: portrait)'
      card_mod:
        style: |
          ha-card {
            padding: 0 !important;
          }
  layout_type: custom:grid-layout
entity: remote.lounge_google_tv
size: fullscreen
dismissable: true
card_mod:
  style:
    .: |
      div.content {
        height: fit-content !important;
      }
    ha-dialog$: |
      .mdc-dialog__surface {
        border-radius: var(--ha-card-border-radius) !important;        
      }
      .mdc-dialog__container {
        flex-direction: column !important;
      }
      .mdc-dialog {
        --mdc-dialog-min-width: 95vw !important;
        --mdc-dialog-min-height: fit-content !important;
      }


2 Likes

Version 3.2.0 has just been released! This version changes custom action syntax to follow the Home Assistant actions format, and adds support for remappable double tap and hold actions for custom buttons. The following action types are now supported:

  • key
  • source
  • call-service
  • navigate
  • url

Iā€™ve also refactored and improved how double taps, holds, and touchpad swipes are processed so they now work on all platforms! You can use them on any chromium based or Firefox desktop browser, and the Home Assistant apps on Android and iPhone.

This release does deprecate a few fields related to remapping touchpad actions and changes the format of custom actions (formerly custom keys and sources), but old configurations should continue to work and get internally upgraded to work with the refactored tap/double tap/hold action logic.

1 Like

Hi, I am looking to use the commands learned via Broadlink RM4 mini, however, it is not working. I have already tested the commands and they work via script. Is it possible to use this custom card together with the learned commands?

type: custom:android-tv-card
        title: TV Box
        custom_keys:
          power:
            service: remote.send_command
            target:
              entity_id: remote.control_universal_master
            data:
              device: TVBox_fision
              command:
                - power
          channel_up:
            service: remote.send_command
            target:
              entity_id: remote.control_universal_master
            data:
              device: TVBox_fision
              command:
                - channel_up
          channel_down:
            service: remote.send_command
            target:
              entity_id: remote.control_universal_master
            data:
              device: TVBox_fision
              command:
                - channel_down
          volume_up:
          volume_down:
          info:
          menu:
          back:
          guide:
        rows:
          - - power
          - - back
            - home
            - tv
            - netflix
          - - youtube
            - spotify
            - netflix
          - - touchpad
          - - slider
          - - channel_up
            - channel_down
            - info
          - - rewind
            - play
            - spotify
            - pause
            - fast_forward
1 Like