Skip to content

Initial support for Apple TV#5698

Merged
balloob merged 3 commits into
home-assistant:devfrom
postlund:apple_tv
Feb 7, 2017
Merged

Initial support for Apple TV#5698
balloob merged 3 commits into
home-assistant:devfrom
postlund:apple_tv

Conversation

@postlund
Copy link
Copy Markdown
Contributor

@postlund postlund commented Feb 1, 2017

Description:
I've been working on a python library for the Apple TV for a while now and finally released the first version. So here is the first rough version of an Apple TV platform. Currently, it has only been tested with an Apple TV 3 as that is all I have. If someone owns a gen 4 device and has some time over, I would appreciate some help :) Feel free to use this issue: postlund/pyatv#3

Once I get some more time, I will add support to netdisco and fix automatic discovery. For now you have to configure it manually. As I said, it's in early development and there are some issues. So hit me with some bug reports!

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#1996

Example entry for configuration.yaml (if applicable):
Just specify IP and a name for the device. You also need an identifier called HSGID, you can find it with the atvremote which you can read about here: https://github.com/postlund/pyatv/blob/master/docs/atvremote.rst

media_player:
  - platform: apple_tv
    name: Apple TV
    host: 10.0.10.22
    login_id: 00000000-1234-5678-7f12-91234567890

Checklist:

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

@homeassistant
Copy link
Copy Markdown
Contributor

Hello @postlund,

When attempting to inspect the commits of your pull request for CLA signature status among all authors we encountered commit(s) which were not linked to a GitHub account, thus not allowing us to determine their status(es).

The commits that are missing a linked GitHub account are the following:

Unfortunately, we are unable to accept this pull request until this situation is corrected.

Here are your options:

  1. If you had an email address set for the commit that simply wasn't linked to your GitHub account you can link that email now and it will retroactively apply to your commits. The simplest way to do this is to click the link to one of the above commits and look for a blue question mark in a blue circle in the top left. Hovering over that bubble will show you what email address you used. Clicking on that button will take you to your email address settings on GitHub. Just add the email address on that page and you're all set. GitHub has more information about this option in their help center.

  2. If you didn't use an email address at all, it was an invalid email, or it's one you can't link to your GitHub, you will need to change the authorship information of the commit and your global Git settings so this doesn't happen again going forward. GitHub provides some great instructions on how to change your authorship information in their help center.

    • If you only made a single commit you should be able to run
      git commit --amend --author="Author Name <email@address.com>"
      
      (substituting Author Name and email@address.com for your actual information) to set the authorship information.
    • If you made more than one commit and the commit with the missing authorship information is not the most recent one you have two options:
      1. You can re-create all commits missing authorship information. This is going to be the easiest solution for developers that aren't extremely confident in their Git and command line skills.
      2. You can use this script that GitHub provides to rewrite history. Please note: this should be used only if you are very confident in your abilities and understand its impacts.
    • Whichever method you choose, I will come by to re-check the pull request once you push the fixes to this branch.

We apologize for this inconvenience, especially since it usually bites new contributors to Home Assistant. We hope you understand the need for us to protect ourselves and the great community we all have built legally. The best thing to come out of this is that you only need to fix this once and it benefits the entire Home Assistant and GitHub community.

Thanks, I look forward to checking this PR again soon! ❤️

@homeassistant
Copy link
Copy Markdown
Contributor

Hi @postlund,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@robbiet480
Copy link
Copy Markdown
Contributor

@postlund This was literally my face when I saw this PR: 😮

SUPER excited to try this out once I get home!!!!!!

/cc @maddox

@robbiet480
Copy link
Copy Markdown
Contributor

I confirmed this works for me on an aTV 4 (and commented on the linked pyatv issue as such)

@maddox
Copy link
Copy Markdown
Contributor

maddox commented Feb 2, 2017

Wow I didn't think this protocol worked for the old apple tvs. I thought it was new for the atv4 and the new remote app. Nice work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the newer access_token implementation. There's an example here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have to implement this yourself - it is implemented in the base class.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I will remove it! 👍

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a problem connection does an error get generated here? If so, we should catch it.

Also, normally we set up the device in the setup_platform call and then pass it into the MediaPlayerDevice class.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's currently not handled, it's part of the "rough version". I will add some error handling as soon as possible. And also fix the setup as you describe.

