home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
72.6k stars 30.37k forks source link

Apple-tv integration - "No devices found on the network" #65585

Closed xeor closed 2 years ago

xeor commented 2 years ago

The problem

I have a similar issue as https://github.com/home-assistant/core/issues/52862, but on the newest home-assistant 2022.2.0.

When adding the apple-tv integration and typing in the ip of my apple-tv, I instantly get No devices found on the network. There are no errors in the logs, even with debug turned on as stated in the integration documentation.

What version of Home Assistant Core has the issue?

2022.2.0

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Container

Integration causing the issue

Apple TV

Link to integration documentation on our website

https://www.home-assistant.io/integrations/apple_tv/

Example YAML snippet

No response

Anything in the logs that might be useful for us?

I can only find the error `No devices found on the network`, that comes from the ui when adding the component.

Additional information

On previous (don't remember when, but the network was the same) versions of the apple-tv plugin, I could connect it (even tho it didnt work that well because I had tvOS 15). I did not get the error above anyhow.

To talk to my apple-tv on another vlan, I have iptables -t nat -A POSTROUTING -s 10.32.0.0/24 -d 10.16.0.2 -j MASQUERADE on my firewall. Without that, atvremote -s 10.16.0.2 scan cant find it at all.

I can see info about the apple-tv when running atvremote inside the container:

bash-5.1# atvremote -s 10.16.0.2 scan
Scan Results
========================================
       Name: livingroom
   Model/SW: Apple TV 4K (gen2), tvOS 15.2
    Address: 10.16.0.2
        MAC: F0:B3:EC:xx:xx:xx
 Deep Sleep: False
Identifiers:
 - F0:B3:EC:xx:xx:xx
 - F0B3ECxxxxxx
Services:
 - Protocol: Companion, Port: 49152, Credentials: None, Requires Password: False, Password: None, Pairing: Mandatory
 - Protocol: AirPlay, Port: 7000, Credentials: None, Requires Password: False, Password: None, Pairing: Mandatory
 - Protocol: RAOP, Port: 7000, Credentials: None, Requires Password: False, Password: None, Pairing: Mandatory
bash-5.1# python -c 'import pyatv; print(pyatv.const.__version__)'
0.10.0
probot-home-assistant[bot] commented 2 years ago

apple_tv documentation apple_tv source (message by IssueLinks)

probot-home-assistant[bot] commented 2 years ago

Hey there @postlund, mind taking a look at this issue as it has been labeled with an integration (apple_tv) you are listed as a code owner for? Thanks! (message by CodeOwnersMention)

xeor commented 2 years ago

I was digging a little deeper into this, and it seams like there are some zeroconf stuff that breaks this. If I change https://github.com/home-assistant/core/blob/7112c5b52a1e0016961a725d4ca90b57ddb350de/homeassistant/components/apple_tv/config_flow.py#L57 (which returns [] for me) to scan_result = await scan(loop, timeout=3, hosts=_host_filter()), it returns the correct entity and I am able to add it after it prompts me for 3 pins.

postlund commented 2 years ago

@bdraco Based on the finding above, I think you are the right man for the task!

bdraco commented 2 years ago

@xeor How do you have your network setting configured in Home Assistant? Do you have the interface for the additional vlan checked ?

xeor commented 2 years ago

@xeor How do you have your network setting configured in Home Assistant? Do you have the interface for the additional vlan checked ?

Inside the container, there is only eth0 (attached inside kubernetes) and loopback. I havent done anything with vlans and home-assistant, and it is autodetecting the interface.

It is the physical nodes themself that are connected using the other vlans.

I have configured the network to do IGMP snooping and enabled mDNS reflector service. So mdns should in theory work, even tho I haveto do the iptables -t nat -A POSTROUTING -s 10.32.0.0/24 -d 10.16.0.2 -j MASQUERADE trick as well.

bdraco commented 2 years ago

So with that set up it's probably working because without zeroconf if it's doing unicast to the device. It sounds like there's something not working correctly with your multicast forwarding.

xeor commented 2 years ago

I need to dig deeper into how mdns works to be able to give some valuable feedback here.

Is there more mdns/zeroconf magic in the apple-tv integration? I got it added as mentioned above, but I still can't seam to use it.. Trying with simple stuff like this:

service: remote.send_command
data:
  command:
    - left
target:
  entity_id: remote. livingroom

How can I test furter? I can try with atvremote manually? And if I get it to work, we can look more at the integration..? Maybe there should be an option to disable zeroconf if that is something that can break some network setups..?

postlund commented 2 years ago

Pyatv is in an ambivalent state right now where it has its own MDNS implementation (which is what you get with atvremote for instance or with the change you made earlier). But it's also possible (with some tinkering) to use python-zeroconf as backend, which is work driven by @bdraco and also what Home Assistant uses. So even if atvremote works that doesn't necessarily mean it works in Home Assistant (or vice versa). The goal is to replace the custom built MDNS implementation with python-zeroconf over time.

It is not possible to remove MDNS/zeroconf. The information inside the broadcasted services is needed for discovery (you cannot manually replace that). It is especially needed in network set ups with multiple networks, e.g. VLANs, as it's not possible to use unicast requests there. Packets from other networks are just dropped.

bdraco commented 2 years ago

How can I test furter? I can try with atvremote manually? And if I get it to work, we can look more at the integration..?

Can you control the apple tv using the remote app on an iPhone from the same network Home Assistant is on?

Maybe there should be an option to disable zeroconf if that is something that can break some network setups..?

Ideally we fix zeroconf if its a rfc6762 compliance issue, we would need to understand if it is first though.

xeor commented 2 years ago

Can you control the apple tv using the remote app on an iPhone from the same network Home Assistant is on?

Yes.. Well, I tried using an iPhone on a network in another vlan than home-assistant. The network itself is configured about the same as the one hass is in, so I think the test is valid. The iphone could controll the apple-tv just fine.

How can I test more easily the problem? Would a little python snippet be able to reproduce the problem? I can try some different network configurations to try to narrow the problem if I'm able to reproduce it more easily

bdraco commented 2 years ago

Can this scanner find the device from the HA network?

https://github.com/jstasiak/python-zeroconf/blob/master/examples/async_apple_scanner.py

xeor commented 2 years ago

Can this scanner find the device from the HA network?

https://github.com/jstasiak/python-zeroconf/blob/master/examples/async_apple_scanner.py

yes.. It gave a lot of info.. Some of it below

stua is livingroom.. I changed the name in earlier posts

bash-5.1# ./async_apple_scanner.py --target 10.16.0.2
DEBUG:asyncio:Using selector: EpollSelector

Browsing ['_appletv-v2._tcp.local.', '_touch-able._tcp.local.', '_mediaremotetv._tcp.local.', '_airplay._tcp.local.', '_companion-link._tcp.local.', '_raop._tcp.local.', '_airport._tcp.local.', '_device-info._tcp.local.'] se
rvice(s), press Ctrl-C to exit...

Service stua._companion-link._tcp.local. of type _companion-link._tcp.local. state changed: ServiceStateChange.Added
Service stua._airplay._tcp.local. of type _airplay._tcp.local. state changed: ServiceStateChange.Added                                                                                                                          Service ...@stua._raop._tcp.local. of type _raop._tcp.local. state changed: ServiceStateChange.Added
Service stua._device-info._tcp.local. of type _device-info._tcp.local. state changed: ServiceStateChange.Updated 
Info from zeroconf.get_service_info: AsyncServiceInfo(type='_companion-link._tcp.local.', name='stua._companion-link._tcp.local.', addresses=...
  Name: stua._companion-link._tcp.local.
...  Properties are:                                                                                                                                                                                                                   b'rpMac': b'1'                                
 ...
   b'rpMd': b'AppleTV11,1'                         
    b'rpVr': b'320.2'
...                                                        

Info from zeroconf.get_service_info: AsyncServiceInfo(type='_airplay._tcp.local.', name='stua._airplay._tcp.local.', addresses=[b'\n\x10\x0...498e4433cf4ecf5
f6b61', b'srcvers': b'600.8.41', b'osvers': b'15.2', b'vv': b'2'}, interface_index=None)
  Name: stua._airplay._tcp.local.
  Addresses: 10.16....
    b'features': b'0x4A7FD...DE'
    b'flags': b'0x644'
    b'gid': b'1AE463CA-

anything special you want to look at? I can send you the whole output privately if you want to look at the whole thing..

bdraco commented 2 years ago

So it looks like it is finding it but something is missing.

I think we need to add some debug logging to pyatv to figure out what isn't coming through

bdraco commented 2 years ago

Can you get dumps of https://github.com/postlund/pyatv/blob/master/pyatv/core/scan.py#L377 self.zeroconf.cache.async_all_by_details( zc_type, _TYPE_PTR, _CLASS_IN )

and the value of infos here https://github.com/postlund/pyatv/blob/master/pyatv/core/scan.py#L394?

Feel free to email to nick@koston.org since you probably don't want to post it here.

xeor commented 2 years ago

@bdraco I'll do it tomorrow :) offline for some hours now

bdraco commented 2 years ago

No rush. Take your time.

xeor commented 2 years ago

Sent you an mail..

But I think this might be kubernetes fault.. I'll dig some deeper.

If I do dig @224.0.0.251 -p 5353 -t ptr _airplay._tcp.local.

I'll try to get k8s to play more nice with mdns

xeor commented 2 years ago

I figured out enough.. No need to keep this issue open.

I would need to get mdns working inside the cluster as well, and to do that, I need to set the container to use the hostnetwork, or use multus CNI so I can get 2 nic's inside the home-assistant container.

Thanks for the support! I'll post here if the solution is nice and pepy.. But maybe there should be a little headsup here for those who hits the same issue..?

xeor commented 2 years ago

I got multus running and this fixed the problem when it got an ip inside the container that was connected to the normal network. For anyone that looks at this that are in the same boat, here are some configs.

Note the route to the multicast subnet in the config, without this, it won't work. You should see two nic's inside your container (ip a s), and a routing for multicast (ip r l). dig @224.0.0.251 -p 5353 -t ptr _airplay._tcp.local. should also work and give a lot of output.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-static
  namespace: kube-system
spec:
  # https://www.cni.dev/plugins/current/main/macvlan/#network-configuration-reference
  config: '{
    "cniVersion": "0.3.1",
    "name": "macvlan-static",
    "type": "macvlan",
    "capabilities": { "ips": true },
    "ipam": {
        "type": "host-local",
        "gateway": "10.32.1.1",
        "subnet": "10.32.1.0/18",
        "rangeStart": "10.32.1.150",
        "rangeEnd": "10.32.1.199",
        "routes": [
            { "dst": "224.0.0.0/4" }
        ]
    }
    }'
    ...
    podAnnotations:
      k8s.v1.cni.cncf.io/networks: |
        [{
          "name":"macvlan-static",
          "namespace": "kube-system",
          "ips": ["10.32.1.150"]
        }]
bdraco commented 2 years ago

@xeor Thanks for closing the loop on this.

We have a section for helping with specific configurations here https://www.home-assistant.io/integrations/zeroconf/#integrations-relying-on-zeroconf-traffic-are-unresponsive

If you feel up to adding to it, I'm sure others would appreciate it

https://github.com/home-assistant/home-assistant.io/blob/current/source/_integrations/zeroconf.markdown

xeor commented 2 years ago

Thanks for the tip @bdraco .. I'm not sure if documenting this in that document is the best solution tho. I actually had no idea that zeroconf was my issue. I consider myself an advanced user tho, and I like to read deep documentation about advanced use-cases. I therefor proposed a documentation fix instead in the issue mentioned.. I'll be happy to fill in some documentation on this