Honeywell away temps (#54704)

This commit is contained in:
RDFurman 2022-03-24 19:17:36 -06:00 committed by GitHub
parent c5c34bc0d7
commit 34ace2e1cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 188 additions and 7 deletions

View File

@ -6,19 +6,48 @@ import somecomfort
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.util import Throttle
from .const import _LOGGER, CONF_DEV_ID, CONF_LOC_ID, DOMAIN
from .const import (
_LOGGER,
CONF_COOL_AWAY_TEMPERATURE,
CONF_DEV_ID,
CONF_HEAT_AWAY_TEMPERATURE,
CONF_LOC_ID,
DOMAIN,
)
UPDATE_LOOP_SLEEP_TIME = 5
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300)
PLATFORMS = [Platform.CLIMATE]
MIGRATE_OPTIONS_KEYS = {CONF_COOL_AWAY_TEMPERATURE, CONF_HEAT_AWAY_TEMPERATURE}
@callback
def _async_migrate_data_to_options(
hass: HomeAssistant, config_entry: ConfigEntry
) -> None:
if not MIGRATE_OPTIONS_KEYS.intersection(config_entry.data):
return
hass.config_entries.async_update_entry(
config_entry,
data={
k: v for k, v in config_entry.data.items() if k not in MIGRATE_OPTIONS_KEYS
},
options={
**config_entry.options,
**{k: config_entry.data.get(k) for k in MIGRATE_OPTIONS_KEYS},
},
)
async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
"""Set up the Honeywell thermostat."""
_async_migrate_data_to_options(hass, config)
username = config.data[CONF_USERNAME]
password = config.data[CONF_PASSWORD]

View File

@ -81,8 +81,8 @@ PARALLEL_UPDATES = 1
async def async_setup_entry(hass, config, async_add_entities, discovery_info=None):
"""Set up the Honeywell thermostat."""
cool_away_temp = config.data.get(CONF_COOL_AWAY_TEMPERATURE)
heat_away_temp = config.data.get(CONF_HEAT_AWAY_TEMPERATURE)
cool_away_temp = config.options.get(CONF_COOL_AWAY_TEMPERATURE)
heat_away_temp = config.options.get(CONF_HEAT_AWAY_TEMPERATURE)
data = hass.data[DOMAIN][config.entry_id]

View File

@ -3,9 +3,16 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import callback
from . import get_somecomfort_client
from .const import DOMAIN
from .const import (
CONF_COOL_AWAY_TEMPERATURE,
CONF_HEAT_AWAY_TEMPERATURE,
DEFAULT_COOL_AWAY_TEMPERATURE,
DEFAULT_HEAT_AWAY_TEMPERATURE,
DOMAIN,
)
class HoneywellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
@ -42,3 +49,42 @@ class HoneywellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
return client is not None
@staticmethod
@callback
def async_get_options_flow(config_entry):
"""Options callback for Honeywell."""
return HoneywellOptionsFlowHandler(config_entry)
class HoneywellOptionsFlowHandler(config_entries.OptionsFlow):
"""Config flow options for Honeywell."""
def __init__(self, entry: config_entries.ConfigEntry) -> None:
"""Initialize Honeywell options flow."""
self.config_entry = entry
async def async_step_init(self, user_input=None):
"""Manage the options."""
if user_input is not None:
return self.async_create_entry(title=DOMAIN, data=user_input)
return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Required(
CONF_COOL_AWAY_TEMPERATURE,
default=self.config_entry.options.get(
CONF_COOL_AWAY_TEMPERATURE, DEFAULT_COOL_AWAY_TEMPERATURE
),
): int,
vol.Required(
CONF_HEAT_AWAY_TEMPERATURE,
default=self.config_entry.options.get(
CONF_HEAT_AWAY_TEMPERATURE, DEFAULT_HEAT_AWAY_TEMPERATURE
),
): int,
}
),
)

View File

@ -5,6 +5,8 @@ DOMAIN = "honeywell"
CONF_COOL_AWAY_TEMPERATURE = "away_cool_temperature"
CONF_HEAT_AWAY_TEMPERATURE = "away_heat_temperature"
DEFAULT_COOL_AWAY_TEMPERATURE = 88
DEFAULT_HEAT_AWAY_TEMPERATURE = 61
CONF_DEV_ID = "thermostat"
CONF_LOC_ID = "location"

View File

@ -13,5 +13,17 @@
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
}
},
"options": {
"step": {
"init": {
"title": "Honeywell Options",
"description": "Additional Honeywell config options. Temperatures are set in Fahrenheit.",
"data": {
"away_cool_temperature": "Away cool temperature",
"away_heat_temperature": "Away heat temperature"
}
}
}
}
}

View File

@ -13,5 +13,17 @@
"title": "Honeywell Total Connect Comfort (US)"
}
}
},
"options": {
"step": {
"init": {
"data": {
"away_cool_temperature": "Away cool temperature",
"away_heat_temperature": "Away heat temperature"
},
"description": "Additional Honeywell config options. Temperatures are set in Fahrenheit.",
"title": "Honeywell Options"
}
}
}
}

View File

@ -4,10 +4,16 @@ from unittest.mock import patch
import somecomfort
from homeassistant import data_entry_flow
from homeassistant.components.honeywell.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER
from homeassistant.components.honeywell.const import (
CONF_COOL_AWAY_TEMPERATURE,
CONF_HEAT_AWAY_TEMPERATURE,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
FAKE_CONFIG = {
"username": "fake",
"password": "user",
@ -49,3 +55,44 @@ async def test_create_entry(hass: HomeAssistant) -> None:
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == FAKE_CONFIG
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_show_option_form(
hass: HomeAssistant, config_entry: MockConfigEntry, location
) -> None:
"""Test that the option form is shown."""
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_create_option_entry(
hass: HomeAssistant, config_entry: MockConfigEntry, location
) -> None:
"""Test that the config entry is created."""
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
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},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
CONF_COOL_AWAY_TEMPERATURE: 1,
CONF_HEAT_AWAY_TEMPERATURE: 2,
}

View File

@ -4,11 +4,19 @@ from unittest.mock import create_autospec, patch
import somecomfort
from homeassistant.components.honeywell.const import (
CONF_COOL_AWAY_TEMPERATURE,
CONF_HEAT_AWAY_TEMPERATURE,
DOMAIN,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
MIGRATE_OPTIONS_KEYS = {CONF_COOL_AWAY_TEMPERATURE, CONF_HEAT_AWAY_TEMPERATURE}
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_setup_entry(hass: HomeAssistant, config_entry: MockConfigEntry):
@ -48,3 +56,28 @@ async def test_setup_multiple_thermostats_with_same_deviceid(
assert config_entry.state is ConfigEntryState.LOADED
assert hass.states.async_entity_ids_count() == 1
assert "Platform honeywell does not generate unique IDs" not in caplog.text
async def test_away_temps_migration(hass: HomeAssistant) -> None:
"""Test away temps migrate to config options."""
legacy_config = MockConfigEntry(
domain=DOMAIN,
data={
CONF_USERNAME: "fake",
CONF_PASSWORD: "user",
CONF_COOL_AWAY_TEMPERATURE: 1,
CONF_HEAT_AWAY_TEMPERATURE: 2,
},
options={},
)
with patch(
"homeassistant.components.honeywell.somecomfort.SomeComfort",
):
legacy_config.add_to_hass(hass)
await hass.config_entries.async_setup(legacy_config.entry_id)
await hass.async_block_till_done()
assert legacy_config.options == {
CONF_COOL_AWAY_TEMPERATURE: 1,
CONF_HEAT_AWAY_TEMPERATURE: 2,
}