Authentic-looking Roku remote

That was the first thing I tried once I finished setting up the code. I just now double-checked and I don’t see the card edit buttons and options.

@diedrichg If you take out the custom header stuff (right after views: everything between layout_type and layout, including the layout subentries), it’ll become a regular card you can cut and paste. It messes up the sizing, but you should be able to deal with that with some experimentation.

Fairly new to HA. For some reason when I copy/paste and replace the remote sources with my Roku tv entity name, all I see is this in the dashboard/view

Did you place that rokunew.png file in your /usr/share/hassio/homeassistant/www folder?

(That’s the folder name in a supervised installation. It may be different in yours. Look for the www subdirectory in the same directory as your configuration.yaml file.)

1 Like

I know this is old, but I’m struggling with the image. I have:

image: /homeassistant/www/rokunew.png

replacing:
https://[EXTERNAL HOME ASSISTANT WEB ADDRESS:PORT]/local/rokunew.png?v=1

in the your posted code, but I don’t get the image. I can see it exists in the /www folder via ssh. Can’t tell what I’ve got wrong.

thanks

Did you try a hard refresh of the webpage? (Shift-refresh on a Chrome browser.). Or try opening it in an incognito window and see if you can see it.

It may be a browser cache problem.

Alternatively, try changing “v=1” to “v=2” in the code.

Got it, thanks!

Thought I had it … wrong again.
I have image statement:
image: >-
http://192.168.4.130:8123/api/hassio_ingress/8LQeR1SxTUl7slivzAMk1NIyCzSK0BVlr8XA4jTxpVg/api/file?filename=/homeassistant/www/rokunew.png

It shows me the correct image on (Windows 10) Edge.
Does not show me image on the same computer in Opera or Chrome.
Does not show me image on Linux box in Firefox.
Note: in all cases I see the rest of the card – the volume buttons

It really sounds like a browser cache problem. You might consider clearing all the data for your Home Assistant website on your browser. Also change “v=1” to “v=2” (or another number) in the code (you don’t have to do anything to the actual image). I’m no expert on this stuff.

Is there a way to make the search function work? So I can type in the movie I want on Home Assistant instead of using the arrow keys?

Pretty sure it’s not a browser cache problem since at least one of my browser tries was from a linux box that had never connected to my HA. Feel like it’s a path thing. Note that my image path
http://192.168.4.130:8123/api/hassio_ingress/8LQeR1SxTUl7slivzAMk1NIyCzSK0BVlr8XA4jTxpVg/api/file?filename=/homeassistant/www/rokunew.png
does not have your:
image: https://[EXTERNAL HOME ASSISTANT WEB ADDRESS:PORT]/local/rokunew.png?v=1

?v=1 at the end. If I try https:\, I get nothing. If I try adding the ?v=1 I get nothing (meaning no image in any browser)

My only goal was to mimic the physical Roku remote control, using the buttons documented in the Roku Home Assistant integration. Implementing a search function would be a whole other project.

Why aren’t you using the web address I suggested? After the 8123, insert the rest of the address.

Try this:

image: /local/rokunew.png?v=1

Then it will use the base URL of wherever you come from.

1 Like

@NYZack
Thanks for this. I am loving it.

I have expanded it a bit using decluttering templates to setup multiple rooms on one card. Just wanted to give back.

I have multiple situations.

Livingroom has a Roku TV. HA can control the volume. It also has a remote that has the find option.

Basement has a Roku stick in a TV that does not pass volume control through the HDMI port. And, the remote does not have the find option.

So, I setup two decluttering templates. One that does the remote. A second that does volume and find remote based on the settings used in the decluttering card.

This is the full dashboard in the Raw Configuration Editor.

It also shows the active application on the Roku.

