Native support for Fire TV


#41

It might have to do with the fact that adb and firetv need to be installed from GitHub, as indicated in REQUIREMENTS. Try sudo -H pip install https://github.com/JeffLIrion/python-firetv/zipball/master, and accordingly for adb. Then check to make sure that you have the forked versions of those packages. For example, you can check whether FireTV (in the installed firetv package) accepts a parameter adbkey.

Or you could install another HA instance in a virtual environment (using a different port in your configuration) and only add the Fire TVs to your configuration.


#42

Hi!
I can’t tell what happened but now it works :raised_hands:. I did not have to install any packages on my hassio system.
Thanks again :smiley:


#43

Awesome! Thanks for giving it a shot and providing feedback!


#44

Check your pull requests - it shouldn’t be necessary to install the requirements manually anymore.

To elaborate:

  • Copied your custom component over, adjusted configuration.yaml
  • Restarted HASS
  • It kept trying to install M2Crypto (while installing deps for python-firetv - the git version -> adb from pip)

This was caused by python-firetv having a dependency on adb in setup.py - so before the git version of adb could be installed, it was trying to get from pip.

Fix:

  • Move adb requirement from custom component to python-firetv/setup.py

Now its all good :wink:


#45

With the changes I made yesterday, I think it already shouldn’t have been necessary to install any requirements manually. Nonetheless, you make a valid point about where the requirements belong, so I merged your pull requests. Thanks!

Once more people have tested it, I’d like to get my forked versions of python-adb and python-firetv merged so that I can submit this component to Home Assistant.


#46

Sorry, I didn’t verify the layout of setup.py afterwards :confused:
Now you have the proper order in the REQUIREMENTS, to first install patched adb, then firetv module… it’s the same outcome :nerd_face:


#48

Hey folks,
Just tried this out (and thanks for pulling together, hoping this will get over the Auth issue preventing FireTV being used). Got the following issue, which doesn’t seem present in the above threads (that i can see):
Just updated to 0.76.2 on docker

custom_components/media-player/android/ - containing the adbkey and adbkey.pub

custom_components/media-player/ - containing the firetv.py from the repo

- platform: firetv
        host: XXXX:5555
        name: Bedroom FireTV
        adbkey: "/config/custom_components/media_player/android/adbkey"
      - platform: firetv
        host: XXXX:5555
        name: Living Room FireTV
        adbkey: "/config/custom_components/media_player/android/adbkey"

Error message:

    2018-08-26 21:40:41 ERROR (MainThread) [homeassistant.components.media_player] Error while setting up platform firetv
    Traceback (most recent call last):
      File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 226, in Unpack
        cls.format, message)
    struct.error: unpack requires a buffer of 24 bytes

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/src/app/homeassistant/helpers/entity_platform.py", line 129, in _async_setup_platform
        SLOW_SETUP_MAX_WAIT, loop=hass.loop)
      File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
        return fut.result()
      File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
        result = self.fn(*self.args, **self.kwargs)
      File "/config/custom_components/media_player/firetv.py", line 53, in setup_platform
        device = FireTVDevice(host, name, adbkey)
      File "/config/custom_components/media_player/firetv.py", line 91, in __init__
        self._firetv = FireTV(host, adbkey)
      File "/config/deps/lib/python3.6/site-packages/firetv/__init__.py", line 105, in __init__
        self.connect()
      File "/config/deps/lib/python3.6/site-packages/firetv/__init__.py", line 118, in connect
        self._adb = adb_commands.AdbCommands().ConnectDevice(serial=self.host, rsa_keys=[signer])
      File "/config/deps/lib/python3.6/site-packages/adb/adb_commands.py", line 142, in ConnectDevice
        self._Connect(**kwargs)
      File "/config/deps/lib/python3.6/site-packages/adb/adb_commands.py", line 173, in _Connect
        conn_str = self.protocol_handler.Connect(self._handle, banner=banner, **kwargs)
      File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 314, in Connect
        cmd, arg0, arg1, banner = cls.Read(usb, [b'CNXN', b'AUTH'])
      File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 243, in Read
        cmd, arg0, arg1, data_length, data_checksum = cls.Unpack(msg)
      File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 228, in Unpack
        raise ValueError('Unable to unpack ADB command.', cls.format, message, e)
    ValueError: ('Unable to unpack ADB command.', b'<6I', b'', error('unpack requires a buffer of 24 bytes',))

