Skip to content

Commit

Permalink
Climate 1.0 (home-assistant#23899)
Browse files Browse the repository at this point in the history
* Climate 1.0 / part 1/2/3

* fix flake

* Lint

* Update Google Assistant

* ambiclimate to climate 1.0 (home-assistant#24911)

* Fix Alexa

* Lint

* Migrate zhong_hong

* Migrate tuya

* Migrate honeywell to new climate schema (home-assistant#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 <[email protected]>

* Update homeassistant/components/climate/const.py

Co-Authored-By: Paulus Schoutsen <[email protected]>

* 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 home-assistant#18932, home-assistant#15063

* address issues home-assistant#18932, home-assistant#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 home-assistant#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 (home-assistant#24913)

* hmip climate fix

* Update hvac_mode and preset_mode

* fix lint

* Fix lint

* Migrate generic_thermostat

* Migrate incomfort to new climate schema (home-assistant#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 (home-assistant#24931)

* Migrate climate component

* Remove unused code

* Corrected line length

* Lint

* Lint

* fix tests

* Fix value

* Migrate geniushub to new climate schema (home-assistant#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 <[email protected]>

* Update homeassistant/components/climate/const.py

Co-Authored-By: Paulus Schoutsen <[email protected]>

* 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 (home-assistant#24938)

* add type hints

* code tidy-up

* Fixes for incomfort migration to climate-1.0 (home-assistant#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 (home-assistant#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 (home-assistant#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 (home-assistant#24980)

* Prepare Netatmo for climate 1.0 (home-assistant#24973)

* Migration Netatmo

* Address comments

* Update climate.py

* Migrate ephember

* Migrate Sensibo

* Implemented review comments (home-assistant#24942)

* Migrate ESPHome

* Migrate MQTT

* Migrate Nest

* Migrate melissa

* Initial/partial migration of ST

* Migrate ST

* Remove Away mode (home-assistant#24995)

* Migrate evohome, cache access tokens (home-assistant#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 (home-assistant#25009)

* Lint

* PyLint

* Pylint

* fix fritzbox tests

* Fix google

* Fix all tests

* Fix lint

* Fix auto for homekit like controler

* Fix lint

* fix lint
  • Loading branch information
pvizeli authored Jul 8, 2019
1 parent c2f1c4b commit 84cf76b
Show file tree
Hide file tree
Showing 119 changed files with 5,208 additions and 5,493 deletions.
3 changes: 2 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"files.trimTrailingWhitespace": true,
"editor.rulers": [80]
"editor.rulers": [80],
"terminal.integrated.shell.linux": "/bin/bash"
}
}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ virtualization/vagrant/.vagrant
virtualization/vagrant/config

# Visual Studio Code
.vscode
.vscode/*
!.vscode/cSpell.json
!.vscode/extensions.json
!.vscode/tasks.json

# Built docs
docs/build
Expand Down
92 changes: 92 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Preview",
"type": "shell",
"command": "hass -c ./config",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pytest",
"type": "shell",
"command": "pytest --timeout=10 tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Flake8",
"type": "shell",
"command": "flake8 homeassistant tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pylint",
"type": "shell",
"command": "pylint homeassistant",
"dependsOn": [
"Install all Requirements"
],
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Generate Requirements",
"type": "shell",
"command": "./script/gen_requirements_all.py",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Install all Requirements",
"type": "shell",
"command": "pip3 install -r requirements_all.txt -c homeassistant/package_constraints.txt",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
}
]
}
37 changes: 22 additions & 15 deletions homeassistant/components/alexa/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from .const import (
API_TEMP_UNITS,
API_THERMOSTAT_MODES,
API_THERMOSTAT_PRESETS,
DATE_FORMAT,
PERCENTAGE_FAN_MAP,
)
Expand Down Expand Up @@ -180,9 +181,13 @@ def get_property(self, name):
if name != 'powerState':
raise UnsupportedProperty(name)

if self.entity.state == STATE_OFF:
return 'OFF'
return 'ON'
if self.entity.domain == climate.DOMAIN:
is_on = self.entity.state != climate.HVAC_MODE_OFF

else:
is_on = self.entity.state != STATE_OFF

return 'ON' if is_on else 'OFF'


class AlexaLockController(AlexaCapibility):
Expand Down Expand Up @@ -546,16 +551,13 @@ def name(self):

def properties_supported(self):
"""Return what properties this entity supports."""
properties = []
properties = [{'name': 'thermostatMode'}]
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & climate.SUPPORT_TARGET_TEMPERATURE:
properties.append({'name': 'targetSetpoint'})
if supported & climate.SUPPORT_TARGET_TEMPERATURE_LOW:
if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
properties.append({'name': 'lowerSetpoint'})
if supported & climate.SUPPORT_TARGET_TEMPERATURE_HIGH:
properties.append({'name': 'upperSetpoint'})
if supported & climate.SUPPORT_OPERATION_MODE:
properties.append({'name': 'thermostatMode'})
return properties

def properties_proactively_reported(self):
Expand All @@ -569,13 +571,18 @@ def properties_retrievable(self):
def get_property(self, name):
"""Read and return a property."""
if name == 'thermostatMode':
ha_mode = self.entity.attributes.get(climate.ATTR_OPERATION_MODE)
mode = API_THERMOSTAT_MODES.get(ha_mode)
if mode is None:
_LOGGER.error("%s (%s) has unsupported %s value '%s'",
self.entity.entity_id, type(self.entity),
climate.ATTR_OPERATION_MODE, ha_mode)
raise UnsupportedProperty(name)
preset = self.entity.attributes.get(climate.ATTR_PRESET_MODE)

if preset in API_THERMOSTAT_PRESETS:
mode = API_THERMOSTAT_PRESETS[preset]
else:
mode = API_THERMOSTAT_MODES.get(self.entity.state)
if mode is None:
_LOGGER.error(
"%s (%s) has unsupported state value '%s'",
self.entity.entity_id, type(self.entity),
self.entity.state)
raise UnsupportedProperty(name)
return mode

unit = self.hass.config.units.temperature_unit
Expand Down
20 changes: 10 additions & 10 deletions homeassistant/components/alexa/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from collections import OrderedDict

from homeassistant.const import (
STATE_OFF,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
Expand Down Expand Up @@ -57,16 +56,17 @@
# reverse mapping of this dict and we want to map the first occurrance of OFF
# back to HA state.
API_THERMOSTAT_MODES = OrderedDict([
(climate.STATE_HEAT, 'HEAT'),
(climate.STATE_COOL, 'COOL'),
(climate.STATE_AUTO, 'AUTO'),
(climate.STATE_ECO, 'ECO'),
(climate.STATE_MANUAL, 'AUTO'),
(STATE_OFF, 'OFF'),
(climate.STATE_IDLE, 'OFF'),
(climate.STATE_FAN_ONLY, 'OFF'),
(climate.STATE_DRY, 'OFF'),
(climate.HVAC_MODE_HEAT, 'HEAT'),
(climate.HVAC_MODE_COOL, 'COOL'),
(climate.HVAC_MODE_HEAT_COOL, 'AUTO'),
(climate.HVAC_MODE_AUTO, 'AUTO'),
(climate.HVAC_MODE_OFF, 'OFF'),
(climate.HVAC_MODE_FAN_ONLY, 'OFF'),
(climate.HVAC_MODE_DRY, 'OFF'),
])
API_THERMOSTAT_PRESETS = {
climate.PRESET_ECO: 'ECO'
}

PERCENTAGE_FAN_MAP = {
fan.SPEED_LOW: 33,
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/alexa/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,11 @@ def default_display_categories(self):

def interfaces(self):
"""Yield the supported interfaces."""
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & climate.SUPPORT_ON_OFF:
# If we support two modes, one being off, we allow turning on too.
if len([v for v in self.entity.attributes[climate.ATTR_HVAC_MODES]
if v != climate.HVAC_MODE_OFF]) == 1:
yield AlexaPowerController(self.entity)

yield AlexaThermostatController(self.hass, self.entity)
yield AlexaTemperatureSensor(self.hass, self.entity)
yield AlexaEndpointHealth(self.hass, self.entity)
Expand Down
45 changes: 34 additions & 11 deletions homeassistant/components/alexa/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .const import (
API_TEMP_UNITS,
API_THERMOSTAT_MODES,
API_THERMOSTAT_PRESETS,
Cause,
)
from .entities import async_get_entities
Expand Down Expand Up @@ -686,23 +687,45 @@ async def async_api_set_thermostat_mode(hass, config, directive, context):
mode = directive.payload['thermostatMode']
mode = mode if isinstance(mode, str) else mode['value']

operation_list = entity.attributes.get(climate.ATTR_OPERATION_LIST)
ha_mode = next(
(k for k, v in API_THERMOSTAT_MODES.items() if v == mode),
None
)
if ha_mode not in operation_list:
msg = 'The requested thermostat mode {} is not supported'.format(mode)
raise AlexaUnsupportedThermostatModeError(msg)

data = {
ATTR_ENTITY_ID: entity.entity_id,
climate.ATTR_OPERATION_MODE: ha_mode,
}

ha_preset = next(
(k for k, v in API_THERMOSTAT_PRESETS.items() if v == mode),
None
)

if ha_preset:
presets = entity.attributes.get(climate.ATTR_PRESET_MODES, [])

if ha_preset not in presets:
msg = 'The requested thermostat mode {} is not supported'.format(
ha_preset
)
raise AlexaUnsupportedThermostatModeError(msg)

service = climate.SERVICE_SET_PRESET_MODE
data[climate.ATTR_PRESET_MODE] = climate.PRESET_ECO

else:
operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES)
ha_mode = next(
(k for k, v in API_THERMOSTAT_MODES.items() if v == mode),
None
)
if ha_mode not in operation_list:
msg = 'The requested thermostat mode {} is not supported'.format(
mode
)
raise AlexaUnsupportedThermostatModeError(msg)

service = climate.SERVICE_SET_HVAC_MODE
data[climate.ATTR_HVAC_MODE] = ha_mode

response = directive.response()
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_OPERATION_MODE, data,
climate.DOMAIN, service, data,
blocking=False, context=context)
response.add_context_property({
'name': 'thermostatMode',
Expand Down
36 changes: 15 additions & 21 deletions homeassistant/components/ambiclimate/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@

from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_ON_OFF, STATE_HEAT)
from homeassistant.const import ATTR_NAME
from homeassistant.const import (ATTR_TEMPERATURE,
STATE_OFF, TEMP_CELSIUS)
SUPPORT_TARGET_TEMPERATURE, HVAC_MODE_OFF, HVAC_MODE_HEAT)
from homeassistant.const import ATTR_NAME, ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (ATTR_VALUE, CONF_CLIENT_ID, CONF_CLIENT_SECRET,
Expand All @@ -20,8 +17,7 @@

_LOGGER = logging.getLogger(__name__)

SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE |
SUPPORT_ON_OFF)
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE

SEND_COMFORT_FEEDBACK_SCHEMA = vol.Schema({
vol.Required(ATTR_NAME): cv.string,
Expand Down Expand Up @@ -177,11 +173,6 @@ def current_humidity(self):
"""Return the current humidity."""
return self._data.get('humidity')

@property
def is_on(self):
"""Return true if heater is on."""
return self._data.get('power', '').lower() == 'on'

@property
def min_temp(self):
"""Return the minimum temperature."""
Expand All @@ -198,9 +189,12 @@ def supported_features(self):
return SUPPORT_FLAGS

@property
def current_operation(self):
def hvac_mode(self):
"""Return current operation."""
return STATE_HEAT if self.is_on else STATE_OFF
if self._data.get('power', '').lower() == 'on':
return HVAC_MODE_HEAT

return HVAC_MODE_OFF

async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
Expand All @@ -209,13 +203,13 @@ async def async_set_temperature(self, **kwargs):
return
await self._heater.set_target_temperature(temperature)

async def async_turn_on(self):
"""Turn device on."""
await self._heater.turn_on()

async def async_turn_off(self):
"""Turn device off."""
await self._heater.turn_off()
async def async_set_hvac_mode(self, hvac_mode):
"""Set new target hvac mode."""
if hvac_mode == HVAC_MODE_HEAT:
await self._heater.turn_on()
return
if hvac_mode == HVAC_MODE_OFF:
await self._heater.turn_off()

async def async_update(self):
"""Retrieve latest state."""
Expand Down
Loading

0 comments on commit 84cf76b

Please sign in to comment.