mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Make devices and activities visible as harmony attributes (#37559)
* Make devices and activities visibile as harmony attributes * Allow restoring previous activity, add tests * fix test * Kill activity_notify with fire * remove trailing ,
This commit is contained in:
parent
ae7d464878
commit
76be95d7e0
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
|
|
||||||
from .const import ATTR_ACTIVITY_NOTIFY, DOMAIN, HARMONY_OPTIONS_UPDATE, PLATFORMS
|
from .const import DOMAIN, HARMONY_OPTIONS_UPDATE, PLATFORMS
|
||||||
from .remote import HarmonyRemote
|
from .remote import HarmonyRemote
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -38,18 +38,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
name = entry.data[CONF_NAME]
|
name = entry.data[CONF_NAME]
|
||||||
activity = entry.options.get(ATTR_ACTIVITY)
|
activity = entry.options.get(ATTR_ACTIVITY)
|
||||||
delay_secs = entry.options.get(ATTR_DELAY_SECS, DEFAULT_DELAY_SECS)
|
delay_secs = entry.options.get(ATTR_DELAY_SECS, DEFAULT_DELAY_SECS)
|
||||||
activity_notify = entry.options.get(ATTR_ACTIVITY_NOTIFY, False)
|
|
||||||
|
|
||||||
harmony_conf_file = hass.config.path(f"harmony_{entry.unique_id}.conf")
|
harmony_conf_file = hass.config.path(f"harmony_{entry.unique_id}.conf")
|
||||||
try:
|
try:
|
||||||
device = HarmonyRemote(
|
device = HarmonyRemote(
|
||||||
name,
|
name, entry.unique_id, address, activity, harmony_conf_file, delay_secs
|
||||||
entry.unique_id,
|
|
||||||
address,
|
|
||||||
activity,
|
|
||||||
harmony_conf_file,
|
|
||||||
delay_secs,
|
|
||||||
activity_notify,
|
|
||||||
)
|
)
|
||||||
connected_ok = await device.connect()
|
connected_ok = await device.connect()
|
||||||
except (asyncio.TimeoutError, ValueError, AttributeError):
|
except (asyncio.TimeoutError, ValueError, AttributeError):
|
||||||
|
@ -14,7 +14,7 @@ from homeassistant.components.remote import (
|
|||||||
from homeassistant.const import CONF_HOST, CONF_NAME
|
from homeassistant.const import CONF_HOST, CONF_NAME
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .const import ATTR_ACTIVITY_NOTIFY, DOMAIN, UNIQUE_ID
|
from .const import DOMAIN, PREVIOUS_ACTIVE_ACTIVITY, UNIQUE_ID
|
||||||
from .util import (
|
from .util import (
|
||||||
find_best_name_for_remote,
|
find_best_name_for_remote,
|
||||||
find_unique_id_for_remote,
|
find_unique_id_for_remote,
|
||||||
@ -148,7 +148,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
async def _async_create_entry_from_valid_input(self, validated, user_input):
|
async def _async_create_entry_from_valid_input(self, validated, user_input):
|
||||||
"""Single path to create the config entry from validated input."""
|
"""Single path to create the config entry from validated input."""
|
||||||
|
|
||||||
data = {CONF_NAME: validated[CONF_NAME], CONF_HOST: validated[CONF_HOST]}
|
data = {
|
||||||
|
CONF_NAME: validated[CONF_NAME],
|
||||||
|
CONF_HOST: validated[CONF_HOST],
|
||||||
|
}
|
||||||
# Options from yaml are preserved, we will pull them out when
|
# Options from yaml are preserved, we will pull them out when
|
||||||
# we setup the config entry
|
# we setup the config entry
|
||||||
data.update(_options_from_user_input(user_input))
|
data.update(_options_from_user_input(user_input))
|
||||||
@ -162,8 +165,6 @@ def _options_from_user_input(user_input):
|
|||||||
options[ATTR_ACTIVITY] = user_input[ATTR_ACTIVITY]
|
options[ATTR_ACTIVITY] = user_input[ATTR_ACTIVITY]
|
||||||
if ATTR_DELAY_SECS in user_input:
|
if ATTR_DELAY_SECS in user_input:
|
||||||
options[ATTR_DELAY_SECS] = user_input[ATTR_DELAY_SECS]
|
options[ATTR_DELAY_SECS] = user_input[ATTR_DELAY_SECS]
|
||||||
if ATTR_ACTIVITY_NOTIFY in user_input:
|
|
||||||
options[ATTR_ACTIVITY_NOTIFY] = user_input[ATTR_ACTIVITY_NOTIFY]
|
|
||||||
return options
|
return options
|
||||||
|
|
||||||
|
|
||||||
@ -190,12 +191,11 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
),
|
),
|
||||||
): vol.Coerce(float),
|
): vol.Coerce(float),
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
ATTR_ACTIVITY, default=self.config_entry.options.get(ATTR_ACTIVITY),
|
ATTR_ACTIVITY,
|
||||||
): vol.In(remote.activity_names),
|
default=self.config_entry.options.get(
|
||||||
vol.Optional(
|
ATTR_ACTIVITY, PREVIOUS_ACTIVE_ACTIVITY
|
||||||
ATTR_ACTIVITY_NOTIFY,
|
),
|
||||||
default=self.config_entry.options.get(ATTR_ACTIVITY_NOTIFY, False),
|
): vol.In([PREVIOUS_ACTIVE_ACTIVITY, *remote.activity_names]),
|
||||||
): vol.Coerce(bool),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return self.async_show_form(step_id="init", data_schema=data_schema)
|
return self.async_show_form(step_id="init", data_schema=data_schema)
|
||||||
|
@ -6,4 +6,8 @@ PLATFORMS = ["remote"]
|
|||||||
UNIQUE_ID = "unique_id"
|
UNIQUE_ID = "unique_id"
|
||||||
ACTIVITY_POWER_OFF = "PowerOff"
|
ACTIVITY_POWER_OFF = "PowerOff"
|
||||||
HARMONY_OPTIONS_UPDATE = "harmony_options_update"
|
HARMONY_OPTIONS_UPDATE = "harmony_options_update"
|
||||||
ATTR_ACTIVITY_NOTIFY = "activity_notify"
|
ATTR_ACTIVITY_LIST = "activity_list"
|
||||||
|
ATTR_DEVICES_LIST = "devices_list"
|
||||||
|
ATTR_LAST_ACTIVITY = "last_activity"
|
||||||
|
ATTR_CURRENT_ACTIVITY = "current_activity"
|
||||||
|
PREVIOUS_ACTIVE_ACTIVITY = "Previous Active Activity"
|
||||||
|
@ -25,12 +25,17 @@ from homeassistant.exceptions import PlatformNotReady
|
|||||||
from homeassistant.helpers import entity_platform
|
from homeassistant.helpers import entity_platform
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ACTIVITY_POWER_OFF,
|
ACTIVITY_POWER_OFF,
|
||||||
ATTR_ACTIVITY_NOTIFY,
|
ATTR_ACTIVITY_LIST,
|
||||||
|
ATTR_CURRENT_ACTIVITY,
|
||||||
|
ATTR_DEVICES_LIST,
|
||||||
|
ATTR_LAST_ACTIVITY,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
HARMONY_OPTIONS_UPDATE,
|
HARMONY_OPTIONS_UPDATE,
|
||||||
|
PREVIOUS_ACTIVE_ACTIVITY,
|
||||||
SERVICE_CHANGE_CHANNEL,
|
SERVICE_CHANGE_CHANNEL,
|
||||||
SERVICE_SYNC,
|
SERVICE_SYNC,
|
||||||
UNIQUE_ID,
|
UNIQUE_ID,
|
||||||
@ -40,6 +45,7 @@ from .util import (
|
|||||||
find_matching_config_entries_for_host,
|
find_matching_config_entries_for_host,
|
||||||
find_unique_id_for_remote,
|
find_unique_id_for_remote,
|
||||||
get_harmony_client_if_available,
|
get_harmony_client_if_available,
|
||||||
|
list_names_from_hublist,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -48,7 +54,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
ATTR_CHANNEL = "channel"
|
ATTR_CHANNEL = "channel"
|
||||||
ATTR_CURRENT_ACTIVITY = "current_activity"
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
@ -123,12 +128,10 @@ async def async_setup_entry(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HarmonyRemote(remote.RemoteEntity):
|
class HarmonyRemote(remote.RemoteEntity, RestoreEntity):
|
||||||
"""Remote representation used to control a Harmony device."""
|
"""Remote representation used to control a Harmony device."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, name, unique_id, host, activity, out_path, delay_secs):
|
||||||
self, name, unique_id, host, activity, out_path, delay_secs, activity_notify
|
|
||||||
):
|
|
||||||
"""Initialize HarmonyRemote class."""
|
"""Initialize HarmonyRemote class."""
|
||||||
self._name = name
|
self._name = name
|
||||||
self.host = host
|
self.host = host
|
||||||
@ -140,7 +143,7 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
self.delay_secs = delay_secs
|
self.delay_secs = delay_secs
|
||||||
self._available = False
|
self._available = False
|
||||||
self._unique_id = unique_id
|
self._unique_id = unique_id
|
||||||
self._activity_notify = activity_notify
|
self._last_activity = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def activity_names(self):
|
def activity_names(self):
|
||||||
@ -163,26 +166,20 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
if ATTR_ACTIVITY in data:
|
if ATTR_ACTIVITY in data:
|
||||||
self.default_activity = data[ATTR_ACTIVITY]
|
self.default_activity = data[ATTR_ACTIVITY]
|
||||||
|
|
||||||
if ATTR_ACTIVITY_NOTIFY in data:
|
|
||||||
self._activity_notify = data[ATTR_ACTIVITY_NOTIFY]
|
|
||||||
self._update_callbacks()
|
|
||||||
|
|
||||||
def _update_callbacks(self):
|
def _update_callbacks(self):
|
||||||
callbacks = {
|
callbacks = {
|
||||||
"config_updated": self.new_config,
|
"config_updated": self.new_config,
|
||||||
"connect": self.got_connected,
|
"connect": self.got_connected,
|
||||||
"disconnect": self.got_disconnected,
|
"disconnect": self.got_disconnected,
|
||||||
"new_activity_starting": None,
|
"new_activity_starting": self.new_activity,
|
||||||
"new_activity": None,
|
"new_activity": None,
|
||||||
}
|
}
|
||||||
if self._activity_notify:
|
|
||||||
callbacks["new_activity_starting"] = self.new_activity
|
|
||||||
else:
|
|
||||||
callbacks["new_activity"] = self.new_activity
|
|
||||||
self._client.callbacks = ClientCallbackType(**callbacks)
|
self._client.callbacks = ClientCallbackType(**callbacks)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Complete the initialization."""
|
"""Complete the initialization."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
_LOGGER.debug("%s: Harmony Hub added", self._name)
|
_LOGGER.debug("%s: Harmony Hub added", self._name)
|
||||||
# Register the callbacks
|
# Register the callbacks
|
||||||
self._update_callbacks()
|
self._update_callbacks()
|
||||||
@ -199,6 +196,19 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
# activity
|
# activity
|
||||||
await self.new_config()
|
await self.new_config()
|
||||||
|
|
||||||
|
# Restore the last activity so we know
|
||||||
|
# how what to turn on if nothing
|
||||||
|
# is specified
|
||||||
|
last_state = await self.async_get_last_state()
|
||||||
|
if not last_state:
|
||||||
|
return
|
||||||
|
if ATTR_LAST_ACTIVITY not in last_state.attributes:
|
||||||
|
return
|
||||||
|
if self.is_on:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._last_activity = last_state.attributes[ATTR_LAST_ACTIVITY]
|
||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
"""Close connection on shutdown."""
|
"""Close connection on shutdown."""
|
||||||
_LOGGER.debug("%s: Closing Harmony Hub", self._name)
|
_LOGGER.debug("%s: Closing Harmony Hub", self._name)
|
||||||
@ -241,7 +251,14 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Add platform specific attributes."""
|
"""Add platform specific attributes."""
|
||||||
return {ATTR_CURRENT_ACTIVITY: self._current_activity}
|
return {
|
||||||
|
ATTR_CURRENT_ACTIVITY: self._current_activity,
|
||||||
|
ATTR_ACTIVITY_LIST: list_names_from_hublist(
|
||||||
|
self._client.hub_config.activities
|
||||||
|
),
|
||||||
|
ATTR_DEVICES_LIST: list_names_from_hublist(self._client.hub_config.devices),
|
||||||
|
ATTR_LAST_ACTIVITY: self._last_activity,
|
||||||
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
@ -271,6 +288,11 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
activity_id, activity_name = activity_info
|
activity_id, activity_name = activity_info
|
||||||
_LOGGER.debug("%s: activity reported as: %s", self._name, activity_name)
|
_LOGGER.debug("%s: activity reported as: %s", self._name, activity_name)
|
||||||
self._current_activity = activity_name
|
self._current_activity = activity_name
|
||||||
|
if activity_id != -1:
|
||||||
|
# Save the activity so we can restore
|
||||||
|
# to that activity if none is specified
|
||||||
|
# when turning on
|
||||||
|
self._last_activity = activity_name
|
||||||
self._state = bool(activity_id != -1)
|
self._state = bool(activity_id != -1)
|
||||||
self._available = True
|
self._available = True
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
@ -306,6 +328,16 @@ class HarmonyRemote(remote.RemoteEntity):
|
|||||||
|
|
||||||
activity = kwargs.get(ATTR_ACTIVITY, self.default_activity)
|
activity = kwargs.get(ATTR_ACTIVITY, self.default_activity)
|
||||||
|
|
||||||
|
if not activity or activity == PREVIOUS_ACTIVE_ACTIVITY:
|
||||||
|
if self._last_activity:
|
||||||
|
activity = self._last_activity
|
||||||
|
else:
|
||||||
|
all_activities = list_names_from_hublist(
|
||||||
|
self._client.hub_config.activities
|
||||||
|
)
|
||||||
|
if all_activities:
|
||||||
|
activity = all_activities[0]
|
||||||
|
|
||||||
if activity:
|
if activity:
|
||||||
activity_id = None
|
activity_id = None
|
||||||
if activity.isdigit() or activity == "-1":
|
if activity.isdigit() or activity == "-1":
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
"description": "Adjust Harmony Hub Options",
|
"description": "Adjust Harmony Hub Options",
|
||||||
"data": {
|
"data": {
|
||||||
"activity": "The default activity to execute when none is specified.",
|
"activity": "The default activity to execute when none is specified.",
|
||||||
"delay_secs": "The delay between sending commands.",
|
"delay_secs": "The delay between sending commands."
|
||||||
"activity_notify": "Update current activity on start of activity switch."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
"init": {
|
"init": {
|
||||||
"data": {
|
"data": {
|
||||||
"activity": "The default activity to execute when none is specified.",
|
"activity": "The default activity to execute when none is specified.",
|
||||||
"activity_notify": "Update current activity on start of activity switch.",
|
|
||||||
"delay_secs": "The delay between sending commands."
|
"delay_secs": "The delay between sending commands."
|
||||||
},
|
},
|
||||||
"description": "Adjust Harmony Hub Options"
|
"description": "Adjust Harmony Hub Options"
|
||||||
|
@ -49,3 +49,14 @@ def find_matching_config_entries_for_host(hass, host):
|
|||||||
if entry.data[CONF_HOST] == host:
|
if entry.data[CONF_HOST] == host:
|
||||||
return entry
|
return entry
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def list_names_from_hublist(hub_list):
|
||||||
|
"""Extract the name key value from a hub list of names."""
|
||||||
|
if not hub_list:
|
||||||
|
return []
|
||||||
|
return [
|
||||||
|
element["name"]
|
||||||
|
for element in hub_list
|
||||||
|
if element.get("name") and element.get("id") != -1
|
||||||
|
]
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
"""Test the Logitech Harmony Hub config flow."""
|
"""Test the Logitech Harmony Hub config flow."""
|
||||||
from homeassistant import config_entries, setup
|
from homeassistant import config_entries, data_entry_flow, setup
|
||||||
from homeassistant.components.harmony.config_flow import CannotConnect
|
from homeassistant.components.harmony.config_flow import CannotConnect
|
||||||
from homeassistant.components.harmony.const import DOMAIN
|
from homeassistant.components.harmony.const import DOMAIN, PREVIOUS_ACTIVE_ACTIVITY
|
||||||
|
from homeassistant.const import CONF_HOST, CONF_NAME
|
||||||
|
|
||||||
from tests.async_mock import AsyncMock, MagicMock, patch
|
from tests.async_mock import AsyncMock, MagicMock, PropertyMock, patch
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
def _get_mock_harmonyapi(connect=None, close=None):
|
def _get_mock_harmonyapi(connect=None, close=None):
|
||||||
@ -14,6 +16,23 @@ def _get_mock_harmonyapi(connect=None, close=None):
|
|||||||
return harmonyapi_mock
|
return harmonyapi_mock
|
||||||
|
|
||||||
|
|
||||||
|
def _get_mock_harmonyclient():
|
||||||
|
harmonyclient_mock = MagicMock()
|
||||||
|
type(harmonyclient_mock).connect = AsyncMock()
|
||||||
|
type(harmonyclient_mock).close = AsyncMock()
|
||||||
|
type(harmonyclient_mock).get_activity_name = MagicMock(return_value="Watch TV")
|
||||||
|
type(harmonyclient_mock.hub_config).activities = PropertyMock(
|
||||||
|
return_value=[{"name": "Watch TV", "id": 123}]
|
||||||
|
)
|
||||||
|
type(harmonyclient_mock.hub_config).devices = PropertyMock(
|
||||||
|
return_value=[{"name": "My TV", "id": 1234}]
|
||||||
|
)
|
||||||
|
type(harmonyclient_mock.hub_config).info = PropertyMock(return_value={})
|
||||||
|
type(harmonyclient_mock.hub_config).hub_state = PropertyMock(return_value={})
|
||||||
|
|
||||||
|
return harmonyclient_mock
|
||||||
|
|
||||||
|
|
||||||
async def test_user_form(hass):
|
async def test_user_form(hass):
|
||||||
"""Test we get the user form."""
|
"""Test we get the user form."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||||
@ -37,10 +56,7 @@ async def test_user_form(hass):
|
|||||||
|
|
||||||
assert result2["type"] == "create_entry"
|
assert result2["type"] == "create_entry"
|
||||||
assert result2["title"] == "friend"
|
assert result2["title"] == "friend"
|
||||||
assert result2["data"] == {
|
assert result2["data"] == {"host": "1.2.3.4", "name": "friend"}
|
||||||
"host": "1.2.3.4",
|
|
||||||
"name": "friend",
|
|
||||||
}
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_setup.mock_calls) == 1
|
assert len(mock_setup.mock_calls) == 1
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
@ -66,7 +82,6 @@ async def test_form_import(hass):
|
|||||||
"name": "friend",
|
"name": "friend",
|
||||||
"activity": "Watch TV",
|
"activity": "Watch TV",
|
||||||
"delay_secs": 0.9,
|
"delay_secs": 0.9,
|
||||||
"activity_notify": True,
|
|
||||||
"unique_id": "555234534543",
|
"unique_id": "555234534543",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -79,7 +94,6 @@ async def test_form_import(hass):
|
|||||||
"name": "friend",
|
"name": "friend",
|
||||||
"activity": "Watch TV",
|
"activity": "Watch TV",
|
||||||
"delay_secs": 0.9,
|
"delay_secs": 0.9,
|
||||||
"activity_notify": True,
|
|
||||||
}
|
}
|
||||||
# It is not possible to import options at this time
|
# It is not possible to import options at this time
|
||||||
# so they end up in the config entry data and are
|
# so they end up in the config entry data and are
|
||||||
@ -125,10 +139,7 @@ async def test_form_ssdp(hass):
|
|||||||
|
|
||||||
assert result2["type"] == "create_entry"
|
assert result2["type"] == "create_entry"
|
||||||
assert result2["title"] == "Harmony Hub"
|
assert result2["title"] == "Harmony Hub"
|
||||||
assert result2["data"] == {
|
assert result2["data"] == {"host": "192.168.1.12", "name": "Harmony Hub"}
|
||||||
"host": "192.168.1.12",
|
|
||||||
"name": "Harmony Hub",
|
|
||||||
}
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_setup.mock_calls) == 1
|
assert len(mock_setup.mock_calls) == 1
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
@ -150,9 +161,46 @@ async def test_form_cannot_connect(hass):
|
|||||||
"name": "friend",
|
"name": "friend",
|
||||||
"activity": "Watch TV",
|
"activity": "Watch TV",
|
||||||
"delay_secs": 0.2,
|
"delay_secs": 0.2,
|
||||||
"activity_notify": True,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
assert result2["errors"] == {"base": "cannot_connect"}
|
assert result2["errors"] == {"base": "cannot_connect"}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_options_flow(hass):
|
||||||
|
"""Test config flow options."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
unique_id="abcde12345",
|
||||||
|
data={CONF_HOST: "1.2.3.4", CONF_NAME: "Guest Room"},
|
||||||
|
options={"activity": "Watch TV", "delay_secs": 0.5},
|
||||||
|
)
|
||||||
|
|
||||||
|
harmony_client = _get_mock_harmonyclient()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"aioharmony.harmonyapi.HarmonyClient", return_value=harmony_client,
|
||||||
|
), patch("homeassistant.components.harmony.remote.HarmonyRemote.write_config_file"):
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={"activity": PREVIOUS_ACTIVE_ACTIVITY, "delay_secs": 0.4},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert config_entry.options == {
|
||||||
|
"activity": PREVIOUS_ACTIVE_ACTIVITY,
|
||||||
|
"delay_secs": 0.4,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user