any help very much welcomed as not really sure where to start with this error.


#49

I’ve gotten that issue before. Unfortunately, I don’t remember exactly what the fix is… But here’s a few things to try.

  1. Make sure you’re using my forked version of adb. To do this, insert the following lines into the firetv.py file after the _LOGGER line. If your log says that your version is 1.3.0, then you’re using the pypi version. If it says 1.3.0.1, then you’re using my forked version.

    _LOGGER = logging.getLogger(__name__)
    
    import inspect
    from adb import adb_commands
    adb_commands_source = inspect.getsource(adb_commands)
    adb_version = '1.3.0' if adb_commands_source.splitlines()[129].strip() == "elif serial and ':' in serial:" else '1.3.0.1'
    _LOGGER.fatal('adb version = {0}'.format(adb_version))
    
  2. Try restarting Home Assistant. I think I got an error the first time I used this custom component, but I restarted Home Assistant and it worked and I haven’t gotten that error since.

  3. For the sake of debugging, remove one of your Fire TV instances from your configuration and turn on the other Fire TV device. Restart HA. Your Fire TV should ask if you want to allow the device to connect via ADB, so say yes and permanently allow that device. Home Assistant will probably fail to setup the Fire TV because it will take too long, but it should work correctly when you restart because now the Fire TV will allow the connection right away.

Let me know if any of this works for you!


#50

This morning, my second Fire TV stick started requiring ADB authentication, and in the process of getting it re-integrated into Home Assistant I learned that ADB authentication with this component will only work using a trusted key!

I added the following to the README:

ADB Authentication (for Fire TV devices with recent software)

If you get a “Device authentication required, no keys available” error when trying to setup Fire TV, then you’ll need to create an adbkey and add its path to your configuration. Follow the instructions on this page to connect to your Fire TV from your computer: Connecting to Fire TV Through adb.

Important! You must check the box that says “always allow connections from this device.” ADB authentication in Home Assistant will only work using a trusted key.

Once you’ve successfully connected to your Fire TV via the command adb connect <ipaddress> , the files adbkey and adbkey.pub will be created on your computer. Copy these to your Home Assistant folder and add the path to the adbkey file to your configuration.


#51

Not working for me. I created the custom_components/media_player/firetv.py. Here’s my config:

- platform: firetv
  name: Fire TV
  host: 'xxx.xxx.xxx.xxx:5555'
  adbkey: '/config/adbkey'

The x’s are replaced with the firetv’s IP.
The adbkey I got by using adb on a different computer than the one running home assistant. I put both adbkey and adbkey.pub in the /config folder.

Here’s what I get in the logs with debug logging enabled:

2018-08-30 05:10:43 INFO (MainThread) [homeassistant.loader] Loaded media_player from homeassistant.components.media_player
2018-08-30 05:10:43 INFO (MainThread) [homeassistant.loader] Loaded media_player.firetv from homeassistant.components.media_player.firetv
2018-08-30 05:10:44 INFO (MainThread) [homeassistant.setup] Setting up media_player
2018-08-30 05:10:44 INFO (MainThread) [homeassistant.components.media_player] Setting up media_player.firetv
2018-08-30 05:10:44 ERROR (SyncWorker_18) [homeassistant.components.media_player.firetv] Could not connect to firetv-server at xxx.xxx.xxx.xxx:5555

That’s all I get. Any ideas on what could be wrong? Looks like it’s using the origin firetv component under components/media_player/firetv.py and not the custom one under custom_components/media_player/firetv.py

Update:
OK, I had put the file in the wrong folder. It should be in <config_dir>/custom_components/media_player/firetv.py. I had missed the <config_dir> part and instead put it in the homeassistant python package location.


#52

It’s definitely using the built-in component, not the custom component. Did you put firetv.py in the right place? The custom_components folder should be in your configuration directory.


#53

Yep, that was the issue. My bad :slight_smile:


#54

So is it working for you now? Did you encounter any issues when setting it up?


#55

It seems to be loading fine. I see no error messages and the card shows up in the UI. I haven’t been able to test its functionality yet. I’ll have to do that tonight. But so far it looks very promising and much better than running a separate container with a server.


