mirror of
https://github.com/home-assistant/core.git
synced 2025-04-28 11:17:53 +00:00

* Add an integration for Bryant Evolution HVAC systems. * Update newly created tests so that they pass. * Improve compliance with home assistant guidelines. * Added tests * remove xxx * Minor test cleanups * Add a test for reading HVAC actions. * Update homeassistant/components/bryant_evolution/__init__.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/climate.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/climate.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/climate.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/climate.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/climate.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Update homeassistant/components/bryant_evolution/config_flow.py Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> * Address reviewer comments. * Address additional reviewer comments. * Use translation for exception error messages. * Simplify config flow. * Continue addressing comments * Use mocking rather than DI to provide a for-test client in tests. * Fix a failure in test_config_flow.py * Track host->filename in strings.json. * Use config entry ID for climate entity unique id * Guard against fan mode returning None in async_update. * Move unavailable-client check from climate.py to init.py. * Improve test coverage * Bump evolutionhttp version * Address comments * update comment * only have one _can_reach_device fn * Auto-detect which systems and zones are attached. * Add support for reconfiguration * Fix a few review comments * Introduce multiple devices * Track evolutionhttp library change that returns additional per-zone information during enumeration * Move construction of devices to init * Avoid triplicate writing * rework tests to use mocks * Correct attribute name to unbreak test * Pull magic tuple of system-zone into a constant * Address some test comments * Create test_init.py * simplify test_reconfigure * Replace disable_auto_entity_update with mocks. * Update tests/components/bryant_evolution/test_climate.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/bryant_evolution/test_climate.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/bryant_evolution/test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/bryant_evolution/config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/bryant_evolution/test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/bryant_evolution/test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * fix test errors * do not access runtime_data in tests * use snapshot_platform and type fixtures --------- Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
113 lines
4.4 KiB
Python
113 lines
4.4 KiB
Python
"""Test setup for the bryant_evolution integration."""
|
|
|
|
import logging
|
|
from unittest.mock import AsyncMock
|
|
|
|
from evolutionhttp import BryantEvolutionLocalClient
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
|
|
from homeassistant.components.bryant_evolution.const import CONF_SYSTEM_ZONE, DOMAIN
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.const import CONF_FILENAME
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
|
|
|
from .conftest import DEFAULT_SYSTEM_ZONES
|
|
from .test_climate import trigger_polling
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def test_setup_integration_prevented_by_unavailable_client(
|
|
hass: HomeAssistant, mock_evolution_client_factory: AsyncMock
|
|
) -> None:
|
|
"""Test that setup throws ConfigEntryNotReady when the client is unavailable."""
|
|
mock_evolution_client_factory.side_effect = FileNotFoundError("test error")
|
|
mock_evolution_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
CONF_FILENAME: "test_setup_integration_prevented_by_unavailable_client",
|
|
CONF_SYSTEM_ZONE: [(1, 1)],
|
|
},
|
|
)
|
|
mock_evolution_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_evolution_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
assert mock_evolution_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
async def test_setup_integration_client_returns_none(
|
|
hass: HomeAssistant, mock_evolution_client_factory: AsyncMock
|
|
) -> None:
|
|
"""Test that an unavailable client causes ConfigEntryNotReady."""
|
|
mock_client = AsyncMock(spec=BryantEvolutionLocalClient)
|
|
mock_evolution_client_factory.side_effect = None
|
|
mock_evolution_client_factory.return_value = mock_client
|
|
mock_client.read_fan_mode.return_value = None
|
|
mock_client.read_current_temperature.return_value = None
|
|
mock_client.read_hvac_mode.return_value = None
|
|
mock_client.read_cooling_setpoint.return_value = None
|
|
mock_client.read_zone_name.return_value = None
|
|
mock_evolution_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_FILENAME: "/dev/ttyUSB0", CONF_SYSTEM_ZONE: [(1, 1)]},
|
|
)
|
|
mock_evolution_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_evolution_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
assert mock_evolution_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
async def test_setup_multiple_systems_zones(
|
|
hass: HomeAssistant,
|
|
mock_evolution_client_factory: AsyncMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
) -> None:
|
|
"""Test that a device with multiple systems and zones works."""
|
|
hass.config.units = US_CUSTOMARY_SYSTEM
|
|
mock_evolution_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_FILENAME: "/dev/ttyUSB0", CONF_SYSTEM_ZONE: DEFAULT_SYSTEM_ZONES},
|
|
)
|
|
mock_evolution_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_evolution_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
# Set the temperature of each zone to its zone number so that we can
|
|
# ensure we've created the right client for each zone.
|
|
for sz, client in mock_evolution_entry.runtime_data.items():
|
|
client.read_current_temperature.return_value = sz[1]
|
|
await trigger_polling(hass, freezer)
|
|
|
|
# Check that each system and zone has the expected temperature value to
|
|
# verify that the initial setup flow worked as expected.
|
|
for sz in DEFAULT_SYSTEM_ZONES:
|
|
system = sz[0]
|
|
zone = sz[1]
|
|
state = hass.states.get(f"climate.system_{system}_zone_{zone}")
|
|
assert state, hass.states.async_all()
|
|
assert state.attributes["current_temperature"] == zone
|
|
|
|
# Check that the created devices are wired to each other as expected.
|
|
device_registry = dr.async_get(hass)
|
|
|
|
def find_device(name):
|
|
return next(filter(lambda x: x.name == name, device_registry.devices.values()))
|
|
|
|
sam = find_device("System Access Module")
|
|
s1 = find_device("System 1")
|
|
s2 = find_device("System 2")
|
|
s1z1 = find_device("System 1 Zone 1")
|
|
s1z2 = find_device("System 1 Zone 2")
|
|
s2z3 = find_device("System 2 Zone 3")
|
|
|
|
assert sam.via_device_id is None
|
|
assert s1.via_device_id == sam.id
|
|
assert s2.via_device_id == sam.id
|
|
assert s1z1.via_device_id == s1.id
|
|
assert s1z2.via_device_id == s1.id
|
|
assert s2z3.via_device_id == s2.id
|