Fire TV Channel Picker

Good day everyone. I wanted to show off / get suggestions on something I put together on my HomeAssistant. Basically, a panel that controls the FireTV. I built this for the household, but largely with my son in mind. He is a smart kid, but due to some misfortune in life’s genetic lottery, he is completely nonverbal. This makes the voice-control setup of the FireTV impossible for him. Add to that the near impossibility of keeping track of physical remotes, and he is unable to properly control the entertainment systems. With this setup, he can bring up his favorite channels and even go directly to his favorite movie (note the Garfield button) with a single visual tap.

Item #1 is just an entity card on the Harmony Hub, which shows the activity, which will say something like “PowerOff” / “Nintendo” / “XBox” kinds of things. Display only.

Item #2 is a series of buttons that send volume change commands to the media_player, which winds up changing the audible volume of the FireTV. One example:

- show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: media_player.volume_set
      data:
        volume_level: 0.25
      target:
        entity_id: media_player.fire_projector
    name: Low Volume
    icon: mdi:volume-low

Item #3 is the Harmony Hub card I found on this forum which basically sends remote control commands to the Harmony Hub, which is mapped as an added-on keyboard to the FireTV. This is how to navigate menus.

type: custom:harmony-card
entity: remote.harmony_hub
name: ' '
volume_entity: media_player.fire_projector
activities:
  - name: Watch Fire TV
    device: Amazon Fire TV
  - name: Play Nintendo Switch
    device: Acer Projector
    volume_device: Acer Projector
  - name: Play Xbox One
    device: Basement Xbox Series X
    volume_device: Acer Projector
show_error: false
show_warning: false
hide_activities: true

Item #4 (and relatedly #5) is where I’m pleased with my outcome, but very certain that I went about solving this the wrong way entirely, and would love feedback around that.

#4 is a grid of Images with tap handlers, like this:

type: picture
image: >-
  https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.XhbxkAg778EImtC55tfYSgHaHa%26pid%3DApi&f=1&ipt=6191730efaae5653aeae17056135e10ca8b8b7adef91d4167542c2b5011d2e8c&ipo=images
hold_action:
  action: none
tap_action:
  action: call-service
  service: script.open_youtube_to_fire_tv
  data: {}
  target: {}

The image is usually used to pick the logo for the channel for ease of use. The script it calls:

alias: Open YouTube on Basement FireTV
use_blueprint:
  path: MyBlueprints/command_basement_firetv.yaml
  input:
    command_name: Open YouTube
icon: mdi:cast-connected
mode: single

Which is of course meaningless without the underlying blueprint:

blueprint:

  name: Issue Command to Basement FireTV

  description: Issues a given command to the fireTV as though it had heard you speak it.  Will also switch on the projector and adjust inputs as necessary.

  domain: script

  input:

    command_name:

      name: Command Input

      description: This is the text that will be sent to Alexa as if spoken.

max_exceeded: silent

sequence:

  - variables:

      wait_delay: 1

  - service: media_player.play_media

    target:

      entity_id: media_player.fire_projector

    data:

      media_content_type: sound

      media_content_id: amzn_sfx_doorbell_chime_01

  - if:

      - alias: "If we need to wait for projector boot-up"

        condition: state

        entity_id: select.harmony_hub_activities

        state: "power_off"

    then:

      - service: remote.turn_on

        target:

          entity_id: remote.harmony_hub

        data:

          activity: "Watch Fire TV"

      - alias: "Wait 60 seconds for boot"

        delay:

          seconds: 60

      - service: script.projector_zoom_fix

  - if:

      - alias: "If we need to wait for activity swap"

        condition: state

        entity_id: select.harmony_hub_activities

        state: "Watch Fire TV"

    then:

      - service: remote.turn_on

        target:

          entity_id: remote.harmony_hub

        data:

          activity: "Watch Fire TV"

    else:

      - service: remote.turn_on

        target:

          entity_id: remote.harmony_hub

        data:

          activity: "Watch Fire TV"

      - alias: "Wait 20 seconds for boot"

        delay:

          seconds: 15

  - service: media_player.play_media

    target:

      entity_id: media_player.fire_projector

    data:

      media_content_type: custom

      media_content_id: !input command_name

mode: single

The content around sleeping for X seconds is mostly to give the hardware time to catch up, waiting for projector bulbs to warm up, that kind of thing. The last bit is I think the interesting part: By passing the command name in, the FireTV responds as though you’ve said that bit to it out loud. It even verbally responds “Sure, here’s YouTube!”. So anything that can be a text command can be a button. As you may have gathered by now, #5 lets you send arbitrary text, which is surprisingly useful (as the text stays on the screen forever, so if you’re binging a show, you leave that as the text and its a one-click to see the next episode):

type: entities
entities:
  - entity: input_text.fire_projector_command_text
title: FireTV Command
footer:
  type: buttons
  entities:
    - entity: script.issue_inputted_command_to_basement_firetv
      name: Issue Command
      icon: mdi:send-circle
state_color: false

Where I feel like I hacked something that might have an elegant solution:

1- I can’t figure out for the life of me how to pass parameters to scripts in YAML. As a result, every single button on the screen has a hard-copy of the main script with the only alteration being the text passed in. This makes it more work than I’d like it to be to add buttons, and moves the complexity of it out of reach for most of the household (who might otherwise like to add their own favorites).

2- Right now, the “list” of commands only exists as this YAML in the dashboard. I want to be able to have this “panel” (terminology check: what I mean is “this small portion of my dashboard”) something that I can put in multiple dashboards. Right now, if I do that, and I add a new item to the panel, I have to manually copy-paste that item across to the other dashboards to keep them in sync. I feel like if I could somehow store this in a generalized data structure (if I were doing this at work, I’d be talking about creating a new table in SQL or some kind of persisted Dictionary<string,poco>), and then have the UI have some kind of custom card that queries the entity and builds the view dynamically, I’d have something more scalable and useful. I strongly suspect there’s an easier way to do this inside the HomeAssistant eco system than trying to run my own little SQLite DB just for something like this.

3- I’d love it if the screen could show some kind of view of what the FireTV is currently playing (Something like “FireTV - YouTube” or “FireTV - Star Trek: The Trekening”). The blacked-out parts of the screen represent my currently failed but work-in-progress attempts to extract that value.

1 Like

Check out the Android Debig Bridge integration. Throw the fire into dev node and then add the integration.

It enables the Custom Firemote card and some other interesting tricks.

So once you do that, the card has an input selector (apps) that the author maintains. And you can present it as a simplified list.

The android debug bridge can also snapshot the screen and it’s dropped into the media players picture entity so… Screen preview on most media player cards.

3 Likes