#56

I have multiple firesticks. So far 2 are showing up. The others I am having issues with the need for ADB authentication.
I ran adb connect from my laptop to each of the firestick by IP address, connected and got the adbkey and adbkey.pub. Now:
where exactly do I put them and how do I deal with more than one key (more than one firestick)?

PI3B+, hass.io 1.10, HA 0.77.1


#57

First of all, I would suggest using the same key to connect to all of your Fire TV sticks that require authentication. In my case, when I connected from my laptop to my first Fire TV it put the key files in $HOME/.android. When I connected from my laptop to my second Fire TV stick, it automatically used the same key. If you do have multiple keys, you could either rename them as “adbkey1” & “adbkey1.pub”, “adbkey2” & “adbkey2.pub”, etc. (I don’t know if this would work) or put the key files in separate folders, such as /android1, /android2, etc. Then in your configuration, make sure that for each Fire TV you specify the path to the correct key.

You should put the key files in your Home Assistant configuration folder. My HA configuration on Hassio is /config, so I copied the key files from my laptop and put them in /config/android and specified the path accordingly, as seen in the sample configuration in the first post.


#58

Okay that worked. The using just a single key for all of them… we have joy with all firesticks.
I guess I deserved all that hair pulling due to my desire to make things complicated rather than just following instructions. :slight_smile:
Thank you very much!


#59

I had a chance to test this today. Everything seems to be working really well. The only thing I noticed, which might by an issue with python-firetv or adb, is, after clicking play on the card in the UI the video starts playing right away on the firetv but the button takes about 5 seconds to switch to pause. Same thing happens when clicking pause. But as far as the work you did getting rid of the firetv server, this is awesome and I think we should move ahead with upstream PRs to get this merged to the mainstream.

Thanks for your work!


#60

That delay in updating the status is just the way it is – every 10 seconds or so Home Assistant updates the state of the Fire TV, which entails sending out some ADB commands. Furthermore, the state of the device isn’t entirely accurate. For example, if you have an app open, I believe it will show the state as “playing.”

BTW, one feature I included is the ability to stop apps. To do so, use the media_player.select_source command and prefix the app name with an exclamation mark. For example, setting the source as !com.netflix.ninja should close Netflix (assuming that’s the right name for the Netflix app).

I plan to merge it into Home Assistant, but I’m currently waiting for this pull request to go through: https://github.com/google/python-adb/pull/119


#61

A final observation other than I love what you did.
If you have to power down your PI HA server, you need to reboot each of your firesticks or they won’t be recognized when you bring your PI back up.

Sun Sep 02 2018 18:41:25 GMT-0500 (Central Daylight Time)

Error while setting up platform firetv
Traceback (most recent call last):
  File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 226, in Unpack
    cls.format, message)
struct.error: unpack requires a buffer of 24 bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/media_player/firetv.py", line 53, in setup_platform
    device = FireTVDevice(host, name, adbkey)
  File "/config/custom_components/media_player/firetv.py", line 91, in __init__
    self._firetv = FireTV(host, adbkey)
  File "/config/deps/lib/python3.6/site-packages/firetv/__init__.py", line 105, in __init__
    self.connect()
  File "/config/deps/lib/python3.6/site-packages/firetv/__init__.py", line 120, in connect
    self._adb = adb_commands.AdbCommands().ConnectDevice(serial=self.host)
  File "/config/deps/lib/python3.6/site-packages/adb/adb_commands.py", line 142, in ConnectDevice
    self._Connect(**kwargs)
  File "/config/deps/lib/python3.6/site-packages/adb/adb_commands.py", line 173, in _Connect
    conn_str = self.protocol_handler.Connect(self._handle, banner=banner, **kwargs)
  File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 314, in Connect
    cmd, arg0, arg1, banner = cls.Read(usb, [b'CNXN', b'AUTH'])
  File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 243, in Read
    cmd, arg0, arg1, data_length, data_checksum = cls.Unpack(msg)
  File "/config/deps/lib/python3.6/site-packages/adb/adb_protocol.py", line 228, in Unpack
    raise ValueError('Unable to unpack ADB command.', cls.format, message, e)
ValueError: ('Unable to unpack ADB command.', b'<6I', b'', error('unpack requires a buffer of 24 bytes',))