decluttering_templates:
  remote:
    card:
      type: picture-elements
      view_layout:
        grid-area: main
      elements:
        - type: service-button
          service: remote.send_command
          service_data:
            command: power
            entity_id: remote.[[roku_location]]
          style:
            top: 6%
            left: 50%
        - type: service-button
          service: remote.send_command
          service_data:
            command: back
            entity_id: remote.[[roku_location]]
          style:
            top: 14%
            left: 31%
        - type: service-button
          service: remote.send_command
          service_data:
            command: home
            entity_id: remote.[[roku_location]]
          style:
            top: 14%
            left: 70%
        - type: service-button
          service: remote.send_command
          service_data:
            command: up
            entity_id: remote.[[roku_location]]
          style:
            top: 22%
            left: 50%
        - type: service-button
          service: remote.send_command
          service_data:
            command: left
            entity_id: remote.[[roku_location]]
          style:
            top: 29%
            left: 24%
        - type: service-button
          service: remote.send_command
          service_data:
            command: select
            entity_id: remote.[[roku_location]]
          style:
            top: 29%
            left: 50%
        - type: service-button
          service: remote.send_command
          service_data:
            command: right
            entity_id: remote.[[roku_location]]
          style:
            top: 29%
            left: 76%
        - type: service-button
          service: remote.send_command
          service_data:
            command: down
            entity_id: remote.[[roku_location]]
          style:
            top: 39%
            left: 50%
        - type: service-button
          service: remote.send_command
          service_data:
            command: replay
            entity_id: remote.[[roku_location]]
          style:
            top: 46%
            left: 32%
        - type: service-button
          service: remote.send_command
          service_data:
            command: info
            entity_id: remote.[[roku_location]]
          style:
            top: 46%
            left: 70%
        - type: service-button
          service: remote.send_command
          service_data:
            command: reverse
            entity_id: remote.[[roku_location]]
          style:
            top: 53%
            left: 26%
        - type: service-button
          service: remote.send_command
          service_data:
            command: play
            entity_id: remote.[[roku_location]]
          style:
            top: 53%
            left: 50%
        - type: service-button
          service: remote.send_command
          service_data:
            command: forward
            entity_id: remote.[[roku_location]]
          style:
            top: 53%
            left: 75%
        - type: service-button
          service: media_player.select_source
          service_data:
            source: YouTube TV
            entity_id: media_player.[[roku_location]]
          style:
            top: 64%
            left: 50%
        - type: service-button
          service: media_player.select_source
          service_data:
            source: MLB
            entity_id: media_player.[[roku_location]]
          style:
            top: 70%
            left: 50%
        - type: service-button
          service: media_player.select_source
          service_data:
            source: Plex - Free Movies & TV
            entity_id: media_player.[[roku_location]]
          style:
            top: 77%
            left: 50%
        - type: service-button
          service: media_player.select_source
          service_data:
            source: Prime Video
            entity_id: media_player.[[roku_location]]
          style:
            top: 84%
            left: 50%
      image: /local/images/rokunew.png?v=1
  options:
    default:
      - volume: 'no'
      - find_remote: 'no'
    card:
      type: vertical-stack
      cards:
        - type: custom:state-switch
          entity: '{% if ''yes'' == ''[[volume]]'' %} yes {% else %} no {% endif %}'
          states:
            'yes':
              type: horizontal-stack
              cards:
                - type: button
                  icon: mdi:volume-minus
                  icon_height: 20px
                  show_icon: true
                  name: Decrease
                  show_name: false
                  tap_action:
                    action: call-service
                    service: remote.send_command
                    data:
                      command: volume_down
                    target:
                      entity_id: remote.[[roku_location]]
                - type: button
                  icon: mdi:volume-plus
                  icon_height: 20px
                  show_icon: true
                  name: Increase
                  show_name: false
                  tap_action:
                    action: call-service
                    service: remote.send_command
                    data:
                      command: volume_up
                    target:
                      entity_id: remote.[[roku_location]]
                - type: button
                  icon: mdi:volume-mute
                  icon_height: 20px
                  show_icon: true
                  name: Mute
                  show_name: false
                  tap_action:
                    action: call-service
                    service: remote.send_command
                    data:
                      command: volume_mute
                    target:
                      entity_id: remote.[[roku_location]]
        - type: custom:state-switch
          entity: '{% if ''yes'' == ''[[find_remote]]'' %} yes {% else %} no {% endif %}'
          states:
            'yes':
              type: button
              show_icon: false
              name: Find Remote
              show_name: true
              tap_action:
                action: call-service
                service: remote.send_command
                target:
                  entity_id: remote.[[roku_location]]
                data:
                  command:
                    - find_remote
        - type: markdown
          content: >
            Current App <img src = '{{
            state_attr('media_player.[[roku_location]]', 'entity_picture') }}'
            height='60' width='150'></img>
          theme: no_border
views:
  - title: Livingroom
    theme: Backend-selected
    type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: 230px 180px
      grid-template-rows: auto
      grid-template-areas: |
        "main sidebar"
    path: livingroom_remote
    subview: false
    badges: []
    cards:
      - type: custom:decluttering-card
        template: remote
        variables:
          - roku_location: livingroom
      - type: custom:decluttering-card
        template: options
        variables:
          - roku_location: livingroom
          - volume: 'yes'
          - find_remote: 'yes'
  - title: Basement
    theme: Backend-selected
    type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: 230px 180px
      grid-template-rows: auto
      grid-template-areas: |
        "main sidebar"
    path: basement_remote
    subview: false
    badges: []
    cards:
      - type: custom:decluttering-card
        template: remote
        variables:
          - roku_location: basement
      - type: custom:decluttering-card
        template: options
        variables:
          - roku_location: basement


We use Youtube TV subscription to watch TV. The Roku add-on does handle deep linking, but not just to change the channel.

I am working on more code for this to select channels from HA. But, it is annoying because it must restart Youtube TV to select the channel. I have a couple emails to support and they are not much ‘support’ :slight_smile:

I’ll post what I come up with when complete.

Are you aware of a way to add haptics to the remote on mobile devices? Other remote cards, etc seem to have this functionality. If you don’t mind, I may decide to contribute some effort to this as a minor QoL addition especially if there’s a known method.

Also, has anyone found the different parameters for making this its own card, instead of its own dashboard?

With regard to its being its own card - it IS its own card. As discussed above, I don’t think it can be manipulated via the UI, but you can cut and paste the code as a card like any other card using the raw configuration editor. I organized it the way I did in order to fine-tune the widths of the volume controls next to the Roku remote, but with a little tweaking, it’s totally a stand-alone card. (Try cutting and pasting the entire picture-elements card in the “cards” section.)

I’m not aware of the ability to control haptics on mobile devices via scripts in Home Assistant, but I haven’t looked hard for that functionality. If you can find any way of manipulating haptics via a script, it shouldn’t be hard to implement.

I have decided to start a new thread that points back here as it will certainly go into several things that lead away from your wonderful work.

As an alternative for anyone who might be interested, the Firemote Card now supports Roku devices.

1 Like

I finally got a chance to make a post expanding on this great work by @NYZack.

It is mostly specific to YouTubeTV on Roku. I hope it can help someone.
Authentic Roku Remote and YouTube TV - Share your Projects! / Dashboards & Frontend - Home Assistant Community (home-assistant.io)