Added optional precision configuration option to generic_thermostat. (#18317)
* Added optional precision configuration option to generic_thermostat. * Added optional precision configuration option to generic_thermostat. * Style update.pull/18319/head
parent
7fed49c4ab
commit
599542394a
|
@ -17,7 +17,8 @@ from homeassistant.components.climate import (
|
||||||
SUPPORT_AWAY_MODE, SUPPORT_TARGET_TEMPERATURE, PLATFORM_SCHEMA)
|
SUPPORT_AWAY_MODE, SUPPORT_TARGET_TEMPERATURE, PLATFORM_SCHEMA)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME, ATTR_ENTITY_ID,
|
STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME, ATTR_ENTITY_ID,
|
||||||
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_UNKNOWN)
|
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_UNKNOWN, PRECISION_HALVES,
|
||||||
|
PRECISION_TENTHS, PRECISION_WHOLE)
|
||||||
from homeassistant.helpers import condition
|
from homeassistant.helpers import condition
|
||||||
from homeassistant.helpers.event import (
|
from homeassistant.helpers.event import (
|
||||||
async_track_state_change, async_track_time_interval)
|
async_track_state_change, async_track_time_interval)
|
||||||
|
@ -43,6 +44,7 @@ CONF_HOT_TOLERANCE = 'hot_tolerance'
|
||||||
CONF_KEEP_ALIVE = 'keep_alive'
|
CONF_KEEP_ALIVE = 'keep_alive'
|
||||||
CONF_INITIAL_OPERATION_MODE = 'initial_operation_mode'
|
CONF_INITIAL_OPERATION_MODE = 'initial_operation_mode'
|
||||||
CONF_AWAY_TEMP = 'away_temp'
|
CONF_AWAY_TEMP = 'away_temp'
|
||||||
|
CONF_PRECISION = 'precision'
|
||||||
SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE |
|
SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE |
|
||||||
SUPPORT_OPERATION_MODE)
|
SUPPORT_OPERATION_MODE)
|
||||||
|
|
||||||
|
@ -63,7 +65,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
cv.time_period, cv.positive_timedelta),
|
cv.time_period, cv.positive_timedelta),
|
||||||
vol.Optional(CONF_INITIAL_OPERATION_MODE):
|
vol.Optional(CONF_INITIAL_OPERATION_MODE):
|
||||||
vol.In([STATE_AUTO, STATE_OFF]),
|
vol.In([STATE_AUTO, STATE_OFF]),
|
||||||
vol.Optional(CONF_AWAY_TEMP): vol.Coerce(float)
|
vol.Optional(CONF_AWAY_TEMP): vol.Coerce(float),
|
||||||
|
vol.Optional(CONF_PRECISION): vol.In(
|
||||||
|
[PRECISION_TENTHS, PRECISION_HALVES, PRECISION_WHOLE]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,11 +87,13 @@ async def async_setup_platform(hass, config, async_add_entities,
|
||||||
keep_alive = config.get(CONF_KEEP_ALIVE)
|
keep_alive = config.get(CONF_KEEP_ALIVE)
|
||||||
initial_operation_mode = config.get(CONF_INITIAL_OPERATION_MODE)
|
initial_operation_mode = config.get(CONF_INITIAL_OPERATION_MODE)
|
||||||
away_temp = config.get(CONF_AWAY_TEMP)
|
away_temp = config.get(CONF_AWAY_TEMP)
|
||||||
|
precision = config.get(CONF_PRECISION)
|
||||||
|
|
||||||
async_add_entities([GenericThermostat(
|
async_add_entities([GenericThermostat(
|
||||||
hass, name, heater_entity_id, sensor_entity_id, min_temp, max_temp,
|
hass, name, heater_entity_id, sensor_entity_id, min_temp, max_temp,
|
||||||
target_temp, ac_mode, min_cycle_duration, cold_tolerance,
|
target_temp, ac_mode, min_cycle_duration, cold_tolerance,
|
||||||
hot_tolerance, keep_alive, initial_operation_mode, away_temp)])
|
hot_tolerance, keep_alive, initial_operation_mode, away_temp,
|
||||||
|
precision)])
|
||||||
|
|
||||||
|
|
||||||
class GenericThermostat(ClimateDevice):
|
class GenericThermostat(ClimateDevice):
|
||||||
|
@ -96,7 +102,7 @@ class GenericThermostat(ClimateDevice):
|
||||||
def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
|
def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
|
||||||
min_temp, max_temp, target_temp, ac_mode, min_cycle_duration,
|
min_temp, max_temp, target_temp, ac_mode, min_cycle_duration,
|
||||||
cold_tolerance, hot_tolerance, keep_alive,
|
cold_tolerance, hot_tolerance, keep_alive,
|
||||||
initial_operation_mode, away_temp):
|
initial_operation_mode, away_temp, precision):
|
||||||
"""Initialize the thermostat."""
|
"""Initialize the thermostat."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self._name = name
|
self._name = name
|
||||||
|
@ -109,6 +115,7 @@ class GenericThermostat(ClimateDevice):
|
||||||
self._initial_operation_mode = initial_operation_mode
|
self._initial_operation_mode = initial_operation_mode
|
||||||
self._saved_target_temp = target_temp if target_temp is not None \
|
self._saved_target_temp = target_temp if target_temp is not None \
|
||||||
else away_temp
|
else away_temp
|
||||||
|
self._temp_precision = precision
|
||||||
if self.ac_mode:
|
if self.ac_mode:
|
||||||
self._current_operation = STATE_COOL
|
self._current_operation = STATE_COOL
|
||||||
self._operation_list = [STATE_COOL, STATE_OFF]
|
self._operation_list = [STATE_COOL, STATE_OFF]
|
||||||
|
@ -202,6 +209,13 @@ class GenericThermostat(ClimateDevice):
|
||||||
"""Return the name of the thermostat."""
|
"""Return the name of the thermostat."""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def precision(self):
|
||||||
|
"""Return the precision of the system."""
|
||||||
|
if self._temp_precision is not None:
|
||||||
|
return self._temp_precision
|
||||||
|
return super().precision
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature_unit(self):
|
def temperature_unit(self):
|
||||||
"""Return the unit of measurement."""
|
"""Return the unit of measurement."""
|
||||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.const import (
|
||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
|
TEMP_FAHRENHEIT,
|
||||||
ATTR_TEMPERATURE
|
ATTR_TEMPERATURE
|
||||||
)
|
)
|
||||||
from homeassistant import loader
|
from homeassistant import loader
|
||||||
|
@ -1074,6 +1075,37 @@ async def test_turn_off_when_off(hass, setup_comp_9):
|
||||||
state_cool.attributes.get('operation_mode')
|
state_cool.attributes.get('operation_mode')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def setup_comp_10(hass):
|
||||||
|
"""Initialize components."""
|
||||||
|
hass.config.temperature_unit = TEMP_FAHRENHEIT
|
||||||
|
assert hass.loop.run_until_complete(async_setup_component(
|
||||||
|
hass, climate.DOMAIN, {'climate': {
|
||||||
|
'platform': 'generic_thermostat',
|
||||||
|
'name': 'test',
|
||||||
|
'cold_tolerance': 0.3,
|
||||||
|
'hot_tolerance': 0.3,
|
||||||
|
'target_temp': 25,
|
||||||
|
'heater': ENT_SWITCH,
|
||||||
|
'target_sensor': ENT_SENSOR,
|
||||||
|
'min_cycle_duration': datetime.timedelta(minutes=15),
|
||||||
|
'keep_alive': datetime.timedelta(minutes=10),
|
||||||
|
'precision': 0.1
|
||||||
|
}}))
|
||||||
|
|
||||||
|
|
||||||
|
async def test_precision(hass, setup_comp_10):
|
||||||
|
"""Test that setting precision to tenths works as intended."""
|
||||||
|
common.async_set_operation_mode(hass, STATE_OFF)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.services.async_call('climate', SERVICE_TURN_OFF)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
common.async_set_temperature(hass, 23.27)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(ENTITY)
|
||||||
|
assert 23.3 == state.attributes.get('temperature')
|
||||||
|
|
||||||
|
|
||||||
async def test_custom_setup_params(hass):
|
async def test_custom_setup_params(hass):
|
||||||
"""Test the setup with custom parameters."""
|
"""Test the setup with custom parameters."""
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
|
|
Loading…
Reference in New Issue