mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add support for Tfiac Climate component (#21823)
## Description: Add support for AC-models that follows the Tfiac protocol. Built together with @mellado. **Pull request in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) with documentation (if applicable):** home-assistant/home-assistant.io#8910 ## Example entry for `configuration.yaml` (if applicable): ```yaml climate: platform: tfiac host: 192.168.10.26 ``` ## Checklist: - [x] The code change is tested and works locally. - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass** - [x] There is no commented out code in this PR. If user exposed functionality or configuration variables are added/changed: - [x] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) If the code communicates with devices, web services, or third-party tools: - [x] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]). - [x] New dependencies are only imported inside functions that use them ([example][ex-import]). - [x] New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`. - [x] New files were added to `.coveragerc`. [ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L14 [ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L23 Co-authored-by: Robbie Trencheny <me@robbiet.us>
This commit is contained in:
parent
d1f75fcf32
commit
b6987a1235
@ -82,6 +82,7 @@ omit =
|
||||
homeassistant/components/proliphix/climate.py
|
||||
homeassistant/components/radiotherm/climate.py
|
||||
homeassistant/components/sensibo/climate.py
|
||||
homeassistant/components/tfiac/climate.py
|
||||
homeassistant/components/touchline/climate.py
|
||||
homeassistant/components/venstar/climate.py
|
||||
homeassistant/components/zhong_hong/climate.py
|
||||
|
@ -241,15 +241,16 @@ homeassistant/components/tautulli/sensor.py @ludeeus
|
||||
homeassistant/components/tellduslive/* @fredrike
|
||||
homeassistant/components/template/cover.py @PhracturedBlue
|
||||
homeassistant/components/tesla/* @zabuldon
|
||||
homeassistant/components/tfiac/* @fredrike @mellado
|
||||
homeassistant/components/thethingsnetwork/* @fabaff
|
||||
homeassistant/components/threshold/binary_sensor.py @fabaff
|
||||
homeassistant/components/tibber/* @danielhiversen
|
||||
homeassistant/components/tile/device_tracker.py @bachya
|
||||
homeassistant/components/time_date/sensor.py @fabaff
|
||||
homeassistant/components/toon/* @frenck
|
||||
homeassistant/components/tplink/* @rytilahti
|
||||
homeassistant/components/traccar/device_tracker.py @ludeeus
|
||||
homeassistant/components/tradfri/* @ggravlingen
|
||||
homeassistant/components/toon/* @frenck
|
||||
|
||||
# U
|
||||
homeassistant/components/uber/sensor.py @robbiet480
|
||||
|
1
homeassistant/components/tfiac/__init__.py
Normal file
1
homeassistant/components/tfiac/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""The tfiac component."""
|
185
homeassistant/components/tfiac/climate.py
Normal file
185
homeassistant/components/tfiac/climate.py
Normal file
@ -0,0 +1,185 @@
|
||||
"""Climate platform that offers a climate device for the TFIAC protocol."""
|
||||
from concurrent import futures
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice
|
||||
from homeassistant.components.climate.const import (
|
||||
STATE_AUTO, STATE_COOL, STATE_DRY, STATE_FAN_ONLY, STATE_HEAT,
|
||||
SUPPORT_FAN_MODE, SUPPORT_ON_OFF, SUPPORT_OPERATION_MODE,
|
||||
SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, CONF_HOST, TEMP_FAHRENHEIT
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
REQUIREMENTS = ['pytfiac==0.3']
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
})
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
MIN_TEMP = 61
|
||||
MAX_TEMP = 88
|
||||
OPERATION_MAP = {
|
||||
STATE_HEAT: 'heat',
|
||||
STATE_AUTO: 'selfFeel',
|
||||
STATE_DRY: 'dehumi',
|
||||
STATE_FAN_ONLY: 'fan',
|
||||
STATE_COOL: 'cool',
|
||||
}
|
||||
OPERATION_MAP_REV = {
|
||||
v: k for k, v in OPERATION_MAP.items()}
|
||||
FAN_LIST = ['Auto', 'Low', 'Middle', 'High']
|
||||
SWING_LIST = [
|
||||
'Off',
|
||||
'Vertical',
|
||||
'Horizontal',
|
||||
'Both',
|
||||
]
|
||||
|
||||
CURR_TEMP = 'current_temp'
|
||||
TARGET_TEMP = 'target_temp'
|
||||
OPERATION_MODE = 'operation'
|
||||
FAN_MODE = 'fan_mode'
|
||||
SWING_MODE = 'swing_mode'
|
||||
ON_MODE = 'is_on'
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices,
|
||||
discovery_info=None):
|
||||
"""Set up the TFIAC climate device."""
|
||||
from pytfiac import Tfiac
|
||||
|
||||
tfiac_client = Tfiac(config[CONF_HOST])
|
||||
try:
|
||||
await tfiac_client.update()
|
||||
except futures.TimeoutError:
|
||||
_LOGGER.error("Unable to connect to %s", config[CONF_HOST])
|
||||
return
|
||||
async_add_devices([TfiacClimate(hass, tfiac_client)])
|
||||
|
||||
|
||||
class TfiacClimate(ClimateDevice):
|
||||
"""TFIAC class."""
|
||||
|
||||
def __init__(self, hass, client):
|
||||
"""Init class."""
|
||||
self._client = client
|
||||
self._available = True
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return if the device is available."""
|
||||
return self._available
|
||||
|
||||
async def async_update(self):
|
||||
"""Update status via socket polling."""
|
||||
try:
|
||||
await self._client.update()
|
||||
self._available = True
|
||||
except futures.TimeoutError:
|
||||
self._available = False
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
return (SUPPORT_FAN_MODE | SUPPORT_ON_OFF | SUPPORT_OPERATION_MODE
|
||||
| SUPPORT_SWING_MODE | SUPPORT_TARGET_TEMPERATURE)
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum temperature."""
|
||||
return MIN_TEMP
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum temperature."""
|
||||
return MAX_TEMP
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the climate device."""
|
||||
return self._client.name
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._client.status['target_temp']
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
"""Return the unit of measurement."""
|
||||
return TEMP_FAHRENHEIT
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the current temperature."""
|
||||
return self._client.status['current_temp']
|
||||
|
||||
@property
|
||||
def current_operation(self):
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
operation = self._client.status['operation']
|
||||
return OPERATION_MAP_REV.get(operation, operation)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if on."""
|
||||
return self._client.status[ON_MODE] == 'on'
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""Return the list of available operation modes."""
|
||||
return sorted(OPERATION_MAP)
|
||||
|
||||
@property
|
||||
def current_fan_mode(self):
|
||||
"""Return the fan setting."""
|
||||
return self._client.status['fan_mode']
|
||||
|
||||
@property
|
||||
def fan_list(self):
|
||||
"""Return the list of available fan modes."""
|
||||
return FAN_LIST
|
||||
|
||||
@property
|
||||
def current_swing_mode(self):
|
||||
"""Return the swing setting."""
|
||||
return self._client.status['swing_mode']
|
||||
|
||||
@property
|
||||
def swing_list(self):
|
||||
"""List of available swing modes."""
|
||||
return SWING_LIST
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
if kwargs.get(ATTR_TEMPERATURE) is not None:
|
||||
await self._client.set_state(TARGET_TEMP,
|
||||
kwargs.get(ATTR_TEMPERATURE))
|
||||
|
||||
async def async_set_operation_mode(self, operation_mode):
|
||||
"""Set new operation mode."""
|
||||
await self._client.set_state(OPERATION_MODE,
|
||||
OPERATION_MAP[operation_mode])
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode):
|
||||
"""Set new fan mode."""
|
||||
await self._client.set_state(FAN_MODE, fan_mode)
|
||||
|
||||
async def async_set_swing_mode(self, swing_mode):
|
||||
"""Set new swing mode."""
|
||||
await self._client.set_swing(swing_mode)
|
||||
|
||||
async def async_turn_on(self):
|
||||
"""Turn device on."""
|
||||
await self._client.set_state(ON_MODE, 'on')
|
||||
|
||||
async def async_turn_off(self):
|
||||
"""Turn device off."""
|
||||
await self._client.set_state(ON_MODE, 'off')
|
@ -1299,6 +1299,9 @@ pytautulli==0.5.0
|
||||
# homeassistant.components.liveboxplaytv.media_player
|
||||
pyteleloisirs==3.4
|
||||
|
||||
# homeassistant.components.tfiac.climate
|
||||
pytfiac==0.3
|
||||
|
||||
# homeassistant.components.thinkingcleaner.sensor
|
||||
# homeassistant.components.thinkingcleaner.switch
|
||||
pythinkingcleaner==0.0.3
|
||||
|
Loading…
x
Reference in New Issue
Block a user