postlund / pyatv

A client library for Apple TV and AirPlay devices
https://pyatv.dev
MIT License
891 stars 100 forks source link

Can't Add Apple TV #402

Closed Tangston311 closed 4 years ago

Tangston311 commented 4 years ago

Describe the bug I was previously successfully using this Beta but had to delete it to try and solve some other issues I was having, but now that I've reinstalled it I can't get it to add my AppleTV.

After I've installed it and go to "Integrations" and then "AppleTV", I get a message that it's auto-discovered all of the AppleTV's in my house, even though I have the following in my yaml:

discovery: ignore: - apple_tv

Then I'll add in the IP address of the AppleTV I want to add, enter the code, and then it simply says "Aborted" and nothing happens. Furthermore, if I get a code starting in '0' I can't add it. It's almost as if the Beta component just isn't installing correctly, even though I tried both installing through HACS and manually. Debug logs are attached.

To Reproduce Try and add an AppleTV using the steps in the custom component. PYATV.log

Expected behavior Auto-discovery of my AppleTV's shouldn't occur, I should be able to enter codes starting in 0, and I should be able to successfully add my AppleTV.

System Setup (please complete the following information):

Additional context

postlund commented 4 years ago

Ok, so, we have a few different things a play here. Firstly, when it says that it has "auto-discovered" your devices it has nothing to do with with the discovery in Home Assistant. I scan for devices with pyatv.scan and present the results in the first dialog, as a convenience to the user. This makes it easier to add devices if you don't know their names or addresses. Since this is a custom component, discovery doesn't even work as that is not supported for custom components (yet). But I might re-phrase the text to make it more clear, I can see how it is confusing.

The empty dialog seems like a bug. My guess is that a config entry still exists somewhere, so the flow abort since you try to add the same device again. Can you make sure that you remove the integration, all devices and entities (you find Devices and Entities under Configuration), restart Home Assistant and try again? It's a bit messy due to the fact that remote doesn't support config entries, so I can't implement unloading properly yet (that is why you have to restart Home Assistant).

The leading zero-bug has been reported earlier and I thought it was fixed. It is not possible to enter leading zeros, but it should be sufficient to enter say 123 if the code is 0123. I assume you tried that? Also, was it MRP or AirPlay pairing that failed? It is stated in the dialog.

I don't think it's a problem with the installation, it's just various other issues that we have to deal with. Beta stuff we could call it.

Tangston311 commented 4 years ago

Gotcha, thanks for the detail on the discovery - it just threw me off because the first time I (successfully) installed this plugin I didn't get presented with the results, but this time I did...perhaps because I was using an older version the first time around or something.

I couldn't remove the Integration from the Integration page because it never got added in the first place, but there were some old entities that I deleted, and then restarted HA. I then tried re-adding but got the same "Aborted" message with nothing else (logs attached).

I did try just entering 123 if the code was 0123, but just wound up with the same error. So it may have worked if not for whatever's preventing me from doing it above.

Really appreciate your help with this! home-assistant.log

postlund commented 4 years ago

Yeah, previously I added a hack that would show discovered devices after one failure attempt. Just as a help and my intention was to remove it. But I took a turn and decided to add it as a feature and show it immediately at the first dialog. Hopefully useful.

Ok, then we have another issue here. A quick look shows that it could either be "device not found" or "authentication failed" that should have been shown in the abort-box, because they miss translations as it is now. Based on the situation it must be the latter. To get some additional logs, you can open config_flow.py, goto about line 260 and add the exception log like this:

...
                return await self.async_begin_pairing()
            except exceptions.PairingError:
                _LOGGER.exception("Auth exception")  # <-- add this line
                errors["base"] = "auth"
            except Exception:  # pylint: disable=broad-except
                _LOGGER.exception("Unexpected exception")
                errors["base"] = "unknown"
...

Then try again. It should give us a better idea of what is happening. Based on the logs it seems like pairing of MRP works. Can you confirm that it is AirPlay that doesn't pair correctly?

Tangston311 commented 4 years ago

Ah! I actually couldn't add the AppleTV, not AirPlay, but after you said that I realized that I had Airplay turned off on my AppleTV so I turned it back on and then tried to add the integration again (after a HA restart and adding in the line above), and it worked! Both MRP and Airplay.

So maybe there's a contingency to have Airplay enabled for this to work? I don't think I had it enabled before, which is odd. I can try disabling Airplay and re-adding to see what happens if it's helpful for your diagnostics.

postlund commented 4 years ago

There we have it! I have mitigations to skip AirPlay in case the zeroconf service is not found, but not in case it is disabled. Would be very helpful if you could add the debug line mentioned above and retry pairing with AirPlay disabled. Maybe it is possible to see that and skip adding it in that case.

