Climate 1.0 (#23899)
* Climate 1.0 / part 1/2/3
* fix flake
* Lint
* Update Google Assistant
* ambiclimate to climate 1.0 (#24911)
* Fix Alexa
* Lint
* Migrate zhong_hong
* Migrate tuya
* Migrate honeywell to new climate schema (#24257)
* Update one
* Fix model climate v2
* Cleanup p4
* Add comfort hold mode
* Fix old code
* Update homeassistant/components/climate/__init__.py
Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
* Update homeassistant/components/climate/const.py
Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
* First renaming
* Rename operation to hvac for paulus
* Rename hold mode to preset mode
* Cleanup & update comments
* Remove on/off
* Fix supported feature count
* Update services
* Update demo
* Fix tests & use current_hvac
* Update comment
* Fix tests & add typing
* Add more typing
* Update modes
* Fix tests
* Cleanup low/high with range
* Update homematic part 1
* Finish homematic
* Fix lint
* fix hm mapping
* Support simple devices
* convert lcn
* migrate oem
* Fix xs1
* update hive
* update mil
* Update toon
* migrate deconz
* cleanup
* update tesla
* Fix lint
* Fix vera
* Migrate zwave
* Migrate velbus
* Cleanup humity feature
* Cleanup
* Migrate wink
* migrate dyson
* Fix current hvac
* Renaming
* Fix lint
* Migrate tfiac
* migrate tado
* Fix PRESET can be None
* apply PR#23913 from dev
* remove EU component, etc.
* remove EU component, etc.
* ready to test now
* de-linted
* some tweaks
* de-lint
* better handling of edge cases
* delint
* fix set_mode typos
* apply PR#23913 from dev
* remove EU component, etc.
* ready to test now
* de-linted
* some tweaks
* de-lint
* better handling of edge cases
* delint
* fix set_mode typos
* delint, move debug code
* away preset now working
* code tidy-up
* code tidy-up 2
* code tidy-up 3
* address issues #18932, #15063
* address issues #18932, #15063 - 2/2
* refactor MODE_AUTO to MODE_HEAT_COOL and use F not C
* add low/high to set_temp
* add low/high to set_temp 2
* add low/high to set_temp - delint
* run HA scripts
* port changes from PR #24402
* manual rebase
* manual rebase 2
* delint
* minor change
* remove SUPPORT_HVAC_ACTION
* Migrate radiotherm
* Convert touchline
* Migrate flexit
* Migrate nuheat
* Migrate maxcube
* Fix names maxcube const
* Migrate proliphix
* Migrate heatmiser
* Migrate fritzbox
* Migrate opentherm_gw
* Migrate venstar
* Migrate daikin
* Migrate modbus
* Fix elif
* Migrate Homematic IP Cloud to climate-1.0 (#24913)
* hmip climate fix
* Update hvac_mode and preset_mode
* fix lint
* Fix lint
* Migrate generic_thermostat
* Migrate incomfort to new climate schema (#24915)
* initial commit
* Update climate.py
* Migrate eq3btsmart
* Lint
* cleanup PRESET_MANUAL
* Migrate ecobee
* No conditional features
* KNX: Migrate climate component to new climate platform (#24931)
* Migrate climate component
* Remove unused code
* Corrected line length
* Lint
* Lint
* fix tests
* Fix value
* Migrate geniushub to new climate schema (#24191)
* Update one
* Fix model climate v2
* Cleanup p4
* Add comfort hold mode
* Fix old code
* Update homeassistant/components/climate/__init__.py
Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
* Update homeassistant/components/climate/const.py
Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
* First renaming
* Rename operation to hvac for paulus
* Rename hold mode to preset mode
* Cleanup & update comments
* Remove on/off
* Fix supported feature count
* Update services
* Update demo
* Fix tests & use current_hvac
* Update comment
* Fix tests & add typing
* Add more typing
* Update modes
* Fix tests
* Cleanup low/high with range
* Update homematic part 1
* Finish homematic
* Fix lint
* fix hm mapping
* Support simple devices
* convert lcn
* migrate oem
* Fix xs1
* update hive
* update mil
* Update toon
* migrate deconz
* cleanup
* update tesla
* Fix lint
* Fix vera
* Migrate zwave
* Migrate velbus
* Cleanup humity feature
* Cleanup
* Migrate wink
* migrate dyson
* Fix current hvac
* Renaming
* Fix lint
* Migrate tfiac
* migrate tado
* delinted
* delinted
* use latest client
* clean up mappings
* clean up mappings
* add duration to set_temperature
* add duration to set_temperature
* manual rebase
* tweak
* fix regression
* small fix
* fix rebase mixup
* address comments
* finish refactor
* fix regression
* tweak type hints
* delint
* manual rebase
* WIP: Fixes for honeywell migration to climate-1.0 (#24938)
* add type hints
* code tidy-up
* Fixes for incomfort migration to climate-1.0 (#24936)
* delint type hints
* no async unless await
* revert: no async unless await
* revert: no async unless await 2
* delint
* fix typo
* Fix homekit_controller on climate-1.0 (#24948)
* Fix tests on climate-1.0 branch
* As part of climate-1.0, make state return the heating-cooling.current characteristic
* Fixes from review
* lint
* Fix imports
* Migrate stibel_eltron
* Fix lint
* Migrate coolmaster to climate 1.0 (#24967)
* Migrate coolmaster to climate 1.0
* fix lint errors
* More lint fixes
* Fix demo to work with UI
* Migrate spider
* Demo update
* Updated frontend to 20190705.0
* Fix boost mode (#24980)
* Prepare Netatmo for climate 1.0 (#24973)
* Migration Netatmo
* Address comments
* Update climate.py
* Migrate ephember
* Migrate Sensibo
* Implemented review comments (#24942)
* Migrate ESPHome
* Migrate MQTT
* Migrate Nest
* Migrate melissa
* Initial/partial migration of ST
* Migrate ST
* Remove Away mode (#24995)
* Migrate evohome, cache access tokens (#24491)
* add water_heater, add storage - initial commit
* add water_heater, add storage - initial commit
delint
add missing code
desiderata
update honeywell client library & CODEOWNER
add auth_tokens code, refactor & delint
refactor for broker
delint
* Add Broker, Water Heater & Refactor
add missing code
desiderata
* update honeywell client library & CODEOWNER
add auth_tokens code, refactor & delint
refactor for broker
* bugfix - loc_idx may not be 0
more refactor - ensure pure async
more refactoring
appears all r/o attributes are working
tweak precsion, DHW & delint
remove unused code
remove unused code 2
remove unused code, refactor _save_auth_tokens()
* support RoundThermostat
bugfix opmode, switch to util.dt, add until=1h
revert breaking change
* store at_expires as naive UTC
remove debug code
delint
tidy up exception handling
delint
add water_heater, add storage - initial commit
delint
add missing code
desiderata
update honeywell client library & CODEOWNER
add auth_tokens code, refactor & delint
refactor for broker
add water_heater, add storage - initial commit
delint
add missing code
desiderata
update honeywell client library & CODEOWNER
add auth_tokens code, refactor & delint
refactor for broker
delint
bugfix - loc_idx may not be 0
more refactor - ensure pure async
more refactoring
appears all r/o attributes are working
tweak precsion, DHW & delint
remove unused code
remove unused code 2
remove unused code, refactor _save_auth_tokens()
support RoundThermostat
bugfix opmode, switch to util.dt, add until=1h
revert breaking change
store at_expires as naive UTC
remove debug code
delint
tidy up exception handling
delint
* update CODEOWNERS
* fix regression
* fix requirements
* migrate to climate-1.0
* tweaking
* de-lint
* TCS working? & delint
* tweaking
* TCS code finalised
* remove available() logic
* refactor _switchpoints()
* tidy up switchpoint code
* tweak
* teaking device_state_attributes
* some refactoring
* move PRESET_CUSTOM back to evohome
* move CONF_ACCESS_TOKEN_EXPIRES CONF_REFRESH_TOKEN back to evohome
* refactor SP code and dt conversion
* delinted
* delinted
* remove water_heater
* fix regression
* Migrate homekit
* Cleanup away mode
* Fix tests
* add helpers
* fix tests melissa
* Fix nehueat
* fix zwave
* add more tests
* fix deconz
* Fix climate test emulate_hue
* fix tests
* fix dyson tests
* fix demo with new layout
* fix honeywell
* Switch homekit_controller to use HVAC_MODE_HEAT_COOL instead of HVAC_MODE_AUTO (#25009)
* Lint
* PyLint
* Pylint
* fix fritzbox tests
* Fix google
* Fix all tests
* Fix lint
* Fix auto for homekit like controler
* Fix lint
* fix lint
2019-07-08 12:00:24 +00:00
|
|
|
"""Support for Honeywell (US) Total Connect Comfort climate systems."""
|
2024-03-08 13:52:48 +00:00
|
|
|
|
2023-01-21 19:28:05 +00:00
|
|
|
from dataclasses import dataclass
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2023-02-02 21:45:49 +00:00
|
|
|
import aiosomecomfort
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2022-01-02 15:31:48 +00:00
|
|
|
from homeassistant.config_entries import ConfigEntry
|
2021-12-06 03:10:07 +00:00
|
|
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
2022-03-25 01:17:36 +00:00
|
|
|
from homeassistant.core import HomeAssistant, callback
|
2023-01-30 12:57:14 +00:00
|
|
|
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
2024-02-02 16:31:16 +00:00
|
|
|
from homeassistant.helpers.aiohttp_client import (
|
|
|
|
async_create_clientsession,
|
|
|
|
async_get_clientsession,
|
|
|
|
)
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2022-03-25 01:17:36 +00:00
|
|
|
from .const import (
|
|
|
|
_LOGGER,
|
|
|
|
CONF_COOL_AWAY_TEMPERATURE,
|
|
|
|
CONF_HEAT_AWAY_TEMPERATURE,
|
|
|
|
DOMAIN,
|
|
|
|
)
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2021-09-07 14:32:26 +00:00
|
|
|
UPDATE_LOOP_SLEEP_TIME = 5
|
2024-04-06 15:22:56 +00:00
|
|
|
PLATFORMS = [Platform.CLIMATE, Platform.SENSOR, Platform.SWITCH]
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2022-03-25 01:17:36 +00:00
|
|
|
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},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2022-04-13 17:17:38 +00:00
|
|
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
2021-07-19 19:44:02 +00:00
|
|
|
"""Set up the Honeywell thermostat."""
|
2022-04-13 17:17:38 +00:00
|
|
|
_async_migrate_data_to_options(hass, config_entry)
|
2022-03-25 01:17:36 +00:00
|
|
|
|
2022-04-13 17:17:38 +00:00
|
|
|
username = config_entry.data[CONF_USERNAME]
|
|
|
|
password = config_entry.data[CONF_PASSWORD]
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2024-02-02 16:31:16 +00:00
|
|
|
if len(hass.config_entries.async_entries(DOMAIN)) > 1:
|
|
|
|
session = async_create_clientsession(hass)
|
|
|
|
else:
|
|
|
|
session = async_get_clientsession(hass)
|
|
|
|
|
|
|
|
client = aiosomecomfort.AIOSomeComfort(username, password, session=session)
|
2023-01-18 15:03:13 +00:00
|
|
|
try:
|
|
|
|
await client.login()
|
|
|
|
await client.discover()
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2023-02-02 21:45:49 +00:00
|
|
|
except aiosomecomfort.device.AuthError as ex:
|
2023-01-30 12:57:14 +00:00
|
|
|
raise ConfigEntryAuthFailed("Incorrect Password") from ex
|
2023-01-18 15:03:13 +00:00
|
|
|
|
|
|
|
except (
|
2023-02-02 21:45:49 +00:00
|
|
|
aiosomecomfort.device.ConnectionError,
|
|
|
|
aiosomecomfort.device.ConnectionTimeout,
|
2023-03-28 20:48:27 +00:00
|
|
|
aiosomecomfort.device.SomeComfortError,
|
2024-02-05 11:00:37 +00:00
|
|
|
TimeoutError,
|
2023-01-18 15:03:13 +00:00
|
|
|
) as ex:
|
|
|
|
raise ConfigEntryNotReady(
|
2023-05-05 19:21:22 +00:00
|
|
|
"Failed to initialize the Honeywell client: Connection error"
|
2023-01-18 15:03:13 +00:00
|
|
|
) from ex
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2021-12-14 04:38:43 +00:00
|
|
|
devices = {}
|
2021-07-19 19:44:02 +00:00
|
|
|
for location in client.locations_by_id.values():
|
2024-01-18 02:37:21 +00:00
|
|
|
for device in location.devices_by_id.values():
|
|
|
|
devices[device.deviceid] = device
|
2021-07-19 19:44:02 +00:00
|
|
|
|
|
|
|
if len(devices) == 0:
|
|
|
|
_LOGGER.debug("No devices found")
|
|
|
|
return False
|
2023-01-21 19:28:05 +00:00
|
|
|
data = HoneywellData(config_entry.entry_id, client, devices)
|
2024-01-18 02:35:53 +00:00
|
|
|
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = data
|
2022-07-09 15:27:42 +00:00
|
|
|
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
2021-07-19 19:44:02 +00:00
|
|
|
|
2022-04-13 17:17:38 +00:00
|
|
|
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
2021-09-29 21:10:22 +00:00
|
|
|
|
2021-07-19 19:44:02 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
|
2022-04-13 17:17:38 +00:00
|
|
|
async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
2021-09-29 21:10:22 +00:00
|
|
|
"""Update listener."""
|
2022-04-13 17:17:38 +00:00
|
|
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
2021-09-29 21:10:22 +00:00
|
|
|
|
|
|
|
|
2022-04-13 17:17:38 +00:00
|
|
|
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
2022-12-20 10:10:31 +00:00
|
|
|
"""Unload the config and platforms."""
|
2022-04-13 17:17:38 +00:00
|
|
|
unload_ok = await hass.config_entries.async_unload_platforms(
|
|
|
|
config_entry, PLATFORMS
|
|
|
|
)
|
2021-09-29 21:10:22 +00:00
|
|
|
if unload_ok:
|
2024-01-18 02:35:53 +00:00
|
|
|
hass.data[DOMAIN].pop(config_entry.entry_id)
|
2021-09-29 21:10:22 +00:00
|
|
|
return unload_ok
|
|
|
|
|
|
|
|
|
2023-01-21 19:28:05 +00:00
|
|
|
@dataclass
|
2021-08-23 22:54:55 +00:00
|
|
|
class HoneywellData:
|
2023-01-21 19:28:05 +00:00
|
|
|
"""Shared data for Honeywell."""
|
|
|
|
|
|
|
|
entry_id: str
|
2023-02-02 21:45:49 +00:00
|
|
|
client: aiosomecomfort.AIOSomeComfort
|
|
|
|
devices: dict[str, aiosomecomfort.device.Device]
|