core/homeassistant/components/evohome.py

146 lines
4.5 KiB
Python

"""Support for Honeywell evohome (EMEA/EU-based systems only).
Support for a temperature control system (TCS, controller) with 0+ heating
zones (e.g. TRVs, relays) and, optionally, a DHW controller.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/evohome/
"""
# Glossary:
# TCS - temperature control system (a.k.a. Controller, Parent), which can
# have up to 13 Children:
# 0-12 Heating zones (a.k.a. Zone), and
# 0-1 DHW controller, (a.k.a. Boiler)
import logging
from requests.exceptions import HTTPError
import voluptuous as vol
from homeassistant.const import (
CONF_USERNAME,
CONF_PASSWORD,
CONF_SCAN_INTERVAL,
HTTP_BAD_REQUEST
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform
REQUIREMENTS = ['evohomeclient==0.2.7']
# If ever > 0.2.7, re-check the work-around wrapper is still required when
# instantiating the client, below.
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'evohome'
DATA_EVOHOME = 'data_' + DOMAIN
CONF_LOCATION_IDX = 'location_idx'
MAX_TEMP = 28
MIN_TEMP = 5
SCAN_INTERVAL_DEFAULT = 180
SCAN_INTERVAL_MAX = 300
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_LOCATION_IDX, default=0): cv.positive_int,
}),
}, extra=vol.ALLOW_EXTRA)
# These are used to help prevent E501 (line too long) violations.
GWS = 'gateways'
TCS = 'temperatureControlSystems'
def setup(hass, config):
"""Create a Honeywell (EMEA/EU) evohome CH/DHW system.
One controller with 0+ heating zones (e.g. TRVs, relays) and, optionally, a
DHW controller. Does not work for US-based systems.
"""
evo_data = hass.data[DATA_EVOHOME] = {}
evo_data['timers'] = {}
evo_data['params'] = dict(config[DOMAIN])
evo_data['params'][CONF_SCAN_INTERVAL] = SCAN_INTERVAL_DEFAULT
from evohomeclient2 import EvohomeClient
_LOGGER.debug("setup(): API call [4 request(s)]: client.__init__()...")
try:
# There's a bug in evohomeclient2 v0.2.7: the client.__init__() sets
# the root loglevel when EvohomeClient(debug=?), so remember it now...
log_level = logging.getLogger().getEffectiveLevel()
client = EvohomeClient(
evo_data['params'][CONF_USERNAME],
evo_data['params'][CONF_PASSWORD],
debug=False
)
# ...then restore it to what it was before instantiating the client
logging.getLogger().setLevel(log_level)
except HTTPError as err:
if err.response.status_code == HTTP_BAD_REQUEST:
_LOGGER.error(
"Failed to establish a connection with evohome web servers, "
"Check your username (%s), and password are correct."
"Unable to continue. Resolve any errors and restart HA.",
evo_data['params'][CONF_USERNAME]
)
return False # unable to continue
raise # we dont handle any other HTTPErrors
finally: # Redact username, password as no longer needed.
evo_data['params'][CONF_USERNAME] = 'REDACTED'
evo_data['params'][CONF_PASSWORD] = 'REDACTED'
evo_data['client'] = client
# Redact any installation data we'll never need.
if client.installation_info[0]['locationInfo']['locationId'] != 'REDACTED':
for loc in client.installation_info:
loc['locationInfo']['streetAddress'] = 'REDACTED'
loc['locationInfo']['city'] = 'REDACTED'
loc['locationInfo']['locationOwner'] = 'REDACTED'
loc[GWS][0]['gatewayInfo'] = 'REDACTED'
# Pull down the installation configuration.
loc_idx = evo_data['params'][CONF_LOCATION_IDX]
try:
evo_data['config'] = client.installation_info[loc_idx]
except IndexError:
_LOGGER.warning(
"setup(): Parameter '%s' = %s , is outside its range (0-%s)",
CONF_LOCATION_IDX,
loc_idx,
len(client.installation_info) - 1
)
return False # unable to continue
evo_data['status'] = {}
if _LOGGER.isEnabledFor(logging.DEBUG):
tmp_loc = dict(evo_data['config'])
tmp_loc['locationInfo']['postcode'] = 'REDACTED'
tmp_tcs = tmp_loc[GWS][0][TCS][0]
if 'zones' in tmp_tcs:
tmp_tcs['zones'] = '...'
if 'dhw' in tmp_tcs:
tmp_tcs['dhw'] = '...'
_LOGGER.debug("setup(), location = %s", tmp_loc)
load_platform(hass, 'climate', DOMAIN)
return True