Tangston311 commented 4 years ago

Sure thing - see attached with debug line. Let me know if it didn't work or doesn't give you what you need! home-assistant.log

postlund commented 4 years ago

Strange. When I disable AirPlay on my Apple TV and try adding it, MRP pairs just fine and then I get the "Failed to add"-dialog:

no_airplay

Is that the same dialog you got? It is different from "abort" as that means actually abort. In this case the device should be added but you don't get AirPlay support (i.e. can not use play_url).

I can not see any other issues in your logs, so I assume this is what happened

Tangston311 commented 4 years ago

Weird - that's exactly the message that I got the first time I used this integration....it successfully added my AppleTV (when Airplay was off), and I got that exact message.

This time the only thing the dialog says is "Aborted" with an "Ok" button (I don't have a screenshot but I can share one when I get back home), and the AppleTV was not added.

postlund commented 4 years ago

Yeah, that is weird. Can you try to add the same logging-row as before but also here in the same way:

https://github.com/postlund/hass-atv-beta/blob/master/custom_components/apple_tv/config_flow.py#L233

Tangston311 commented 4 years ago

Sure thing - I'll add that in and post results tomorrow morning.

Tangston311 commented 4 years ago

Ok, added that additional line and just put everything in "debug" mode to make sure I captured everything. See attached. Also is a screenshot of the Aborted error I get. Let me know what else I can provide! home-assistant copy.log

Screen Shot 2020-01-28 at 6 24 06 AM
postlund commented 4 years ago

As I suspected:

020-01-28 06:23:59 ERROR (MainThread) [custom_components.apple_tv.config_flow] Auth exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 936, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 954, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 941, in create_connection
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 464, in sock_connect
    return await fut
  File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 494, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.1.18', 7000)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/pyatv/airplay/pairing.py", line 59, in begin
    return await self.auther.start_authentication()
  File "/usr/local/lib/python3.7/site-packages/pyatv/airplay/auth.py", line 32, in start_authentication
    'pair-pin-start', headers=_AIRPLAY_HEADERS)
  File "/usr/local/lib/python3.7/site-packages/pyatv/net.py", line 76, in post_data
    raise ex
  File "/usr/local/lib/python3.7/site-packages/pyatv/net.py", line 66, in post_data
    timeout=DEFAULT_TIMEOUT if timeout is None else timeout)
  File "/usr/local/lib/python3.7/site-packages/aiohttp/client.py", line 483, in _request
    timeout=real_timeout
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 523, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 859, in _create_connection
    req, traces, timeout)
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 1004, in _create_direct_connection
    raise last_exc
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 986, in _create_direct_connection
    req=req, client_error=client_error)
  File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 943, in _wrap_create_connection
    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.18:7000 ssl:None [Connect call failed ('192.168.1.18', 7000)]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/apple_tv/config_flow.py", line 225, in async_begin_pairing
    await self.pairing.begin()
  File "/usr/local/lib/python3.7/site-packages/pyatv/airplay/pairing.py", line 61, in begin
    raise exceptions.PairingError(str(ex)) from ex
pyatv.exceptions.PairingError: Cannot connect to host 192.168.1.18:7000 ssl:None [Connect call failed ('192.168.1.18', 7000)]

It is reasonable that this happen, I must handle this exception separately. This is all I need to fix this, thanks for all the help! 😄

postlund commented 4 years ago

Ok, so, this was one of those "it works for me"-kinda situations. It so happens that I already fixed this problem (at least for AirPlay):

https://github.com/postlund/pyatv/commit/d49837db28788dc98ae5facacfa84680cb7c4817

Since I have these changes locally I get the proper error message. I have not released pyatv with this change and updated the component yet though. So that is why you get the error above. I will hopefully make a new release tonight.

postlund commented 4 years ago

Will have to delay update another day or so. I have made a lot of other improvements to squash bugs, but I need to make sure it works correct first.

Tangston311 commented 4 years ago

No worries - appreciate the hard work!

postlund commented 4 years ago

@Tangston311 I have made a new release now, feel free to give it a spin!

Tangston311 commented 4 years ago

@postlund just upgraded and tested by removing my AppleTV's, turning off Airplay, and was able to successfully add them back with no issues! Thanks so much!

postlund commented 4 years ago

@Tangston311 Great, thanks for verifying! 😊 I will close the issue, feel free to write a new issue if you run into more problems!

DrMachin commented 4 years ago

Ran into this issue today. I found that I had to change my airplay access settings from "Only people sharing my home" to "Everyone on the same network".