pyatv
pyatv copied to clipboard
Not able to connect to Apple TV in different subnet
Describe the bug I can not add ATV to my Home Assistant. My network is separated in multiple VLANs. The ATV is in VLAN 1 and Home Assistant in VLAN 2. Both can talk to each other. I use a MDNS repeater to use for example Homekit in other VLANs.
In older versions of the integration, HA could see the Apple TV and I got the text field to enter the PIN code. But the PIN was always wrong.
To Reproduce Place ATV in different subnet. (I guess) Expected behavior
System Setup (please complete the following information):
- OS: Debian
- Python: 3.7.3
- pyatv: 0.7.0
- Apple TV: Apple TV 4K tvOS 13.4.6
Additional context Traceback (most recent call last): File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 144, in async_step_user await self.async_find_device() File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 218, in async_find_device self.unique_id, self.hass.loop, cache=self.scan_result File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 76, in device_scan scan_result = await scan(loop, hosts=hosts, timeout=timeout) File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/init.py", line 49, in scan devices = (await scanner.discover(timeout)).values() File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/scan.py", line 154, in discover *[self._get_services(host, timeout) for host in self.hosts] File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/scan.py", line 167, in _get_services self.loop, str(host), ALL_SERVICES, port=port, timeout=timeout File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/mdns.py", line 448, in unicast f"address {address} is not in any local subnet" pyatv.exceptions.NonLocalSubnetError: address 192.168.178.49 is not in any local subnet
This might be a bug with the new scanning implementation, I have seen some issues myself that I will look in to. Adding via unicast (specifying IP address) will not work between VLANs. That's just how zeroconf is designed.
If you could not add because of invalid PIN, that's a separate issue we can deal with once scanning works. Can you provide some output from atvremote --debug scan
?
2020-07-15 16:06:58 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) 2020-07-15 16:06:59 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) 2020-07-15 16:07:00 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) Scan Results
Ok, so no response at all. I guess other services are discovered in Home Assistant? Are you running in docker?
Yes other services work. I use python virtual environment
Ok, so, I have a theory. Been looking at the code for python-zeroconf to try to understand what is happening. The problem I have is that proxies set up by atvproxy
are not picked up by a scan. I use python-zeroconf to publish services for these proxies. What I can see is that requests are received just fine, but no responses are sent. The reason for this is that the source port is not one of 53 (DNS) or 5353 (MDNS), which is a pretty strict constraint (but probably according to standard). Since I just send a unicast request to a multicast address, a random source port are used so this is reasonable. When implementing a full zeroconf client, it would also listen on port 5353 in which case it would make sense to use 5353 as source port. The Apple TV's does not seem to care about this and treat my requests as unicast requests and answer. But as I said, python-zeroconf does not and your MDNS responder probably does not either. This is likely the reason why it doesn't work. So, I guess I will have to investigate how much work is needed to fix this.
Sorry about the long post. Here, have a 🌮
Did some testing last night and I think my theory might be right. It seemed to work when binding to port 5353, but there will be problems if another zeroconf client is doing the same. It's no problem binding to the same address and port, assuming the other client did the same, but received messages will be load balanced between the processes. So pyatv will miss some responses and receive other responses. It will only work properly if one zeroconf client is used at the same time. Will have to think about this a bit...
I've got the same problem, although running in a docker container (NOT host network mode).
pyatv.exceptions.NonLocalSubnetError: address X.X.X.X is not in any local subnet
Used to work with older versions though.
What are you entering when adding the device? Not sure exactly how I ended up doing it, but I think you need to specify either device name or identifier when using a repeat. IP address will not work. Since current scanning is somewhat broken, it might not work still. Looking into that.
I'm pretty sure I used to add it with entering the IP address. Now it doesn't work anymore, neither does it with the device name. (probably as expected, since I don't use a repeater)
So i am also having similar issue except that my Apple TV (4K) and home assistant server are on the same subnet. I tried adding the Apple TV via name (for which it said "Device could not be found on network, please try again."). But when I tried adding through the IP address it gave me the following error:
Unexpected exception
Traceback (most recent call last):
File "/config/custom_components/apple_tv/config_flow.py", line 144, in async_step_user
await self.async_find_device()
File "/config/custom_components/apple_tv/config_flow.py", line 218, in async_find_device
self.unique_id, self.hass.loop, cache=self.scan_result
File "/config/custom_components/apple_tv/config_flow.py", line 76, in device_scan
scan_result = await scan(loop, hosts=hosts, timeout=timeout)
File "/usr/local/lib/python3.7/site-packages/pyatv/__init__.py", line 49, in scan
devices = (await scanner.discover(timeout)).values()
File "/usr/local/lib/python3.7/site-packages/pyatv/support/scan.py", line 154, in discover
*[self._get_services(host, timeout) for host in self.hosts]
File "/usr/local/lib/python3.7/site-packages/pyatv/support/scan.py", line 167, in _get_services
self.loop, str(host), ALL_SERVICES, port=port, timeout=timeout
File "/usr/local/lib/python3.7/site-packages/pyatv/support/mdns.py", line 448, in unicast
f"address {address} is not in any local subnet"
pyatv.exceptions.NonLocalSubnetError: address 192.168.1.247 is not in any local subnet
Home Assistant has started!
How are you running your Home Assistant instances? The edge case I can think of where it would potentially work is if the network is in NAT mode. When the Apple TV receives the request it must come from an IP address on the same network or it will be ignored.
I am running HA in docker on windows and used --net=host while bringing up the container.
Just checked the docker and it was in "bridge" mode. So I recreated the docker container using host net config, but now I now I cant seem to access HA itself. And since host network is not supported on windows I would need to go back to bridge mode. So is there a way to integrate apple tv with HA in bridged mode?
Right, so host mode should of course work as long as the host is on the same network as the Apple TV. But it definitely uses NAT as means for network access (it has another IP address inside the container which is translated to the host address outside of the container). This is a problematic edge case where my check will fail. I might have to remove the check to remedy this.
Removing local subnet check is probably the safest bet until I get scanning to work as expected. I can try to make that happen and make a release later tonight.
That would be great @postlund . I can try again once you release the update. Thanks
@giricgoyal I'll let you know when it's done. Created #775 for the change.
@giricgoyal I have not forgotten about you, just wanted to spend some additional time fiddling with the mdns implementation. I think I have hacky prototype that solves the base problem. Will need some time to make it presentable, but hopefully within the next couple of days. Time to get some sleep.
@postlund is it possible for you to create a release with #775 in the mean time, and include it in a version of the hass component? I have applied that change locally and it works for me, but it would be nice to have it included automatically so I don't have to do it again 😄
@radhus There will be a release very soon 😊 Just had a short break ("vacation") from pyatv, will take up development again albeit with a lower pace. I'm just finishing up #777 (will merge that tonight) and after that I will try to sort out #780. That is what I'm planning for next release, should be able to finish that today or tomorrow. After that I will continue updating the integration and also re-submit PR so I can finally have it updated in Home Assistant. Been putting that of intentionally due to bugs.
@postlund great! No stress :) Let me know if there's anything special to test and I'll help out :)
@radhus Just pushed an update to the component, give it a go and let me know if it works 😊
With the newest version I get no connection at all
@ITTV-tools Interesting that you get that. Please enable logging and provide the pyatv log, perhaps I can implement that.
I see the same behavior
@postlund upgrade worked, then removed and added the apple-tv again (with IP address) and it worked fine. 👍
@geekofweek Do you have the possibility to reproduce this with PYATV_BINARY_MAX_LINE=10000 atvremote --debug -s <ip> playing
? I started to create a fix in #802, but I'm not sure that fixes the problem. I'm afraid that it removes the exception but no device would still be found. So complete logs are needed for debugging.
Home Assistant sits on 192.168.101.0/24, it has all ports opened to the AppleTVs through the firewall so nothing should be blocking it.
# PYATV_BINARY_MAX_LINE=10000 atvremote --debug -s 192.168.100.11 playing
2020-08-17 15:39:58 DEBUG: Knocking at port 3689 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 7000 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 49152 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 32498 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 3689 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 7000 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 49152 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 32498 on 192.168.100.11
2020-08-17 15:40:01 DEBUG: Cleaning up after UDNS request
2020-08-17 15:40:01 DEBUG: Cleaning up after UDNS request
2020-08-17 15:40:01 ERROR: Could not find any Apple TV on current network
Yeah, that won't work. The Apple TV will drop packets from other subnets. That's part of the specification (although it's possible to be lax about it, that's how Apple Implemented it). Only way for this to work is to use an mdns relayer and rely on regular scanning (not unicast like was used here).
I have mdns forwarding configured, which I assume is how it works on the previous versions.