core: Samsung TV Integration Not working across VLANs

The problem

I recently bought a router that supports VLANs, so I have segregated my network using VLANs and firewall rules to allow home assistant to communicate with all devices freely, but devices on a different subnet cannot initiate connection. Since I have done so, all of my integrations have been working except for the Samsung Smart TV integration. When I try to set up this integration in the UI, it immediately says “Unable to connect to this device”, and I believe this is an issue of connection timeout because of the process of traversing VLANs to make the websocket handshake. This is just speculation as I have not tested this, however I have found that my Home Assistant can access the rest API using http://192.168.107.11:8001/api/v2

My home assistant is on the 192.168.0.0/24 VLAN and the Samsung TV is on the 192.168.107.0/24 VLAN

Environment

  • Home Assistant Core release with the issue: 0.109.0
  • Last working Home Assistant Core release (if known): N/A It was working before putting my TV on another VLAN
  • Operating environment (Home Assistant/Supervised/Docker/venv): venv
  • Integration causing this issue: Samsung Smart TV
  • Link to integration documentation on our website: https://www.home-assistant.io/integrations/samsungtv/

Problem-relevant configuration.yaml

Attempted to using the integration via the UI with the same result.

samsungtv:
  - host: 192.168.107.11
    name: Samsung TV

Traceback/Error logs

2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Try config: {'name': 'HomeAssistant', 'description': 'HomeAssistant', 'id': 'ha.component.samsung', 'host': '192.168.107.11', 'method': 'legacy', 'port': None, 'timeout': 31}
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Failing config: {'name': 'HomeAssistant', 'description': 'HomeAssistant', 'id': 'ha.component.samsung', 'host': '192.168.107.11', 'method': 'legacy', 'port': None, 'timeout': 31}, error: [Errno 111] Connection refused
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Try config: {'name': 'HomeAssistant', 'host': '192.168.107.11', 'method': 'websocket', 'port': 8001, 'timeout': 31}
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] WS url ws://192.168.107.11:8001/api/v2/channels/samsung.remote.control?name=SG9tZUFzc2lzdGFudA==
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] Connection closed.
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] Connection closed.
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Failing config: {'name': 'HomeAssistant', 'host': '192.168.107.11', 'method': 'websocket', 'port': 8001, 'timeout': 31}, error: {'event': 'ms.channel.timeOut'}
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Try config: {'name': 'HomeAssistant', 'host': '192.168.107.11', 'method': 'websocket', 'port': 8002, 'timeout': 31}
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] WS url wss://192.168.107.11:8002/api/v2/channels/samsung.remote.control?name=SG9tZUFzc2lzdGFudA==&token=None
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] Connection closed.
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [samsungtvws.remote] Connection closed.
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] Failing config: {'name': 'HomeAssistant', 'host': '192.168.107.11', 'method': 'websocket', 'port': 8002, 'timeout': 31}, error: {'event': 'ms.channel.timeOut'}
2020-05-02 20:39:07 DEBUG (SyncWorker_19) [homeassistant.components.samsungtv] No working config found

Additional information

The rules in my firewall allow connections on any port from my 192.168.0.0/24 VLAN to the 192.168.107.0/24 VLAN. I have also tried setting the firewall rules so that just my TV (192.168.107.11) can connect to my home assistant (192.168.0.26) to no avail. I have set up my network to broadcast mDNS, and since doing so, all my chromecast devices function just fine, it’s just the TV that is not working. The TV Model is UN65KU6300

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 40 (10 by maintainers)

Most upvoted comments

@HeedfulCrayon your problem has nothing to do with mdns (mdns is hardly even relevant to your problem, you’re not autodiscovering), and your problem has nothing to do with VLANs - but everything to do with your TV and how it handles websockets across subnets (spoiler: evidently it doesn’t handle them well).

I have a similar TV (UN50KU6300) and worked around this issue today. Posting a solution here since I can’t be the only one who stumbled upon this issue looking for an answer.

Scouring online, I read somewhere a remark that it’s the TV that’s unable/refusing to communicate using websockets across subnets, rather than the client having issues or network being unable to route traffic. So, having HA on subnet_1 (vlan_1) and TV on subnet_2 (vlan2), I proceed as follows:

Hypothesis: the TV is unable to communicate using websockets across subnets

Solution: install a server running nginx proxy (port 8001 -> tv:8001 and port 8002 -> tv:8002) on the same subnet/VLAN as your TV (subnet_2/vlan_2). Then from home assistant, during your TV integration setup - use your proxy server IP instead of the TV IP. Theory is that the TV shouldn’t have issues talking back to the proxy on the same subnet, and everything should work out fine between proxy and the client being on different subnets because nginx isn’t handicapped like the Samsung TVs are.

The path looks like this: HA[subnet_1] <–> NGINX[subnet_2] <–> TV[subnet_2]

Turns out it works exceptionally well, and validates the hypothesis. I am able to add the TV and am able to manipulate it, while HA and TV run on different subnets and different VLANs.

If you use other integrations/protocols/ports for communication with your TV - you may need to change your proxy accordingly.

I have only touched nginx a handful of times before, so the following config may not be ideal but it solves the problem and seems rather conservative (remember to replace IP_OF_YOUR_TV):

http {                                                                                                                 
    map $http_upgrade $connection_upgrade {                
        default upgrade;                       
        '' close;                                                                                                      
    }                                                                                                                  
                                                           
    upstream websocket {                     
        server IP_OF_YOUR_TV:8001;                
        server IP_OF_YOUR_TV:8002;                                                                                        
    }                                                                                                                  
                                                           
    server {                                               
        listen 8001;                                                                                                   
        listen 8002;                                                                                                   
        location / {                                       
            proxy_pass http://websocket;                   
            proxy_http_version 1.1;                        
            proxy_set_header Upgrade $http_upgrade;                                                                    
            proxy_set_header Connection $connection_upgrade;                                                           
            proxy_set_header Host $host;                   
        }                                                                                                              
    }                                                                                                                  
}

Good luck.

Hello, If you have a Unifi UDM: 1- Backup your UDM 2- log in (as root). 3- Switch to shell mode with the command: unifi-os shell 4- download the utility allowing the execution of script at the start of the UDM: curl -L https://udm-boot.boostchicken.dev -o udm-boot_1.0.5_all.deb 5- install the utility and exit shell mode: dpkg -i udm-boot_1.0.5_all.deb exit 6- Check the presence of the on_boot.d folder in /mnt/data 7- Create the script (.sh extension) in the on_boot.d folder: vi iptables_tvsamsung.sh Inside : #!/bin/sh iptables -t nat -A POSTROUTING -s IP_OF_YOUR_HA -d IP_OF_YOUR_TV -j MASQUERADE Save and exit: Esc key then :wq! Give the rights and make it executable: chmod 775 iptables_tvsamsung.sh Restart the UDM: reboot

Hello, If you have a Unifi UDM: 1- Backup your UDM 2- log in (as root). 3- Switch to shell mode with the command: unifi-os shell 4- download the utility allowing the execution of script at the start of the UDM: curl -L https://udm-boot.boostchicken.dev -o udm-boot_1.0.5_all.deb 5- install the utility and exit shell mode: dpkg -i udm-boot_1.0.5_all.deb exit 6- Check the presence of the on_boot.d folder in /mnt/data 7- Create the script (.sh extension) in the on_boot.d folder: vi iptables_tvsamsung.sh Inside : #!/bin/sh iptables -t nat -A POSTROUTING -s IP_OF_YOUR_HA -d IP_OF_YOUR_TV -j MASQUERADE Save and exit: Esc key then :wq! Give the rights and make it executable: chmod 775 iptables_tvsamsung.sh Restart the UDM: reboot

This is even more minimalistic & beautiful: Tricking the TV into thinking, it speaks with an IP from the same net-segment by using NAT. I replicated something similar with my pfSense Firewall.

Navigate to Firewall/NAT/Outbound and create a new rule (assuming, you use “Hybrid Outbound NAT rule generation”) image

All settings in the rule look like this: image

The “IOT” interface is my VLAN “100” for IoT devices, supplying this network: 10.100.100.0/24 The network “Network_Private” is an alias to my “private network” for trusted devices. IP Range is 192.168.0.0/24 image

The network “Network_SamsungTVs” is an alias to IPs of Samsung TVs living in the IoT Network (currently just one): 10.100.100.40 image

Running a pairing request from my private network to the TV in the IoT network now works: image

Running more advanced network setups, like using VLANs, often involve configuring things like mDNS reflectors/repeaters or IGMP proxies to make these things work (and that is not just this Samsung integration).

This is not really a Home Assistant issue, to be honest, this is a design/networking issues on the user end. Therefore I think this issue should be closed.

Thank you @Idan37S it solve my issue on my EdgeRouter X

using what it proveded there and adjust it for my need in Outbound Interface I’ve put switch0.200 (vlan where my Samsung TV is) and adjust my ip addresses.

For those using PfSense (or any other pro router), Look at this thread for Masquerading: rytilahti/python-miio#422

It solved all my problems with Samsung TVs in a different VLAN than my HA.

@Jc2k Sorry, for some reason when I first created this, it didn’t show the template. I have updated it now