Fix exceptions when using newer Samsung TVs (#31602)

* try to fix websocket problems

* use tuple

* catch websocket exceptions

* typo
This commit is contained in:
escoand 2020-02-08 12:03:35 +01:00 committed by GitHub
parent baa9184b33
commit 0823ee4385
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 10 deletions

View File

@ -5,6 +5,7 @@ from urllib.parse import urlparse
from samsungctl import Remote
from samsungctl.exceptions import AccessDenied, UnhandledResponse
import voluptuous as vol
from websocket import WebSocketException
from homeassistant import config_entries
from homeassistant.components.ssdp import (
@ -23,7 +24,7 @@ from homeassistant.const import (
)
# pylint:disable=unused-import
from .const import CONF_MANUFACTURER, CONF_MODEL, DOMAIN, LOGGER, METHODS
from .const import CONF_MANUFACTURER, CONF_MODEL, DOMAIN, LOGGER
DATA_SCHEMA = vol.Schema({vol.Required(CONF_HOST): str, vol.Required(CONF_NAME): str})
@ -32,6 +33,12 @@ RESULT_SUCCESS = "success"
RESULT_NOT_SUCCESSFUL = "not_successful"
RESULT_NOT_SUPPORTED = "not_supported"
SUPPORTED_METHODS = (
{"method": "websocket", "timeout": 1},
# We need this high timeout because waiting for auth popup is just an open socket
{"method": "legacy", "timeout": 31},
)
def _get_ip(host):
if host is None:
@ -76,27 +83,25 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
def _try_connect(self):
"""Try to connect and check auth."""
for method in METHODS:
for cfg in SUPPORTED_METHODS:
config = {
"name": "HomeAssistant",
"description": "HomeAssistant",
"id": "ha.component.samsung",
"host": self._host,
"method": method,
"port": self._port,
# We need this high timeout because waiting for auth popup is just an open socket
"timeout": 31,
}
config.update(cfg)
try:
LOGGER.debug("Try config: %s", config)
with Remote(config.copy()):
LOGGER.debug("Working config: %s", config)
self._method = method
self._method = cfg["method"]
return RESULT_SUCCESS
except AccessDenied:
LOGGER.debug("Working but denied config: %s", config)
return RESULT_AUTH_MISSING
except UnhandledResponse:
except (UnhandledResponse, WebSocketException):
LOGGER.debug("Working but unsupported config: %s", config)
return RESULT_NOT_SUPPORTED
except OSError as err:

View File

@ -9,5 +9,3 @@ DEFAULT_NAME = "Samsung TV"
CONF_MANUFACTURER = "manufacturer"
CONF_MODEL = "model"
CONF_ON_ACTION = "turn_on_action"
METHODS = ("websocket", "legacy")

View File

@ -4,6 +4,7 @@ from unittest.mock import call, patch
from asynctest import mock
import pytest
from samsungctl.exceptions import AccessDenied, UnhandledResponse
from websocket import WebSocketProtocolException
from homeassistant.components.samsungtv.const import (
CONF_MANUFACTURER,
@ -42,7 +43,7 @@ AUTODETECT_WEBSOCKET = {
"method": "websocket",
"port": None,
"host": "fake_host",
"timeout": 31,
"timeout": 1,
}
AUTODETECT_LEGACY = {
"name": "HomeAssistant",
@ -245,6 +246,28 @@ async def test_ssdp_not_supported(hass):
assert result["reason"] == "not_supported"
async def test_ssdp_not_supported_2(hass):
"""Test starting a flow from discovery for not supported device."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=WebSocketProtocolException("Boom"),
), patch("homeassistant.components.samsungtv.config_flow.socket"):
# confirm to add the entry
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "form"
assert result["step_id"] == "confirm"
# device not supported
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input="whatever"
)
assert result["type"] == "abort"
assert result["reason"] == "not_supported"
async def test_ssdp_not_successful(hass):
"""Test starting a flow from discovery but no device found."""
with patch(