Address Honeywell late review (#86202)

This commit is contained in:
mkmer 2023-01-20 14:30:48 -05:00 committed by GitHub
parent df77646c8a
commit 7f4a727e10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 30 deletions

View File

@ -26,6 +26,7 @@ from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import HoneywellData
from .const import ( from .const import (
_LOGGER, _LOGGER,
CONF_COOL_AWAY_TEMPERATURE, CONF_COOL_AWAY_TEMPERATURE,
@ -70,7 +71,7 @@ HW_FAN_MODE_TO_HA = {
"follow schedule": FAN_AUTO, "follow schedule": FAN_AUTO,
} }
SCAN_INTERVAL = datetime.timedelta(seconds=10) SCAN_INTERVAL = datetime.timedelta(seconds=30)
async def async_setup_entry( async def async_setup_entry(
@ -93,7 +94,13 @@ async def async_setup_entry(
class HoneywellUSThermostat(ClimateEntity): class HoneywellUSThermostat(ClimateEntity):
"""Representation of a Honeywell US Thermostat.""" """Representation of a Honeywell US Thermostat."""
def __init__(self, data, device, cool_away_temp, heat_away_temp): def __init__(
self,
data: HoneywellData,
device: AIOSomecomfort.device.Device,
cool_away_temp: int | None,
heat_away_temp: int | None,
) -> None:
"""Initialize the thermostat.""" """Initialize the thermostat."""
self._data = data self._data = data
self._device = device self._device = device
@ -110,8 +117,13 @@ class HoneywellUSThermostat(ClimateEntity):
self._attr_is_aux_heat = device.system_mode == "emheat" self._attr_is_aux_heat = device.system_mode == "emheat"
# not all honeywell HVACs support all modes # not all honeywell HVACs support all modes
mappings = [v for k, v in HVAC_MODE_TO_HW_MODE.items() if device.raw_ui_data[k]]
self._hvac_mode_map = {k: v for d in mappings for k, v in d.items()} self._hvac_mode_map = {
key2: value2
for key1, value1 in HVAC_MODE_TO_HW_MODE.items()
if device.raw_ui_data[key1]
for key2, value2 in value1.items()
}
self._attr_hvac_modes = list(self._hvac_mode_map) self._attr_hvac_modes = list(self._hvac_mode_map)
self._attr_supported_features = ( self._attr_supported_features = (
@ -130,8 +142,12 @@ class HoneywellUSThermostat(ClimateEntity):
return return
# not all honeywell fans support all modes # not all honeywell fans support all modes
mappings = [v for k, v in FAN_MODE_TO_HW.items() if device.raw_fan_data[k]] self._fan_mode_map = {
self._fan_mode_map = {k: v for d in mappings for k, v in d.items()} key2: value2
for key1, value1 in FAN_MODE_TO_HW.items()
if device.raw_fan_data[key1]
for key2, value2 in value1.items()
}
self._attr_fan_modes = list(self._fan_mode_map) self._attr_fan_modes = list(self._fan_mode_map)
@ -246,15 +262,15 @@ class HoneywellUSThermostat(ClimateEntity):
# Get next period time # Get next period time
hour, minute = divmod(next_period * 15, 60) hour, minute = divmod(next_period * 15, 60)
# Set hold time # Set hold time
if mode == HVACMode.COOL: if mode == "cool":
await self._device.set_hold_cool(datetime.time(hour, minute)) await self._device.set_hold_cool(datetime.time(hour, minute))
elif mode == HVACMode.HEAT: elif mode == "heat":
await self._device.set_hold_heat(datetime.time(hour, minute)) await self._device.set_hold_heat(datetime.time(hour, minute))
# Set temperature # Set temperature
if mode == HVACMode.COOL: if mode == "cool":
await self._device.set_setpoint_cool(temperature) await self._device.set_setpoint_cool(temperature)
elif mode == HVACMode.HEAT: elif mode == "heat":
await self._device.set_setpoint_heat(temperature) await self._device.set_setpoint_heat(temperature)
except AIOSomecomfort.SomeComfortError: except AIOSomecomfort.SomeComfortError:
@ -301,10 +317,10 @@ class HoneywellUSThermostat(ClimateEntity):
# Set permanent hold # Set permanent hold
# and Set temperature # and Set temperature
away_temp = getattr(self, f"_{mode}_away_temp") away_temp = getattr(self, f"_{mode}_away_temp")
if mode == HVACMode.COOL: if mode == "cool":
self._device.set_hold_cool(True) self._device.set_hold_cool(True)
self._device.set_setpoint_cool(away_temp) self._device.set_setpoint_cool(away_temp)
elif mode == HVACMode.HEAT: elif mode == "heat":
self._device.set_hold_heat(True) self._device.set_hold_heat(True)
self._device.set_setpoint_heat(away_temp) self._device.set_setpoint_heat(away_temp)
@ -325,9 +341,9 @@ class HoneywellUSThermostat(ClimateEntity):
if mode in HW_MODE_TO_HVAC_MODE: if mode in HW_MODE_TO_HVAC_MODE:
try: try:
# Set permanent hold # Set permanent hold
if mode == HVACMode.COOL: if mode == "cool":
await self._device.set_hold_cool(True) await self._device.set_hold_cool(True)
elif mode == HVACMode.HEAT: elif mode == "heat":
await self._device.set_hold_heat(True) await self._device.set_hold_heat(True)
except AIOSomecomfort.SomeComfortError: except AIOSomecomfort.SomeComfortError:

View File

@ -29,10 +29,9 @@ class HoneywellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_user(self, user_input=None) -> FlowResult:
"""Create config entry. Show the setup form to the user.""" """Create config entry. Show the setup form to the user."""
errors = {} errors = {}
valid = False
if user_input is not None: if user_input is not None:
try: try:
valid = await self.is_valid(**user_input) await self.is_valid(**user_input)
except AIOSomecomfort.AuthError: except AIOSomecomfort.AuthError:
errors["base"] = "invalid_auth" errors["base"] = "invalid_auth"
except ( except (
@ -42,7 +41,7 @@ class HoneywellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
): ):
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
if valid: if not errors:
return self.async_create_entry( return self.async_create_entry(
title=DOMAIN, title=DOMAIN,
data=user_input, data=user_input,

View File

@ -36,6 +36,7 @@ async def test_show_authenticate_form(hass: HomeAssistant) -> None:
async def test_connection_error(hass: HomeAssistant, client: MagicMock) -> None: async def test_connection_error(hass: HomeAssistant, client: MagicMock) -> None:
"""Test that an error message is shown on connection fail.""" """Test that an error message is shown on connection fail."""
client.login.side_effect = AIOSomecomfort.ConnectionError client.login.side_effect = AIOSomecomfort.ConnectionError
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG
) )
@ -45,6 +46,7 @@ async def test_connection_error(hass: HomeAssistant, client: MagicMock) -> None:
async def test_auth_error(hass: HomeAssistant, client: MagicMock) -> None: async def test_auth_error(hass: HomeAssistant, client: MagicMock) -> None:
"""Test that an error message is shown on login fail.""" """Test that an error message is shown on login fail."""
client.login.side_effect = AIOSomecomfort.AuthError client.login.side_effect = AIOSomecomfort.AuthError
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG
) )
@ -53,17 +55,21 @@ async def test_auth_error(hass: HomeAssistant, client: MagicMock) -> None:
async def test_create_entry(hass: HomeAssistant) -> None: async def test_create_entry(hass: HomeAssistant) -> None:
"""Test that the config entry is created.""" """Test that the config entry is created."""
with patch(
"homeassistant.components.honeywell.async_setup_entry",
return_value=True,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=FAKE_CONFIG
)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"] == FAKE_CONFIG assert result["data"] == FAKE_CONFIG
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_show_option_form( async def test_show_option_form(
hass: HomeAssistant, config_entry: MockConfigEntry, location hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:
"""Test that the option form is shown.""" """Test that the option form is shown."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -72,15 +78,18 @@ async def test_show_option_form(
assert config_entry.state is ConfigEntryState.LOADED assert config_entry.state is ConfigEntryState.LOADED
result = await hass.config_entries.options.async_init(config_entry.entry_id) with patch(
"homeassistant.components.honeywell.async_setup_entry",
return_value=True,
):
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "init" assert result["step_id"] == "init"
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_create_option_entry( async def test_create_option_entry(
hass: HomeAssistant, config_entry: MockConfigEntry, location hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:
"""Test that the config entry is created.""" """Test that the config entry is created."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -89,11 +98,18 @@ async def test_create_option_entry(
assert config_entry.state is ConfigEntryState.LOADED assert config_entry.state is ConfigEntryState.LOADED
options_form = await hass.config_entries.options.async_init(config_entry.entry_id) with patch(
result = await hass.config_entries.options.async_configure( "homeassistant.components.honeywell.async_setup_entry",
options_form["flow_id"], return_value=True,
user_input={CONF_COOL_AWAY_TEMPERATURE: 1, CONF_HEAT_AWAY_TEMPERATURE: 2}, ):
) options_form = await hass.config_entries.options.async_init(
config_entry.entry_id
)
result = await hass.config_entries.options.async_configure(
options_form["flow_id"],
user_input={CONF_COOL_AWAY_TEMPERATURE: 1, CONF_HEAT_AWAY_TEMPERATURE: 2},
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert config_entry.options == { assert config_entry.options == {