@robbiet480
Copy link
Copy Markdown
Contributor

@postlund Pressing Pause in Home Assistant pauses my aTV 4 for a split second then it plays again...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is implemented inside the main class, you don't have to do to copy paste it. Please remove it.

Instead, implement the property media_image_url and all will work magically 🌟

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I think I misunderstood have that worked but now I get it. I will fix that as well 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thought one more time about this. I do not expose the image URL from pyatv, just a method that fetches the binary image (as part of my abstraction). I guess this doesn't work with that solution?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't. Would it be possible to expose the url ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@balloob It's possible but would be ugly, because Apple TV requires a somewhat rapidly changing session ID on every request, so now the pyATV library will need to expose that ID to HA for consumption on just this one call...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @robbiet480 says, it would technically be possible but more of a hack. Maybe we could extend the cache somehow so that it would be possible to manually add images to it? I would prefer to remove that part of the code from this integration.

Copy link
Copy Markdown
Member

@balloob balloob Feb 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove all art work from this PR and open a new PR that:

  • The web view will implement the following logic:
if hasattr(player, 'async_get_media_image'):
    image = yield from player.async_media_image()

if image is None and hasattr(player, 'get_media_image'):
    image = yield from self.app['hass''].loop.run_in_executor(None, player.media_image)

if image is None and player.media_image_url:
    image =# fetch image using player.media_image_url

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After that, implementing the coroutine async_get_media_image, or if your lib is not async, implement get_media_image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I like this approach. I will make a new PR for that later tonight or tomorrow 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An issue here, from what I have understood, is that the frontend uses media_entity_image to figure out if there is an image at all. Since that method returns None now, no image is shown. If I just return anything in that method, I can of course intercept the request in view and that works. Any input on how to handle this in a good way?

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 2, 2017

@maddox, I think the API is actually from the older devices. Nowadays there's some "kit" for doing this that probably only works on gen 4 (and later, when that happens). But the old protocol sort-of still works with newer devices as well :) @robbiet480 is testing the library like crazy, so there might be some things to fix in order to be equally compatible with gen 4 devices.

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 5, 2017

Made some updates based on comments and some other fixes. Artwork does currently not work until #5754 is done, but it is prepared for that.

@robbiet480
Copy link
Copy Markdown
Contributor

Since pairing is now functional and netdisco support is forthcoming it may be a good idea to use the configurator to allow interactive pairing through the HASS UI.

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 6, 2017

I agree and it is on my TODO-list. But it might be better to make a new PR for that once I have released the next version of pyatv. My goal is to finish the "play_url" support so that TTS can be used out-of-the-box (it's not that far away now). So if we could get this on dev that would be great!

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 6, 2017

I just realized that I need to write some doc for this before merge. Will do that later tonight.

@rosahas
Copy link
Copy Markdown

rosahas commented Feb 7, 2017

I would love to test out TTS support. I have it working now as a "custom_components". Thanks to @robbiet480 help on the gitter.im

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 7, 2017

I would love some feedback on that. Just pushed necessary updates to this PR, so it should work with Home Assistant. But it's not in pyatv yet. So you will have to clone that repo, switch to branch play_media and install it (or use python setup.py develop). Also, you need to update the version for this component to 0.0.2dev1 as well. Feel free to try it out :)

https://github.com/postlund/pyatv/tree/play_media

@balloob
Copy link
Copy Markdown
Member

balloob commented Feb 7, 2017

Awesome work! 🐬

@balloob balloob merged commit c7e2822 into home-assistant:dev Feb 7, 2017
@rosahas
Copy link
Copy Markdown

rosahas commented Feb 7, 2017

@postlund I will test this out tonight hopefully (play_media) that is.. not sure I followed the update steps for payatv, will try to setup with develop option.

Also, please update the original post, where the example configuration.yaml still says: "hsgid", it looks like now it's "login_id".

Another issues I just noticed. I have two Apple TV Gen 4, similar to @robbiet480. But my atvremote scan shows the two separate Apple TVs, with their correct static IPs, but the HSGID is the exact same. ... which my guess is not correct?

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 7, 2017

@rosahas, great! I'm going try to release the next version of pyatv ASAP so that I hopefully can get that included in the next release of Home Assistant. But if you have any problems, just let me know.

I have updated the instructions, they were indeed incorrect.

Since I don't have more than one Apple TV myself, I'm not sure how HSGID works. But I wouldn't be surprised if they are they same, it is probably associated with your account. Since you are talking with devices on two different IP-address, this shouldn't be a problem. Have you had any issues with this?

@rosahas
Copy link
Copy Markdown

rosahas commented Feb 7, 2017

@postlund just tried to get the dev environment setup. Created an issue on your github:
postlund/pyatv#28

If I can get at least the virtual_env built with the dev code and the new play_media branch, which I assume this will help me create locally, then I can at least test playing media using atvremote from "bin/activate"? Not sure how I would bind that to Home Assistant's configuration.yaml.

I haven't tried setting up the second apple tv, was not sure about the same hsgid, will try it out tonight.

@postlund postlund deleted the apple_tv branch February 7, 2017 20:40
@rosahas
Copy link
Copy Markdown

rosahas commented Feb 8, 2017

@postlund yes, I was able to play the sample video on my Apple TV! I can "turn_on" the media, but i can't "turn_off". I don't think that's implemented, perhaps the Standby is implemented, but not sure what the command is for that?

If everything is off, just turning on the Apple TV gets the rest of my components to start. But, it's failing on "turn_off" command at the moment. I will also have to increase the delay to accommodate for my receiver and TV to turn on properly.

I was able to test playing the Goggle_TTS built MP3 just with atvremote command, but not via the Home Assistant script yet.

@rosahas
Copy link
Copy Markdown

rosahas commented Feb 8, 2017

I can also confirm that the HSGID is the same, must be by my userid or something.. I was able to add my other Apple TV using the same HSGID and the other IP address, no problem.

@rosahas
Copy link
Copy Markdown

rosahas commented Feb 8, 2017

@postlund Is there anyway to stop both my Apple TVs from turning on, when Home Assistant restarts?

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 8, 2017

And as ju you noticed, it is not possible to turn off the device as that is not implemented. I don't think it's possible to implement I'm afraid.

@robbiet480
Copy link
Copy Markdown
Contributor

@postlund It's probably possible for Gen4 since you can long press the TV button to sleep but yeah not possible for anything other than that.

@postlund
Copy link
Copy Markdown
Contributor Author

postlund commented Feb 9, 2017

@robbiet480 but I guess it would be hard to know when to trigger sleep in that case.

@rosahas
Copy link
Copy Markdown

rosahas commented Feb 9, 2017

@robbiet480 interesting.. I didn't know that. Anyway to try it out? I would love to have a way to put Apple TV on standby. Perhaps through a shell script that long presses the TV button?

@robbiet480
Copy link
Copy Markdown
Contributor

@rosahas Just press and hold the TV button and it will ask if you want to sleep. It will then turn itself and all connected CEC devices.

@rosahas
Copy link
Copy Markdown

rosahas commented Mar 3, 2017

@robbiet480 I turned on CEC so that when the Apple TV turns off after the 15 min timer, it turns off my TV and other CEC devices (like my Onkyo receiver). It seems that somehow this is causing my Apple TV to come on when I restart HA now! Will investigate further.

@robbiet480
Copy link
Copy Markdown
Contributor

@rosahas This is a known issue

@rosahas
Copy link
Copy Markdown

rosahas commented Mar 7, 2017

@robbiet480 thanks .. yes, I am on that thread too.. and I finally have the same random issue as well!

@rosahas
Copy link
Copy Markdown

rosahas commented Mar 18, 2017

@robbiet480 any way to do this "standby" programmatically by duplicating the long press for TV button?

@SShah7433
Copy link
Copy Markdown

@robbiet480 Would it be possible to get top_menu functionality implemented (accessible through HASS) since its already available in pyatv?

@postlund
Copy link
Copy Markdown
Contributor Author

@SShah2601 Yes, that would be possible and it's on my TODO-list. My goal is to add a service that can simulate all kinds of key presses. Once I can get pyatv 0.3.0 out the door, even arrow keys can be supported. But I'm currently blocked by a dependency issue. I'll see if I can get some time tonight to at least support the keys that are supported by the user pyatv version.

@home-assistant home-assistant locked and limited conversation to collaborators Aug 12, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants